summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2004-04-15 01:01:56 +0000
committerpeter <peter@FreeBSD.org>2004-04-15 01:01:56 +0000
commit6045cae71a438a752980a395f03717a13cc22179 (patch)
treefd220ac1ddaebaa4a730f86d6f727fb639279056 /contrib/cvs/src
parent0de1aa939e0bb1831fe5ba20e2afa2fe6d7426ab (diff)
downloadFreeBSD-src-6045cae71a438a752980a395f03717a13cc22179.zip
FreeBSD-src-6045cae71a438a752980a395f03717a13cc22179.tar.gz
Import cvs-1.11.15
Diffstat (limited to 'contrib/cvs/src')
-rw-r--r--contrib/cvs/src/ChangeLog1742
-rw-r--r--contrib/cvs/src/Makefile.am11
-rw-r--r--contrib/cvs/src/Makefile.in239
-rw-r--r--contrib/cvs/src/add.c278
-rw-r--r--contrib/cvs/src/admin.c56
-rw-r--r--contrib/cvs/src/annotate.c10
-rw-r--r--contrib/cvs/src/buffer.c114
-rw-r--r--contrib/cvs/src/buffer.h1
-rw-r--r--contrib/cvs/src/checkin.c28
-rw-r--r--contrib/cvs/src/checkout.c178
-rw-r--r--contrib/cvs/src/classify.c6
-rw-r--r--contrib/cvs/src/client.c1324
-rw-r--r--contrib/cvs/src/client.h20
-rw-r--r--contrib/cvs/src/commit.c709
-rw-r--r--contrib/cvs/src/create_adm.c10
-rw-r--r--contrib/cvs/src/cvs.h227
-rwxr-xr-xcontrib/cvs/src/cvsbug.in19
-rw-r--r--contrib/cvs/src/cvsrc.c2
-rw-r--r--contrib/cvs/src/diff.c436
-rw-r--r--contrib/cvs/src/edit.c93
-rw-r--r--contrib/cvs/src/edit.h13
-rw-r--r--contrib/cvs/src/entries.c53
-rw-r--r--contrib/cvs/src/error.c4
-rw-r--r--contrib/cvs/src/expand_path.c38
-rw-r--r--contrib/cvs/src/fileattr.c2
-rw-r--r--contrib/cvs/src/fileattr.h2
-rw-r--r--contrib/cvs/src/filesubr.c212
-rw-r--r--contrib/cvs/src/find_names.c12
-rw-r--r--contrib/cvs/src/hardlink.c16
-rw-r--r--contrib/cvs/src/hash.c15
-rw-r--r--contrib/cvs/src/hash.h2
-rw-r--r--contrib/cvs/src/history.c61
-rw-r--r--contrib/cvs/src/history.h13
-rw-r--r--contrib/cvs/src/ignore.c104
-rw-r--r--contrib/cvs/src/import.c70
-rw-r--r--contrib/cvs/src/lock.c170
-rw-r--r--contrib/cvs/src/log.c148
-rw-r--r--contrib/cvs/src/login.c43
-rw-r--r--contrib/cvs/src/logmsg.c76
-rw-r--r--contrib/cvs/src/main.c61
-rw-r--r--contrib/cvs/src/mkmodules.c20
-rw-r--r--contrib/cvs/src/modules.c146
-rw-r--r--contrib/cvs/src/myndbm.c10
-rw-r--r--contrib/cvs/src/no_diff.c9
-rw-r--r--contrib/cvs/src/parseinfo.c60
-rw-r--r--contrib/cvs/src/patch.c174
-rw-r--r--contrib/cvs/src/rcs.c577
-rw-r--r--contrib/cvs/src/rcs.h47
-rw-r--r--contrib/cvs/src/rcscmds.c139
-rw-r--r--contrib/cvs/src/recurse.c102
-rw-r--r--contrib/cvs/src/release.c56
-rw-r--r--contrib/cvs/src/remove.c16
-rw-r--r--contrib/cvs/src/repos.c32
-rw-r--r--contrib/cvs/src/root.c129
-rw-r--r--contrib/cvs/src/root.h25
-rw-r--r--contrib/cvs/src/run.c33
-rwxr-xr-xcontrib/cvs/src/sanity.sh7176
-rw-r--r--contrib/cvs/src/server.c1105
-rw-r--r--contrib/cvs/src/server.h59
-rw-r--r--contrib/cvs/src/stack.c187
-rw-r--r--contrib/cvs/src/stack.h18
-rw-r--r--contrib/cvs/src/status.c23
-rw-r--r--contrib/cvs/src/subr.c227
-rw-r--r--contrib/cvs/src/tag.c130
-rw-r--r--contrib/cvs/src/update.c371
-rw-r--r--contrib/cvs/src/update.h4
-rw-r--r--contrib/cvs/src/vers_ts.c19
-rw-r--r--contrib/cvs/src/watch.c23
-rw-r--r--contrib/cvs/src/watch.h2
-rw-r--r--contrib/cvs/src/wrapper.c2
-rw-r--r--contrib/cvs/src/zlib.c180
71 files changed, 12042 insertions, 5677 deletions
diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog
index 656ca2f..f7e9470 100644
--- a/contrib/cvs/src/ChangeLog
+++ b/contrib/cvs/src/ChangeLog
@@ -1,10 +1,1750 @@
+2004-04-11 Derek Price <derek@ximbiot.com>
+
+ * client.c (call_in_directory): Check paths the server sends us to make
+ sure they are within a sandbox the user requested be updated.
+ (is_valid_client_path, path_list_prefixed): New functions.
+
+2004-04-11 Derek Price <derek@ximbiot.com>
+
+ * modules.c (do_module): Don't allow up-level references in paths to
+ step out of the repository.
+ * sanity.sh (multiroot3): Update tests and add a few more.
+
+2004-04-07 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (parseroot): Replace hard path with $HOME.
+
+2004-04-07 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (parseroot): s/oberon/$username/.
+
+2004-04-07 Derek Price <derek@ximbiot.com>
+
+ * client.c (start_tcp_server): Use xstrdup rather than
+ xmalloc(strlen)/strcpy.
+
+2004-04-07 Derek Price <derek@ximbiot.com>
+
+ * root.c (parse_cvsroot): Ignore method options.
+ * sanity.sh (parseroot): Verify that method options are ignored.
+
+2004-04-06 Derek Price <derek@ximbiot.com>
+
+ * root.h (cvsroot_t): Move username, password, hostname, port inside
+ CLIENT_SUPPORT ifdefs.
+ * buffer.c, root.c, server.c: Add #ifdefs as necessary so that this
+ will compile without client support and the root.h change. Some
+ gratuitous restyling.
+
+2004-04-06 Derek Price <derek@ximbiot.com>
+
+ * log.c, tag.c: Gratuitous restyling.
+
+2004-04-04 Derek Price <derek@ximbiot.com>
+
+ * filesubr.c (isabsolute): Move...
+ * subr.c: ...here and use new ISABSOLUTE macro.
+
+2004-04-04 Derek Price <derek@ximbiot.com>
+
+ * client.c (send_file_names): Cast out an unneeded const to avoid a
+ warning.
+
+2004-04-03 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * client.c (send_file_names): Remove unused variables.
+
+2004-04-02 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (client): Honor $keep.
+
+2004-04-02 Derek Price <derek@ximbiot.com>
+
+ * log.c, patch.c, rcs.c: Gratuitous restyling.
+
+2004-04-02 Derek Price <derek@ximbiot.com>
+
+ * import.c (import): Use ISDIRSEP rather than testing paths against `/'
+ directly. Some gratuitos reformatting.
+
+2004-04-02 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Note the effectiveness of `tail -f check.log' in providing
+ running status.
+
+2004-04-02 Derek Price <derek@ximbiot.com>
+
+ * client.c (send_file_names): Move code which calculates and sends
+ Max-dotdot...
+ (send_max_dotdot): ...to this new function.
+ (send_files): Call send_max_dotdot.
+ * sanity.sh (files-14): Expect .. in paths to work now.
+ (status): Add a few new tests using `..'.
+
+2004-04-01 Derek Price <derek@ximbiot.com>
+
+ * lock.c: Gratuitous restyling.
+
+2004-04-01 Derek Price <derek@ximbiot.com>
+
+ * cvs.h, server.c: Gratuitous restyling.
+ * run.c (run_exec): Ditto, plus call cvs_flush{out,err}() instead of
+ flushing stderr & stdout directly.
+
+2004-03-29 Derek Price <derek@ximbiot.com>
+
+ * server.c: Gratuitous restyling.
+
+2004-03-29 Derek Price <derek@ximbiot.com>
+
+ * login.c: Gratuitous restyling.
+
+2004-03-22 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (toplevel): Remove FIXME type comment and unneeded
+ Emtptydir removal.
+
+2004-03-22 Derek Price <derek@ximbiot.com>
+
+ * update.c: Some minor style cleanup.
+
+2004-03-22 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (top-level): Don't match most of the assertion since this
+ string is often system dependent.
+ (Thanks to Larry Jones <lawrence.jones@ugsplm.com>.)
+
+2004-03-22 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (top-level): Don't match the assertion's line number.
+
+2004-03-22 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (top-level): New test to confirm assertion failure.
+
+2004-03-22 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Only verify argument to -f when -f was passed. Check for
+ $TMPDIR/cvsXXXXXX temp files after each test.
+
+2004-03-22 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Verify that the argument to -f is really a test.
+
+2004-03-20 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * cvs.h: Change command_name to cvs_command_name to avoid conflict
+ on HP-UX (incredibly, it declares a global command_name in prot.h,
+ which is included from shadow.h, which we include in server.c).
+ Change all references.
+
+ * subr.c (previous_rev): Fix == vs = typo.
+
+ * buffer.h: Add prototype for buf_empty.
+
+ * add.c (add): Remove unused variable.
+
+2004-03-20 Derek Price <derek@ximbiot.com>
+
+ * add.c (add, add_directory, build_entry), admin.c (admin_dirproc),
+ checkin.c (Checkin), checkout.c (safe_location, build_dirs_and_chdir),
+ client.c (add_prune_candidate, send_repository, send_a_repository,
+ send_to_server, start_rsh_server, send_arg, send_modified,
+ send_ignproc, send_filesdone_proc, send_dirent_proc,
+ send_dirleave_proc, client_notify), commit.c (check_direntproc,
+ check_filesdoneproc, checkaddfile, commit_direntproc,
+ commit_dirleaveproc, lock_RCS, precommit_proc, find_data,
+ find_dirent_proc, find_ignproc, find_filesdoneproc), create_adm.c
+ (Create_Admin), cvsrc.c (read_cvsrc), diff.c (diff_dirproc,
+ diff_filesdoneproc, diff_dirleaveproc), edit.c (onoff_filesdoneproc,
+ mark_up_to_date, editor_set, notify_proc_args, notify_proc, notify_do,
+ notify_check), entries.c (Scratch_Entry, Register, WriteTag),
+ expand_path.c (expand_variable, expand_path), fileattr.c
+ (fileattr_startdir), filesubr.c (mkdir_if_needed, xchmod,
+ last_component), history.c (history_write), ignore.c (ignore_directory,
+ ignore_files), import.c (get_comment, add_rcs_file, expand_at_signs),xi
+ lock.c (lock_filesdoneproc), log.c (log_dirproc), logmsg.c
+ (logfile_write, rcsinfo_proc, update_logfile_proc, editinfo_proc,
+ verifymsg_proc, do_editor, do_verify, Update_Logfile), main.c (main
+ program_name, program_path, command_name), parseinfo.c (Parse_Info),
+ patch.c (patch_dirproc), rcs.c (RCS_getdatebranch, rcs_lockfilename,
+ RCS_parse, RCS_setattic, RCS_getversion, RCS_gettag, RCS_getbranch,
+ RCS_getdate, RCS_datecmp, RCS_getrevtime, RCS_setexpand,
+ expand_keywords, RCS_checkout, RCS_addbranch, RCS_checkin, RCS_lock,
+ RCS_cmp_file, RCS_deltas, rcs_lockfilename, make_file_label),
+ rcscmds.c (RCS_output_diff_options, call_diff, RCS_merge,
+ RCS_exec_rcsdiff, diff_exec), recurse.c (start_recursion, do_recursion,
+ do_file_proc), remove.c (remove_dirproc), repos.c (Name_Repository,
+ Short_Repository), root.c (Name_Root, Create_Root), run.c
+ (piped_child), server.c (output_dir, server_register,
+ server_checked_in, server_update_entries, server_copy_file,
+ server_set_entstat, server_clear_entstat, server_set_sticky,
+ server_template, cvs_output_tagged), status.c (status_dirproc), subr.c
+ (make_message_rcslegal), tag.c (pretag_proc, tag_dirproc,
+ check_fileproc, check_filesdoneproc, tag_fileproc, val_direntproc),
+ update.c (update_dirent_proc, update_dirleave_proc, update_ignproc,
+ update_filesdone_proc, isemptydir), vers_ts.c (time_stamp_server,
+ time_stamp), watch.c (watch_modify_watchers, addremove_filesdoneproc),
+ zlib.c (read_and_gzip): Make most string args const, mainly in the
+ interest of preserving repository & updatedir but including some
+ collateral damage. Update a few functions to comply with new
+ requirement. Some style fixes.
+ * client.h, cvs.h, edit.h, fileattr.h, rcs.h, server.h, update.h,
+ watch.h: Update prototypes to match.
+
+2004-03-20 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (conflicts2): s/cvs/$testcvs/.
+
+2004-03-20 Derek Price <derek@ximbiot.com>
+
+ * add.c (add): Correct longstanding resurrection bugs. Remove FIXME
+ comment to this effect. Set mode and Entries timestamps of resurrected
+ files correctly.
+ * sanity.sh (basica, binfiles, conflicts2, recase, resurrection,
+ update-p): Update tests to compensate. Remove FIXCVS comments.
+
+2004-03-19 Mark D. Baushke <mdb@cvshome.org>
+
+ * server.c (gserver_authenticate_connection): Handle large
+ GSSAPI packets dynamically.
+ (Bug report from Douglas Engert <DEEngert@anl.gov>)
+
+2004-03-19 Derek Price <derek@ximbiot.com>
+
+ * cvs.h (pathname_levels, previous_rev): Remove leading underscore from
+ prototype arguments to avoid potential conflicts with implementations.
+
+2004-03-18 Derek Price <derek@ximbiot.com>
+
+ * cvs.h (pathname_levels): Make string argument const.
+ * subr.c (pathname_levels): Simplify function.
+
+2004-03-17 Derek Price <derek@ximbiot.com>
+
+ * subr.c (pathname_levels): Get it right this time.
+
+2004-03-17 Derek Price <derek@ximbiot.com>
+
+ * subr.c (pathname_levels): Remove incorrect assertion and just
+ return 0 when pathname is NULL.
+
+2004-03-17 Derek Price <derek@ximbiot.com>
+
+ * subr.c (pathname_levels): Use ISDIRSEP() instead of strchr('/')
+ and remove FIXME comment to that effect.
+
+2004-03-16 Derek Price <derek@ximbiot.com>
+
+ * main.c (main): Update the --version Copyright (c) string to
+ include 2004.
+
+2004-03-15 Mark D. Baushke <mdb@cvshome.org>
+
+ * release.c (release): Add missing xmalloc of update_cmd.
+
+2004-03-15 Derek Price <derek@ximbiot.com>
+
+ * release.c (release): Enable authentication and encryption for a child
+ update process when necessary.
+ (Original patch from Dan Russell <russelld@aol.net> via Hal Mahaffey
+ <HMahaffey@aol.com>.)
+
+2004-03-14 Derek Price <derek@ximbiot.com>
+
+ * add.c (add): Only call server_updated() when we actual have a new
+ resurrected file for the client.
+
+2004-03-14 Derek Price <derek@ximbiot.com>
+
+ * cvs.h (previous_rev, write_letter): New prototypes.
+ (struct file_info): Move to before the write_letter prototype.
+ * add.c (add): Allow resurrection of files which used to exist on a
+ branch.
+ * subr.c (previous_rev): New function.
+ * update.c: Consolidate like pragmas.
+ (write_letter): Remove prototype. Remove static declaration.
+ * sanity.sh (resurrection): New tests.
+
+2004-03-14 Derek Price <derek@ximbiot.com>
+
+ * commit.c (remove_file): Print the actual previous revision instead of
+ a branch number.
+ * sanity.sh: Update to match.
+
+2004-03-14 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (RCS_cmp_file): Print the actual name of the file we failed to
+ open in the error message.
+
+2004-03-14 Derek Price <derek@ximbiot.com>
+
+ * diff.c (diff_fileproc): Allow diffing of new files against arbitrary
+ revisions instead of assuming that there is no RCS archive file.
+
+2004-03-03 Derek Price <derek@ximbiot.com>
+
+ * import.c (import): Check that the module name specified by the user
+ does not contain `CVS' as a directory name.
+ * ignore.c (ign_add): Never cease ignoring "CVS" - it is a reserved
+ name.
+ (Original patch from Dan Peterson <dbpete@aol.com>.)
+
+ * sanity.sh (import-CVS): New tests for the above.
+
+2004-02-29 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * import.c (expand_at_signs): Change type of len to size_t.
+ * subr.c (resolve_symlink): Move declaration of newname inside
+ #ifdef, clean up coding style.
+ * zlib.c (gunzip_and_write): Fix up potential overlow problems.
+ (read_and_gzip): Add explicit casts to placate paranoid compilers.
+
+2004-02-28 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * sanity.sh (join6): New tests for previous fix.
+
+ * update.c (join_file): One more fix to avoid dereferencing NULL.
+ (Reported by Steve McIntyre <steve@einval.com>.)
+ * sanity.sh (join6): New tests for above.
+
+2004-02-25 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * update.c (join_file): Fix optimization to avoid dereferencing NULL.
+ (Reported by Steve McIntyre <steve@einval.com>.)
+
+2004-02-25 Derek Price <derek@ximbiot.com>
+
+ * buffer.c (buf_empty): New function.
+ * server.c (server): Check for unread data in buffer before closing.
+
+2004-02-25 Derek Price <derek@ximbiot.com>
+
+ * release.c (release): Restore the initial directory before and after
+ calling various sections of code that expect it to prevent corruption
+ of CVS/Entries files on release of a subdir and tell unedit() what to
+ release.
+ * sanity.sh: Add test case for release.c fix.
+ (Original patch from Matthew Ogilvie <mmo9317bd@mailcan.com>.)
+
+ * client.c (last_entries): Move global variable...
+ (call_in_directory): ...here (now a local variable). Remove test that
+ always evaluates to true.
+ (last_dir_name): Remove unused global variable.
+
+2004-02-24 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * filesubr.c (xresolvepath): Fix crash in error case.
+ (Reported by Reinhard Zierke <zierke@informatik.uni-hamburg.de>.)
+
+2004-02-24 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (crerepos): Minor stylistic changes to previous change.
+
+2004-02-24 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (crerepos): Fix it so that it ignores the user's
+ .cvsrc file (.cvsrc "checkout -r" used to cause the "rm -r 1"
+ command to print warnings and wait for input).
+ (Original patch from Matthew Ogilvie <mmo9317bd@mailcan.com>.)
+
+ * sanity.sh (reposmv, parseroot, devcom3, binwrap3):
+ s/_SAVED\>/_save/ for consistency.
+
+2004-02-20 Derek Price <derek@ximbiot.com>
+
+ * subr.c (set_nonblock_fd): Move back to...
+ * server.c: ...here.
+ * cvs.h: Remove protos for the above two functions.
+ * buffer.c (stdio_buffer_shutdown): Remove unexessary and possibly
+ dangerous check for unread data on a pipe with a nonblock read.
+
+2004-02-20 Derek Price <derek@ximbiot.com>
+
+ * ChangeLog, commit.c, filesubr.c, rcs.c, root.c, sanity.sh, subr.c,
+ update.c: Remove VIM editor commands.
+
+2004-02-20 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * hash.h (struct node): Change data from char * to void *, change
+ all callers.
+
+2004-02-19 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * login.c (password_entry_operation): Initialize line.
+
+2004-02-19 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (crerepos): Correct comment.
+
+2004-02-19 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (crerepos): Don't create directories named `tmp' in
+ $TESTDIR to avoid conflicts with the default value of $TMPDIR.
+
+2004-02-19 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (directory_cmp): Use $TESTDIR for temporary files, like the
+ dotest functions.
+
+2004-02-19 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: No longer allow user override of $tmp. Set $TMPDIR to a
+ directory under $TESTDIR, as for $HOME, but still allowing for user
+ override. Check for cvs-serv* directories under $TMPDIR rather than
+ $tmp at the end of the script.
+
+2004-02-17 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Check for $PWD != $TESTDIR after each set of tests rather
+ than once at the end. Check that there are no cvs-serv* directories in
+ $tmp after each set of remote tests.
+
+2004-02-17 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Don't check for an empty $TESTDIR - if $TESTDIR was empty
+ then the preceding call to mkdir would have failed anyhow.
+
+2004-02-17 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * log.c (rlog_proc): Fix (harmless) uninitialized variable.
+
+ * sanity.sh (basicc): Add tests pointing out defective handling
+ of the Entries file.
+
+2004-02-17 Derek Price <derek@ximbiot.com>
+
+ * checkout.c (build_dir_and_chdir): Expand header comment.
+
+2004-02-15 Mark D. Baushke <mdb@cvshome.org>
+
+ * annotate.c (rannotate_proc): Plug a memory leak.
+ * log.c (log_fileproc): Ditto.
+ * 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.
+
+2004-02-12 Mark D. Baushke <mdb@cvshome.org>
+
+ * lock.c (readers_exist): Plug a memory leak.
+
+2004-02-12 Mark D. Baushke <mdb@cvshome.org>
+
+ * server.c (do_cvs_command): Plug a memory leak.
+
+2004-02-12 Derek Price <derek@ximbiot.com>
+
+ * modules.c: Reformat comment and line to fit in 80 chars.
+
+2004-02-12 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * modules.c (_do_module): Rename to my_module to avoid reserved name.
+ * stack.c (_push, _pop, _unshift, _shift): Rename to do_*.
+
+2004-02-11 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * root.c (parse_cvsroot): Set hostname in fork mode for error messages.
+ * buffer.c (stdio_buffer_shutdown): Undo previous change.
+
+2004-02-11 Mark D. Baushke <mdb@cvshome.org>
+
+ * buffer.c (buf_free): Plug a memory leak.
+ * commit.c (checkaddfile): Ditto.
+
+ * server.c (fd_buffer_shutdown): Avoid a double free().
+
+ * parseinfo.c (parse_config): Fix comments.
+
+2004-02-11 Derek Price <derek@ximbiot.com>
+
+ * buffer.c (stdio_buffer_shutdown): Add logic to avoid attempting to
+ print current_parsed_root->hostname when using the fork method.
+
+2004-02-11 Derek Price <derek@ximbiot.com>
+
+ * server.c (do_cvs_command): Simplify stream & pipe closing.
+ (Suggestion from Eric Siegerman <erics@telepres.com>.)
+
+ * cvs.h, subr.c (set_block_fd): Remove this unnecessary function.
+
+2004-02-11 Derek Price <derek@ximbiot.com>
+
+ * checkout.c (checkout_proc): s/is_absolute/isabsolute/.
+
+2004-02-11 Derek Price <derek@ximbiot.com>
+
+ * checkout.c (checkout_proc): Remove unneeded variable and enclosing
+ block.
+ * modules.c (_do_modules): Minor whitespace change.
+
+2004-02-10 Derek Price <derek@ximbiot.com>
+
+ * server.c (do_cvs_command): s/FIXCVS/FIXME/ in comment.
+ (set_block_fd, set_nonblock_fd): Move to...
+ * subr.c: ...here.
+ * cvs.h: Add protos for the above two functions.
+ * buffer.c (stdio_buffer_shutdown): Replace fgetc() which checked for
+ unread data on a pipe with a nonblock read.
+
+2004-02-10 Derek Price <derek@ximbiot.com>
+
+ * server.c (do_cvs_command): Have the server child close all the pipes
+ but the flow control pipe and wait on an EOF on the flow control pipe
+ from the parent when done to avoid a race condition that could
+ otherwise generate a SIGPIPE for the parent before the SIGCHILD when
+ the other pipes were so full after a child exited that the parent
+ attempted to write a stop byte to the flow control pipe.
+ (Original report from <jesse_off@stchome.com>.)
+
+2004-02-10 Derek Price <derek@ximbiot.com>
+
+ * buffer.c (stdio_buffer_shutdown): Add a helpful comment.
+
+2004-02-09 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (co-d): Update comments and tests to reflect the current
+ state of my side of my discussion with Larry Jones on how these
+ commands should behave.
+
+2004-02-09 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (emptydir): Add two new tests for how modules -d behaves
+ when a directory already exists in the user's workspace.
+ (emptydir): Add --keep functionality.
+
+2004-02-09 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (co-d): New test to prove `co -d' failure case.
+
+2004-02-05 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (recase): Fix typo that creeped in somehow between my last
+ test run and my commit.
+
+2004-02-04 Derek Price <derek@ximbiot.com>
+
+ * stack.c (shift, shift_string): Make sure these functions return their
+ result.
+
+2004-02-04 Derek Price <derek@ximbiot.com>
+
+ * modules.c (do_modules): Move content to and make this function a
+ wrapper for...
+ (_do_modules): ...this new function which can watch for infinite loops
+ in alias modules.
+ * stack.c (_push, _pop, _unshift, _shift, push_string, pop_string,
+ unshift_string, shift_string): New
+ functions.
+ * stack.h (push_string, pop_string, unshift_string, shift_string: New
+ prototypes.
+ * sanity.sh (modules): Add check for nested alias loops.
+
+2004-02-04 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (recase): Update test names and comments for clarity and
+ consistency.
+
+2004-02-03 Derek Price <derek@ximbiot.com>
+
+ Preserve the case of checked out directories in a path as well as file
+ names for client communication with the server.
+
+ * Makefile.am (cvs_SOURCES): Add stack.c & stack.h.
+ * stack.c, stack.h: New files.
+ * cvs.h: Include stack.h.
+ * client.c (send_file_names): Preserve the case of directories in a
+ path as well as file names for communication with the server.
+
+ * Makefile.in: Regenerated.
+
+2004-02-02 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (join-rm): New test for issue #104 & #159.
+
+2004-02-02 Derek Price <derek@ximbiot.com>
+
+ Continue removal from server of handling of case insensitive clients.
+
+ * cvs.h: Remove extern declaration of ign_case.
+ * ignore.c (ign_case): Remove declaration.
+ (ign_name): Remove support for ign_case.
+ * server.c (serve_case): Ditto.
+ (requests): No longer support the "Case" request.
+ * rcs.c (locate_rcs): Remove reference to GLOBAL in function header
+ comment.
+
+2004-02-02 Derek Price <derek@ximbiot.com>
+
+ * add.c, client.c, cvs.h, rcs.c, subr.c: Remove server support for case
+ insensitivity.
+
+2004-01-25 Derek Price <derek@ximbiot.com>
+
+ * server.c (kserver_authenticate_connection): Fix call to
+ switch_to_user().
+ (Original patch from Alexey Mahotkin <alexm@hsys.msk.ru>.)
+
+2004-01-22 Derek Price <derek@ximbiot.com>
+
+ * modules.c (do_module): Strip trailing slashes before checking for
+ infinite alias loops.
+ * sanity.sh (modules): Tests for response to infinite alias loops.
+
+2004-01-17 Mark D. Baushke <mdb@cvshome.org>
+
+ * logmsg.c (do_verify): Eliminate double-free bug.
+ (Original patch from Gerald Combs.)
+
+2004-01-07 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * checkout.c (safe_location): Remove unused variable(s).
+ * lock.c (lock_tree_for_write): Ditto.
+ * rcs.c (RCS_checkin): Ditto.
+ * subr.c (compare_revnums): Ditto.
+ * tag.c (tag_check_valid): Ditto.
+ * mkmodules.c (init): Initialize err and return it rather than 0.
+ * server.c (do_cvs_command): Only define and set max_command_fd if
+ we're actually going to use it.
+
+2004-01-01 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * zlib.c (read_and_gzip, gunzip_and_write): Fix potential buffer
+ overruns, use names for magic numbers.
+ (Original patch from Jeff Downs <heydowns@borg.com>.)
+
+2003-12-18 Derek Price <derek@ximbiot.com>
+
+ * server.c (switch_to_user): SysLog attempts to root from pserver.
+
+2003-12-18 Derek Price <derek@ximbiot.com>
+
+ * server.c (switch_to_user): Don't allow CVS to run as root in pserver
+ mode.
+ (Original patch from Wichert Akkerman via Bradley M Kuhn
+ <bkuhn@fsf.org>.)
+ * sanity.sh (pserver): Check for bad root error message.
+
+2003-12-17 Larry Jones <lawrence.jones@eds.com>
+
+ * run.c (close_on_exec): fcntl is not documented to return 0 for
+ success (and QNX doesn't), only -1 for error.
+ (Patch from George Refseth <george.refseth@arxi.no>.)
+
+2003-12-09 Mark D. Baushke <mdb@cvshome.org>
+
+ * server.c (template_proc): Fix broken Template protocol code.
+ Must call send buf_send_counted() for Template files to avoid
+ "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...
+ (recase-8sscs): ...this to match the convention.
+
+2003-12-03 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (recase): Add some clarifying comments.
+
+2003-12-03 Larry Jones <lawrence.jones@eds.com>
+
+ * expand_path.c (expand_variable): Expand ${CVSROOT} to just the
+ directory like it's supposed to be.
+ (Reported by Michael S. Tsirkin <cvs1@misha.eml.cc>.)
+
+2003-11-26 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (modules3-2): Simplify syntax that may have given Cygwin
+ intermittent conniptions.
+
+2003-11-25 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (recase-17sscs): Use ${CVSROOT_DIRNAME} in pattern.
+
+2003-11-25 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (release): Perform forgotten cleanup.
+
+2003-11-25 Derek Price <derek@ximbiot.com>
+
+ * commit.c (commit_fileproc): Reword comment.
+
+2003-11-25 Derek Price <derek@ximbiot.com>
+
+ * add.c (add): Disable ign_case for the purposes of adding a file so
+ that recasing the name of a file is possible from a case insensitive
+ client.
+ * sanity.sh (recase): New tests for behavior which varies when the
+ client and/or the server are case insensitive.
+
+2003-11-25 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (devcom3-9ar): Ignore the stderr output since it varies
+ considerably between platforms.
+
+2003-11-24 Larry Jones <lawrence.jones@eds.com>
+
+ * diff.c (diff_file_nodiff): use_rev1 does *not* imply that diff_rev1
+ is not null, diff_date1 could be set instead (ditto for use_rev2).
+ (Reported by <jnelson-cvsbug@jamponi.net>.)
+
+2003-11-24 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (modes3): Skip modes3-5 entirely under Cygwin since
+ permisions are broken there. This change removes most of the earlier
+ Cygwin differentiation in this test ($cygwin_hack & $cygwin_hack2) in
+ favor of skipping the test entirely.
+
+2003-11-21 Larry Jones <lawrence.jones@eds.com>
+
+ * hash.c (printnode, printlist): Cast %p arguments to void * as
+ required by the C standard.
+
+2003-11-21 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Add `-h <hostname>' option to enable testing across a
+ :ext: connection to another host. Warn when `-h' is specified without
+ $TESTDIR. Leave $TESTDIR intact when it looks absolute since it may
+ contain symlinks. Allow $CVS_SERVER to be overridden via the
+ environment for `-h'. Default $CVS_RSH to `rsh'.
+ (*): Use $CVS_RSH to perform certain commands on the remote host (esp.
+ `ln -s' and `chmod') when `-h' is specified to work around
+ incompatibilities with CygWin & Samba. Add a few other minor
+ workarounds for Cygwin bugs.
+
+ (newroot): New function.
+ (*): Use newroot when appropriate.
+
+2003-11-19 Larry Jones <lawrence.jones@eds.com>
+
+ * rcs.c (RCS_getrevtime): Add error checking; cleanup.
+
+2003-11-18 Derek Price <derek@ximbiot.com>
+
+ * modules.c (do_module): Reject absolute paths.
+ (Report and suggested fix from Tony Hoyle <tmh@nodomain.org>.)
+
+ * sanity.sh (abspath2): Check for the above.
+ (spacefiles): Remove tests that expect absolute paths to files in the
+ top level repository directory to work.
+ (tests): Add abspath2.
+
+2003-11-13 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (RCS_delete_revs): It's `&&', not `and'.
+
+2003-11-13 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Create the empty log to make it easier to tail immediately
+ after the script is started.
+
+2003-11-13 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (exit_help): Correct help to specify `-H' and not `-h' as
+ the help option.
+
+2003-11-13 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (RCS_delete_revs): Don't use the WOE32 kludge which refuses to
+ delete revisions from bvinary files on Cygwin. I'm not sure what the
+ kludge was trying to avoid, but commenting it out causes the test suite
+ to pass.
+
+2003-11-10 Derek Price <derek@ximbiot.com>
+
+ * commit.c (check_fileproc, find_fileproc): Don't leak memory.
+
+2003-11-10 Derek Price <derek@ximbiot.com>
+
+ * commit.c (find_fileproc, check_fileproc): Refuse to remove files
+ when the file exists in the sandbox. This used to cause data loss.
+ (Report from Andreas Reifschneider <andyreif@studcs.uni-sb.de>.)
+
+ * sanity.sh (rmadd3): Update to match. Expand comments.
+
+2003-11-10 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (rmadd3): Test the behavior of commit after the
+ add/replace.
+ (Report from Andreas Reifschneider <andyreif@studcs.uni-sb.de>.)
+
+2003-11-10 Mark D. Baushke <mdb@cvshome.org>
+
+ * Backport symlink bugfix from cvs 1.12.1.1 feature release
+ as written by Derek Price <derek@ximbiot.com>. (This fixes
+ the Issue 142 bug.)
+
+ * recurse.c (start_recursion): Accept new repository argument so
+ that the working directory may be tracked by do_recursion without
+ using xgetwd(), which returned a value different from the one the
+ user requested when symlinks were in use. Pass repository_in to
+ do_recursion() as part of the recursion frame.
+
+ * cvs.h (xreadlink): #ifdef HAVE_READLINK proto.
+ (xresolvepath): New proto.
+ (start_recursion): Add repository to proto.
+
+ * checkout.c (safe_location): Add more complete header comment.
+ Add trace. Use new xresolvepath() function. Always return true
+ in client mode since checking our destination path against the
+ CVSROOT path is usually meaningless in client/server mode.
+ (checkout_proc): Pass repository to do_update() for later use with
+ start_recursion().
+
+ * admin.c (admin): Use new definition of start_recursion().
+ * annotate.c (rannotate_proc): Ditto.
+ * client.c (send_files): Ditto.
+ * commit.c (commit): Ditto.
+ * diff.c (diff): Ditto.
+ * edit.c (watch_onoff, send_notifications, edit, unedit, editors):
+ Ditto.
+ * lock.c (lock_tree_for_write): Ditto.
+ * log.c (rlog_proc): Ditto.
+ * patch.c (patch_proc): Ditto.
+ * remove.c (cvsremove): Ditto.
+ * tag.c (rtag_proc): Ditto.
+ * update.c (do_update): Ditto.
+ * watch.c (watch_addremove, watchers): Ditto.
+
+ * patch.c (patch_proc): Call tag_check_valid with repository
+ instead of NULL.
+
+ * filesubr.c (xreadlink): #ifdef HAVE_READLINK this function. Add
+ more complete header comment.
+ (xresolvepath): New function.
+
+ * recurse.c (do_recursion): Call Lock_Cleanup() only repository
+ was set.
+
+ * update.c (do_update): Accept new repository argument so that the
+ working directory may be tracked.
+ (update): Pass NULL repository to do_update().
+ * update.c (do_update): Add repository to proto.
+
+ * checkout.c (checkout_proc): Use new definition of do_update().
+ * update.c (update): Ditto.
+
+ * sanity.sh: Add new -l option to test symlinked roots.
+ (checkout_repository-1): Add server error messages about absolute
+ paths since the client now skips destination validity checks.
+ (check_repository-2): Test renamed to checkout_repository-2.
+ (checkout_repository-2): Process client error messages about
+ 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_repository-3): Test renamed to checkout_repository-3.
+ (dottedroot): New test to check that a CVSROOT with a "." in the
+ name will work.
+
+2003-11-10 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (rmadd3): Add whitespace after end of test for readability.
+
+2003-11-10 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (rmadd3): New tests that confirms that CVS refuses to
+ delete a file it thinks was already removed.
+ (Report and test from Andreas Reifschneider
+ <andyreif@studcs.uni-sb.de>.)
+
+2003-11-03 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (server): Test that the global `-l' option is ignored
+ nonfatally.
+
+2003-11-01 Larry Jones <lawrence.jones@eds.com>
+
+ * ignore.c (ignore_files): Use CVS_LSTAT() instead of lstat().
+ * filesubr.c (xcmp): Make sure S_ISLNK exists before calling it.
+ (Reported by Paul Edwards <kerravon@nosppaam.w3.to>.)
+
+2003-10-31 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (checkout_repository): Name tests consistently.
+
+2003-10-31 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: s/${TESTDIR}/cvsroot/${CVSROOT_DIRNAME}/.
+
+2003-10-28 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (devcom): s/cvs/$PROG/.
+
+2003-10-28 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (devcom): Renumber tests and use dotest function.
+
+2003-10-28 Derek Price <derek@ximbiot.com>
+
+ * sever.h: Add the standard copyright notice.
+
+2003-10-28 Derek Price <derek@ximbiot.com>
+
+ * lock.c: Remove some suggestions which have already been implemented
+ or which have become obsolete from the header comment.
+
+2003-10-26 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (join6): Fix a few typos in the last test and remove a
+ misplaced test.
+
+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
+ CVSROOT and cvsroot are the same directory (eg, MacOS X).
+
+2003-10-24 Derek Price <derek@ximbiot.com>
+
+ * update.c (join_file): Restore the optimization Mark recently removed,
+ but fix it. Move one other optimization up since it needs to be
+ checked for first. Add bew status messages like merge_file produces
+ when the requested diff has already been applied to the destination.
+ Expand header comment.
+ * sanity.sh (join6): Add tests for the new error messages.
+ (import-113, join-admin-2, diffmerge1): Fix collateral damage.
+
+2003-10-23 Mark D. Baushke <mdb@cvshome.org>
+
+ * update.c (join_file): Do the -jrev1 -jrev2 merge even when
+ the file is already at rev2.
+ * 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
+ on failure.
+
+2003-10-19 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (admin-31): Fix more typos.
+
+2003-10-18 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (admin): Fix a typo.
+
+ * admin.c (admin_fileproc): Restore the ':' character in the
+ -mtag:message admin argument even if the tag does not exist so
+ that other files with the tag will be found. Also, be more
+ paranoid that a symbolic tag actually points to a version that
+ 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
+ -mversion:message rather than altering the wrong log message.
+ (Patch from "Rodolfo Schulz de Lima" <rodsoft@uol.com.br>.)
+ * sanity.sh (admin): Test case for it.
+
+2003-10-15 Larry Jones <lawrence.jones@eds.com>
+
+ * commit.c (commit_fileproc, finaladd): Don't call fixaddfile()
+ if the RCS file didn't get created at all.
+ (Reported by David Wood <David.Wood@thestreet.com>.)
+
+2003-10-14 Derek Price <derek@ximbiot.com>
+
+ Port to pedantic POSIX 1003.1-2001 hosts, such as Debian GNU/Linux
+ testing with _POSIX2_VERSION=200112 in the environment.
+
+ * sanity.sh: Use 'sed 1q', not 'head -1'.
+ (Patch from Paul Eggert <eggert@twinsun.com>.)
+
+2003-10-10 Derek Price <derek@ximbiot.com>
+
+ * lock.c (set_lock): Clarify comment.
+
+2003-10-08 Derek Price <derek@ximbiot.com>
+
+ * Makefile.am (cvs_SOURCES): Add history.h.
+ * history.c: Include history.h. Add the `P' record types to more
+ comments. s/ALL_REC_TYPES/ALL_HISTORY_REC_TYPES/.
+ (usage): Reference ALL_HISTORY_REC_TYPES rather than using a separate
+ string literal.
+ (report_hrecs): Handle `P' record type.
+ (ALL_REC_TYPES): Rename and move...
+ * history.h (ALL_HISTORY_REC_TYPES): ...here.
+ * mkmodules.c: Include history.h.
+ (config_contents): Update contents of and references to LogHistory
+ records to use ALL_HISTORY_REC_TYPES.
+ * sanity.sh (basic2-64): Update to include history records of type `P'.
+
+ * Makefile.in: Regenerated.
+
+2003-10-08 Derek Price <derek@ximbiot.com>
+
+ * update.c (patch_file): Correct spelling and punctuation in comment.
+ Update some lines to fit in 80 characters.
+
+2003-10-08 Larry Jones <lawrence.jones@eds.com>
+
+ * history.c (history): Don't conflate -e with -x since the client's
+ idea of what -e means may not match the server's.
+ (Reported by Frank Hemer <frank@hemer.org>.)
+
+2003-10-07 Larry Jones <lawrence.jones@eds.com>
+
+ * sanity.sh: Use dotest_fail instead of dotest_status for diff tests
+ since CVS only returns success/fail rather than 0/1/2 like diff does.
+
+2003-10-07 Derek Price <derek@ximbiot.com>
+
+ Fix a client/server bug introduced via the data loss fix of 2003-03-17.
+ Basically, the server was reporting ambiguous filename requests when it
+ should have been trusting the user to type the intended case or using
+ the case the client preserved in CVS/Entries before it tried to look
+ anything up in case insensitive mode.
+
+ * rcs.c (locate_rcs): Use the filename exactly as cased before
+ investigating a case insensitive lookup, per the client/server protocol
+ specification. Expand comments.
+ * subr.c (locate_file_in_dir): This function only needs to locate files
+ case insensitively. Expand comments.
+ * cvs.h (locate_file_in_dir): Only prototype when servers which need to
+ handle case insensitivity are being compiled.
+
+2003-10-07 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (locate_rcs): Declare static. Move to an earlier location in
+ file to avoid prototyping.
+ * rcs.h (locate_rcs): Remove proto.
+
+2003-10-03 Derek Price <derek@ximbiot.com>
+
+ * server.c (serve_global_option): Warn that -l is being ignored rather
+ than exiting fatally due to backwards compatibility complaints from
+ administrators.
+
+2003-09-29 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (make_file_label): Make a failure to stat a file a fatal error
+ since it signals that a later read will also fail.
+
+2003-09-26 Derek Price <derek@ximbiot.com>
+
+ * diff.c (diff): Add a FIXME re spaces in diff arguments.
+
+2003-09-25 Mark D. Baushke <mdb@cvshome.org>
+
+ * rcs.c (make_file_label): Do not return an uninitialized label.
+ (Reported by "Todd C. Miller" <Todd.Miller@courtesan.com>)
+
+2003-09-12 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (mkmodules): Correct comments.
+
+2003-09-12 Derek Price <derek@ximbiot.com>
+
+ * mkmodules.c (mkmodules): Do not pass a string which came from the
+ checkoutlist file directly to error as a format string since we don't
+ want to trust any user with access to checkoutlist with creating printf
+ format strings. I already claimed I did this in the NEWS file.
+ (Thanks to Larry Jones for spotting my mistake.)
+ * sanity.sh (mkmodules): Test for the above.
+
+2003-09-12 Derek Price <derek@ximbiot.com>
+
+ * mkmodules.c (checkoutlist_contents): Document the optional portions
+ of this file format more accurately.
+ (mkmodules): Ditto, in comments. Fix bug that always failed to ignore
+ whitespace before error messages.
+ * sanity.sh (mkmodules-temp-file-removal): Rename to...
+ (mkmodules): ...this and add a test of the checkoutlist error message.
+ Add cleanup step to restore checkoutlist.
+
+2003-08-27 Larry Jones <lawrence.jones@eds.com>
+
+ * history.c: 'P' is a valid record type and has been for a long time.
+ Add it to the comments, usage message, and, most important,
+ ALL_REC_TYPES so it gets recorded by default.
+ * server.c (do_cvs_command): Set global command_name to the real
+ command name rather than leaving it set to "server".
+ * sanity.sh: Update to match.
+ (Reported by Dmitry Ryzhkov <rdim_outside@softhome.net>.)
+
+2003-08-13 Larry Jones <lawrence.jones@eds.com>
+
+ * server.c (server_cleanup): Don't shutdown buf_from_net if it's
+ null.
+ (Reported by Scott Mitchell <scott@fishballoon.org>.)
+
+2003-08-01 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (join5): Use $PROG consistently and escape a `.'.
+
+2003-08-01 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (join5): Use `[a-z]*' as opposed to `update'.
+
+2003-07-31 Derek Price <derek@ximbiot.com>
+
+ * add.c (add_directory): Restore a malloc I shouldn't have altered on
+ the stable branch.
+
+2003-07-31 Derek Price <derek@ximbiot.com>
+
+ * rcscmds.c (RCS_merge): Pass `--' before the filename arguments to
+ diff so that filenames starting with `-' can be merged.
+ * sanity.sh (join5): New test for same.
+
+2003-07-31 Derek Price <derek@ximbiot.com>
+
+ * add.c (add_directory): Don't print status information in really_quiet
+ mode.
+
+2003-07-29 Derek Price <derek@ximbiot.com>
+
+ * commit.c (checkaddfile): Simplify the logic here, using assumptions
+ already made later in the function to remove calls to locate_rcs and
+ some conditionals. Use same assumptions to remove some variables.
+
+2003-07-29 Derek Price <derek@ximbiot.com>
+
+ * login.c: Remove GETPASS & HAVE_GETPASSPHRASE cruft in favor of always
+ using the GNULIB getpass since the system getpass was removed from the
+ POSIX.2 specification.
+
+2003-07-28 Derek Price <derek@ximbiot.com>
+
+ * subr.c (strip_trailiing_newlines): Use size_t rather than int to
+ count string length.
+ (Suggestion from Paul Edwards, who provides a broken return email
+ address in Tonga. I believe he is actually from Australia.)
+
+2003-07-28 Derek Price <derek@ximbiot.com>
+
+ * checkout.c (checkout): Remove out-of-date comment about Checkin.prog
+ and Update.prog.
+
+2003-07-25 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (RCS_parsercsfile): Declare rcsfile argument as const.
+ * rcs.h (RCS_parsercsfile): Update prototype to match.
+ * commit.c (fixaddfile): Accept a single path to an rcs file as an
+ argument rather than trying to look it up again when it is not
+ necessary.
+
+2003-07-25 Derek Price <derek@ximbiot.com>
+
+ * commit.c (finaladd): But don't free variables we no longer allocate.
+
+2003-07-25 Derek Price <derek@ximbiot.com>
+
+ * checkin.c (Checkin): The rcs argument is unecessary since we know
+ that the parsed RCS data always exists as part of finfo by the time
+ this function gets called.
+ * commit.c (commit_fileproc, finaladd): Use new Checkin() API.
+ * cvs.h (Checkin): Update prototype.
+
+2003-07-25 Derek Price <derek@ximbiot.com>
+
+ * subr.c (strip_trailing_newlines): Check len b4 str[len] to avoid
+ exceeding the array bounds when the string length == 0.
+ (Report from John Tytgat <JoTy@esko-graphics.com>.)
+
+2003-07-25 Derek Price <derek@ximbiot.com>
+
+ * subr.c (strip_trailing_newlines): Generalize this function to watch
+ len so that it cannot walk past the beginning of the string passed in.
+ (Report from John Tytgat <JoTy@esko-graphics.com>.)
+
+2003-07-25 Derek Price <derek@ximbiot.com>
+
+ * subr.c (strip_trailing_newlines): Leave the K&R function decl on this
+ branch.
+
+2003-07-25 Derek Price <derek@ximbiot.com>
+
+ * cvs.h (strip_trailing_newlines): Update prototype.
+ * subr.c (strip_trailing_newlines): Return true when newlines are
+ removed.
+ * server.c (pserver_authenticate_connection): Don't give a DOS attack a
+ chance to authenticate accidentally because I like to be paranoid.
+ * sanity.sh (pserver): New test for same.
+
+2003-07-20 Derek Price <derek@ximbiot.com>
+
+ * wrapper.c: Remove mention of obsolete -f and -t wrapper options from
+ a comment.
+
+2003-07-12 Larry Jones <lawrence.jones@eds.com>
+
+ * sanity.sh (diffnl): New tests for diff on files with no newline
+ at end.
+ (Patch from Andrew Moise <chops@demiurgestudios.com>.)
+
+2003-07-09 Larry Jones <lawrence.jones@eds.com>
+
+ * add.c (add): Update "re-adding" message to have quotes around
+ the file name like all the other similar messages.
+ * sanity.sh: Update to match.
+
+ * update.c (join_file): Handle locally removed but not yet committed
+ files.
+ (Reported by Larry Lords <LordsLL@ldschurch.org>.)
+ * sanity.sh (join, join4): New tests for above.
+
+2003-06-28 Larry Jones <lawrence.jones@eds.com>
+
+ * commit.c (fixaddfile): Bail out if locate_rcs() fails. Make
+ parameters const.
+
+ * add.c (add): Fix -Wall complaints.
+ * diff.c (diff_file_nodiff): Ditto.
+ * filesubr.c (cvs_casecmp): Ditto.
+ * patch.c (patch_fileproc): Ditto.
+ * rcs.c (RCS_cmp_file): Ditto.
+ * root.c (parse_cvsroot): Ditto.
+ * subr.c (locate_file_in_dir): Ditto.
+ * cvs.h (cvs_casecmp, locate_file_in_dir): Update prototypes.
+
+2003-06-27 Larry Jones <lawrence.jones@eds.com>
+
+ * lock.c (readers_exist): Use LockDir rather than always looking
+ in the repository.
+ (Original patch from Robert Ambalu <Robert.Ambalu@gs.com>.)
+ Remove vestigial lock promotion code.
+
+2003-06-26 Larry Jones <lawrence.jones@eds.com>
+
+ * hash.c (sortlist): Avoid crash when list is null.
+
+2003-06-23 Derek Price <derek@ximbiot.com>
+
+ * patch.c (patch_fileproc): Output revision number of the original
+ revision in the removed case.
+ (Idea from Paul Edwards <kerravon@w3.to>.)
+
+ * sanity.sh (rdiff-add-remove-nodiff): Rename to...
+ (rdiff-short): ...this. Test for the above changes. Add some tests
+ for when rev2 defaults to the trunk. Expand comments.
+
+2003-06-23 Derek Price <derek@ximbiot.com>
+
+ * add.c (add): Fix xmalloc's strlen() of wrong variable.
+ * checkout.c (safe_location): leak: reused where_location without free.
+ * log.c (rlog_proc): leak: free where before exit.
+ * logmsg.c (do_verify): leak: free verifymsg_script before exit.
+ (Original patch from Kenneth Lorber <keni@his.com>.)
+
+2003-06-20 Derek Price <derek@ximbiot.com>
+
+ * client.c: Remove silly comment.
+ (Patch from Alexey Mahotkin <alexm@hsys.msk.ru>.)
+
+2003-06-13 Derek Price <derek@ximbiot.com>
+
+ * subr.c (file_has_conflict): Fix comment.
+ (Patch from Paul Edwards <kerravon@w3.to>.)
+
+2003-06-13 Derek Price <derek@ximbiot.com>
+
+ * subr.c (xrealloc): Trivial comment fix.
+ (Patch from Kenneth Lorber <keni@his.com>.)
+
+2003-06-13 Derek Price <derek@ximbiot.com>
+
+ * diff.c (diff_fileproc): Fix memory leak.
+ (Patch from Kenneth Lorber <keni@his.com>.)
+
+2003-06-12 Derek Price <derek@ximbiot.com>
+
+ * root.c (parse_cvsroot, local_cvsroot): Parse trailing '/'s off the
+ end of cvsroots. Make arguments const.
+ * cvs.h: Update prototypes to match.
+ (Idea from Miles Zarathustra <shiva@aranyaka.org>.)
+
+2003-06-11 Larry Jones <lawrence.jones@eds.com>
+
+ * sanity.sh: Change warning messages to note that defective tools
+ can result in defective results, both pass and fail. Also change
+ "which" to "that" for errant grammar pedants.
+
+2003-06-09 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (RCS_delete_revs): Reference WOE32 rather than WIN32 in
+ accordance with the GNU convention to avoid implying that we consider
+ the Microsoft Windows Operating Environment any sort of "win".
+
+2003-06-09 Derek Price <derek@ximbiot.com>
+
+ * filesubr.c (cvs_temp_file): Tidy a comment.
+
+2003-06-09 Derek Price <derek@ximbiot.com>
+
+ * patch.c (patch_fileproc): Don't assume the content of files is
+ different just because the revision number is different.
+ * sanity.sh (rdiff-add-remove-nodiff): New tests for the above.
+ (Report & original patches from Paul Edwards <kerravon@w3.to>.)
+
+2003-06-04 Derek Price <derek@ximbiot.com>
+
+ * cvs.h (locate_file_in_dir): New proto.
+ (locate_rcs): Move proto...
+ * rcs.h: ...here.
+ * filesubr.c (locate_rcs): Move function...
+ * rcs.c: ...here for Windows.
+ * filesubr.c (locate_file_in_dir): Move function...
+ * subr.c: ...here for Windows.
+
+2003-06-02 Derek Price <derek@ximbiot.com>
+
+ * diff.c (diff_file_nodiff): Don't assume that because two specified
+ revision numbers are different, the contents are different.
+ (Original report & patch from Paul Edwards <kerravon@w3.to>.)
+
+ * diff.c (diff_file_nodiff): Pass through rev1_cache to be filled in
+ by RCS_cmp_file when it needs to check out revision 1 into a file. Add
+ some more informative error messages. Cleanup for efficiency &
+ readability.
+ (diff_fileproc): Pass the cached revision to RCS_exec_diff(). Clean up
+ the error exit code. Remove code killed by the changes to
+ diff_file_nodiff().
+ * rcscmds.c (RCS_exec_rcsdiff): Accept and use new cached revision text
+ if present.
+ * rcs.c (RCS_cmp_file): Accept a second revision number and cache the
+ first revision if it needs to be checked out.
+
+ * checkin.c (Checkin): Use new RCS_cmp_file().
+ * import.c (update_rcs_file): Ditto.
+ * no_diff.c (No_Difference): Ditto.
+
+ * cvs.h (RCS_exec_rcsdiff): New proto to match above changes.
+ * rcs.h (RCS_cmp_file): Ditto.
+
+ * sanity.sh: Minor corrections to handle the above changes.
+
+2003-05-29 Derek Price <derek@ximbiot.com>
+
+ * client.c (start_server): Don't send -l to server.
+ * history.c (history_write): Fix comment.
+ * main.c (main): Don't process -l.
+ * server.c (serve_global_option): Ditto.
+ (Suggestion from Rob Lanphier <robla@real.com>.)
+
+2003-05-23 Larry Jones <lawrence.jones@eds.com>
+
+ * sanity.sh (info-cleanup-verifymsg): Avoid race in output.
+
+2003-05-22 Larry Jones <lawrence.jones@eds.com>
+
+ * commit.c (commit): Fix leading zero stripping code to not strip
+ unless there's a following digit.
+
+ * parseinfo.c (Parse_Info): Warn if multiple DEFAULT lines found.
+ * sanity.sh (info): New test for above.
+
+2003-05-21 Derek Price <derek@ximbiot.com>
+
+ * Makefile.in: Regenerate with Automake version 1.7.5.
+
+2003-05-20 Larry Jones <lawrence.jones@eds.com>
+
+ * parseinfo.c (Parse_Info): Fix stupid memory management error.
+
+ * logmsg.c (do_verify): Treate Parse_Info errors as failure.
+ * parseinfo.c (Parse_Info): Don't call expand_path until executing
+ the command so that errors in unexecuted commands aren't reported.
+ * sanity.sh (info): New tests for above.
+
+2003-05-18 Mark D. Baushke <mdb@gnu.org>
+
+ * Makefile.am (localcheck,remotecheck): Use cvs$(EXEEXT) not cvs.
+ * Makefile.in: Regenerated.
+ * sanity.sh (status-init-7): Use ${PROG} not cvs in tests.
+ (branch-after-import-5): Ditto.
+ (keywordname-update-11): Ditto.
+
+2003-05-18 Larry Jones <lawrence.jones@eds.com>
+
+ * server.h (kserver_authenticate_connection,
+ pserver_authenticate_connection): Add prototypes.
+
+ * client.c (update_entries): Set file's access time to the current
+ time rather than the same as the modification time.
+ * vers_ts.c (Version_TS): Ditto.
+
+2003-05-01 Derek Price <derek@ximbiot.com>
+
+ * main.c (main): Ignore -z when CLIENT_SUPPORT is not defined.
+ (Report from Jim Salter <jsalterjim@earthlink.net>.)
+
+2003-05-01 Derek Price <derek@ximbiot.com>
+
+ * repos.c (Sanitize_Repository_Name): Remove some old comments about
+ the defunct RELATIVE_REPOS macro.
+ * server.c (outside_root): Ditto.
+
+2003-04-30 Derek Price <derek@ximbiot.com>
+
+ * add.c (add): Fix a possible, if unlikely, memory out of bounds error.
+
+2003-04-28 Derek Price <derek@ximbiot.com>
+
+ * client.c (save_prog): Remove unneeded struct.
+ (checkin_progs, update_progs): Remove these unneeded globals.
+ (handle_set_checkin_prog, handle_set_update_prog, do_deferred_progs):
+ Remove these functions.
+ (send_repository): Remove checkin and update prog support.
+ (responses): Remove Set-checkin-prog and Set-update-prog.
+ (get_responses_and_close): Don't call do_deferred_prog().
+ * commit.c (commit_usage): Remove reference to -n.
+ (commit): Don't set and send run_module_prog via -n. Don't run
+ Checkin.prog or Checkout.prog in local mode.
+ * modules.c (CVSMODULE_OPTS): Remove -i and -u.
+ (do_module): Don't process -i and -u options to set checkin and update
+ progs, respectively.
+ * server.c (server_prog, serve_checkin_prog, server_update_prog):
+ Remove unused functions.
+ (requests): Remove Checkin-prog and Update-prog.
+ * update.c (update_dirleave_proc): Remove update prog functionality.
+
+ * cvs.h (CVSADM_CIPROG, CVSADM_UPROG): Remove unneeded defines.
+ * server.h (server_prog): Remove proto.
+ (progs): Remove enum.
+
+ * sanity.sh (modules5): Remove tests for checkin and update programs.
+
+2003-04-10 Larry Jones <lawrence.jones@eds.com>
+
+ * Makefile.in: Regenerated.
+
+2003-03-27 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (rdiff2): Add new test case for SEGV problem reported
+ against cvs 1.11.5.
+ (Report from James Cribb)
+
+2003-03-26 Derek Price <derek@ximbiot.com>
+
+ * client.c: Fix, reorganize, and comment ifdefs for AUTH_CLIENT_SUPPORT
+ and HAVE_GSSAPI.
+ * client.h: Ditto. Remove some unecessary server function prototypes.
+
+2003-03-26 Derek Price <derek@ximbiot.com>
+
+ * client.c: Include the net headers for HAVE_GSSAPI.
+ (Report from Jim Salter <jsalterjim@earthlink.net>.)
+
+2003-03-26 Derek Price <derek@ximbiot.com>
+
+ * main.c (main): Verify the argument to -z when running without
+ CLIENT_SUPPORT since Eric Siegerman complained about being bit
+ by a run of `cvs -z -n up' which parsed the -n as the argument to
+ -z.
+ * sanity.sh (opterrmsg): New tests for -z argument checking.
+
+2003-03-26 Larry Jones <lawrence.jones@eds.com>
+
+ * main.c (main): Use strtol() instead of atoi() when parsing -z
+ to detect errors.
+ (Reported by Eric Siegerman <erics@telepres.com>.)
+
+2003-03-24 Derek Price <derek@ximbiot.com>
+
+ * Makefile.am: Update copyright notice.
+
+ * Makefile.in: Regenerated.
+
+2003-03-19 Larry Jones <lawrence.jones@eds.com>
+
+ * filesubr.c (mkdir_if_needed): Save errno since isdir() can clobber.
+ (Patch from Brian Poole <raj@cerias.purdue.edu>.)
+ * sanity.sh (abspath-4): Update to match.
+
+ * filesubr.c (locate_rcs): Fix gcc warning.
+
+2003-03-17 Derek Price <derek@ximbiot.com>
+
+ * add.c: Correct comment.
+ * client.c: Ditto.
+ * checkin.c (Checkin): Pass work file name to RCS_checkin so that this
+ function works properly in the case insensitive mode.
+ * commit.c (checkaddfile): Fix and factor add logic so that the
+ correct files and directories are created in the case insensitive mode.
+ Reuse code in RCS_parse() below. This avoids a problem that could
+ cause corrupted RCS files to be created on an add from a case
+ insensitive system. Corrupted RCS files could cause later assertion
+ failures for everyone.
+ (locate_rcs): Move this function...
+ * filesubr.c (locate_rcs): ...here and rewrite it.
+ (fopen_case): Remove this function.
+ (locate_file_in_dir): New function.
+ * cvs.h (locate_rcs): Prototype new function.
+ * rcs.c (RCS_parse): Factor out file location into locate_rcs.
+
+2003-03-17 Larry Jones <lawrence.jones@eds.com>
+
+ * server.c (switch_to_user): Add syslog calls for setgid/setuid
+ failure.
+
+2003-03-07 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (help): Add explanation of CVS-TO-TEST and edit for
+ consistency.
+
+2003-03-07 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (usage): Show users long --help rather than less
+ informative -h.
+
+2003-03-07 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Add support for long options.
+ (exit_usage): Move the actual generation of usage text to...
+ (usage): ...this new function and improve the usage message.
+ (exit_help): New function.
+
+2003-03-07 Larry Jones <lawrence.jones@eds.com>
+
+ * commit.c (check_fileproc): Remove unused variables.
+
+ * patch.c (patch): Pass local to do_module so that -l actually works.
+ (Reported by John Coers <coers@intrinsity.com>.)
+ (patch_fileproc): Fix uninitialized variables.
+ * sanity.sh: Define a DATE pattern for rdiff and use it.
+ (basic2-24a): New test for above.
+
+2003-03-06 Derek Price <derek@ximbiot.com>
+
+ * subr.c (file_has_conflict): New file.
+ * commit.c (check_fileproc): Factor code into new file_has_conflict()
+ function.
+ * update.c (update_fileproc): Ditto.
+ * status.c (status_fileproc): Use new file_has_conflict() function.
+ (Report from Bernd Kuemmerlen <bkuemmer@mevis.de>.)
+
+ * sanity.sh (status): New test for same.
+
+2003-03-05 Mark D. Baushke <mdb@cvshome.org>
+
+ * rcs.c (RCS_magicrev): Backout CVS_LOCAL_BRANCH_NUM feature.
+
+ * rcs.c (RCS_magicrev): CVS_LOCAL_BRANCH_NUM feature.
+ Port of the FreeBSD hack for setting the next magic branch number
+ to be used. The original patch was written by Peter Wemm
+ <peter@FreeBSD.org> and may be found by visiting the URL:
+ http://www.freebsd.org/cgi/cvsweb.cgi/src/contrib/cvs/src/rcs.c.diff?r1=1.1&r2=1.2
+ Implement a horrible (but simple) hack to allow some control over the
+ branch number that is assigned. This is specifically to support the
+ local commit feature of cvsup. If one sets $CVS_LOCAL_BRANCH_NUM to
+ (say) 1000 then branches the local repository, the revision numbers
+ will look like 1.66.1000.xx. This is almost a dead-set certainty that
+ there will be no conflicts with version numbers.
+ (This needs to be something more than an option to 'cvs tag' or 'cvs
+ 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
+ open() since we abort a few lines earlier if the file doesn't exist.
+ Add a comment to the effect that this is not the optimal method of
+ doing things and needs fixed.
+
+2003-02-28 Derek Price <derek@ximbiot.com>
+
+ * root.c (parse_cvsroot): s/no_passwd/no_password/ in comments.
+
+2003-02-28 Derek Price <derek@ximbiot.com>
+
+ * root.c (parse_cvsroot): Set no_password for :gserver: and :kserver:
+ as tokens should already be obtained via external sources.
+ * update.c (update_fileproc): Remove redundant code.
+
+2003-02-28 Larry Jones <lawrence.jones@eds.com>
+
+ * lock.c (set_lock): If possible, try a short wait with no message
+ before calling lock_wait() to optimize master lock contention.
+
+2003-02-26 Larry Jones <lawrence.jones@eds.com>
+
+ * checkout.c (checkout): Send "--" before file names.
+ * sanity.sh (spacefiles): Remote now works just like local.
+
+2003-02-25 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (rcs4): Use UTC to work across timezones.
+
+2003-02-25 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (RCS_getdate): Fix a bug that shows up when checking out
+ files by date with the "-D date" command line option. There is
+ code in the original to handle a special case. If the date search
+ finds revision 1.1 it is supposed to check whether revision
+ 1.1.1.1 has the same date stamp, which would indicate that the
+ file was originally brought in with "cvs import". In that case it
+ is supposed to return the vendor branch version 1.1.1.1.
+
+ However, there was a bug in the code. It actually compares the date
+ of revision 1.1 for equality with the date given on the command
+ line -- clearly wrong. This commit fixes the coding bug.
+
+ Note: There is an additional bug which is _not_ fixed in this
+ commit. The date comparison should not be a strict equality test.
+ It should allow a fudge factor of, say, 2-3 seconds. Old versions
+ of CVS created the two revisions with two separate invocations of
+ the RCS "ci" command. We have many old files in the tree in which
+ the dates of revisions 1.1 and 1.1.1.1 differ by 1 second.
+
+ 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.
+
+ * sanity.sh (rcs4): Tests for same.
+ (Patch from Mark D. Baushke <mdb@cvshome.org>.)
+
+2003-02-25 Derek Price <derek@ximbiot.com>
+
+ * logmsg.c (logfile_write): Do not pass a NULL pointer to
+ fprintf() when we have an empty log message.
+ * sanity.sh (editor): Add new tests to verify correct behavior of
+ empty log messages.
+ (Patch from Mark D. Baushke <mdb@cvshome.org>, original report from
+ Piotr KUCHARSKI <chopin@sgh.waw.pl>.)
+
+2003-02-25 Derek Price <derek@ximbiot.com>
+
+ * cvsbug.in: Import use of mktemp function from RedHat 8.0's
+ CVS 1.11.2 RPM. Use new MKTEMP configure variable. Use new
+ SENDMAIL from configure.
+
+ * Makefile.in: Regenerated.
+
+2003-02-25 Derek Price <derek@ximbiot.com>
+
+ * watch.c (watch_usage): Use {} rather than () for literals.
+
+2003-02-14 Derek Price <derek@ximbiot.com>
+
+ * watch.c (watch_usage): Make the repeatability of -a part of the
+ usage spec.
+
+2003-02-14 Derek Price <derek@ximbiot.com>
+
+ * watch.c (watch_usage): Mention default for -a. Mention multiple
+ invocations of -a. Mention -R as default. Use required () rather than
+ optional [] around watch subcommand list in invocation spec. Use
+ `path' instead of `file'. Put variable <> around `action' and `path'.
+
+2003-02-07 Derek Price <derek@ximbiot.com>
+
+ * commit.c (checkaddfile): Do not lose the vendor branch when
+ adding files to a new branch. Avoids extranious conflicts for
+ future vendor imports. This was found and fixed in FreeBSD cvs.
+ See http://www.freebsd.org/cgi/query-pr.cgi?pr=4033 for details.
+ * sanity.sh (branch-after-import): New test.
+ (Thanks to Mark D Baushke <mdb@cvshome.org> for forwarding the
+ patch and writing the test cases!)
+
+ * sanity.sh (branch-after-import): Misc portablility and standard
+ changes.
+
+2003-02-12 Derek Price <derek@ximbiot.com>
+
+ * main.c (main): Update copyright message to 2003.
+
+2003-02-21 Larry Jones <lawrence.jones@eds.com>
+
+ * server.c (switch_to_user): Update comment, change error message
+ so it's not an exact duplicate of the one in check_password.
+ (check_repository_password): Add syslog call for password mismatches.
+ (check_password): Add syslog call for password mismatches, rearrange
+ code to simplify and eliminate redundancy.
+ (pserver_authenticate_connection): Remove syslog call, now done by
+ lower-level routines.
+
+2003-02-19 Larry Jones <lawrence.jones@eds.com>
+
+ * sanity.sh (admin-10): Add test for repository files not in
+ working directory.
+
+ * admin.c (admin_fileproc): Fix crash when no rcs file, return
+ failure status for bogus files.
+ * sanity.sh (admin-4a): Test for above.
+ (Original patch submitted by Mark D. Baushke <mdb@cvshome.org>).
+
+2003-02-14 Larry Jones <lawrence.jones@eds.com>
+
+ * log.c (log_expand_revlist): Fix crashes in error cases.
+ (Reported by Bart Santy <Bart.Santy@switch.be>.)
+ * sanity.sh (log): New tests for above.
+
+2003-02-01 Larry Jones <lawrence.jones@eds.com>
+
+ * buffer.c (stdio_buffer_shutdown): Handle EINTR from waitpid.
+ (Patch from Johannes Grødem <johs+n@ifi.uio.no>.)
+
+2003-02-08 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (RCS_checkout): Supply the full function name in the trace
+ output.
+ * update.c (checkout_file, join_file): Supply tag properly to
+ RCS_checkout more often.
+ (patch_file): Ditto. Fill out comments.
+ * sanity.sh (keyword, keywordname): Some changes to accomodate the fact
+ that the above changes cause patches generated by patch_file to fail
+ occassionally.
+
+2003-02-06 Derek Price <derek@ximbiot.com>
+
+ * client.c: Use the complete path to the CVSADM_TEMPLATE file in
+ error messages. Remove related FIXME.
+
+2003-01-31 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (keywordname): Change a "FIXME" comment to "FIXCVS".
+
+2003-01-30 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (keywordname): New test.
+
+2003-01-23 Larry Jones <lawrence.jones@eds.com>
+
+ * diff.c (diff_fileproc): Restructure code to simplify and eliminate
+ redundant tests.
+
+ * server.c (do_cvs_command): Use WCOREDUMP macro rather than hard
+ coding test for core file.
+
+2003-01-21 Larry Jones <lawrence.jones@eds.com>
+
+ * root.c (method_name): Redefine as a 2D array.
+ * root.h (method_name): Ditto.
+
+2003-01-21 Jim Meyering <jim@meyering.net>
+
+ * add.c (add): Rename local-shadowing `i' to `j'.
+
+ * root.c (method_names): Declare to be a const array of const strings.
+ (Name_Root): Save errno so it doesn't get clobbered
+ by the intervening error call.
+ Use getline's return value, mainly to save a call to strrchr.
+
+2003-01-20 Larry Jones <lawrence.jones@eds.com>
+
+ * myndbm.c (O_ACCMODE): Parenthesize the replacement string so that
+ it parses correctly.
+ (Reported by Andres Bertens <abertens@entelchile.net>.)
+
2003-01-15 Karl Fogel <kfogel@collab.net>
* server.c (dirswitch): Don't free dir_name until right before
allocating it again. This removes a potential double-free
problem, whereby this function could free dir_name and then
immediately return due to invalid directory syntax (without ever
- reassigning dir_name), then reenter and free dir_name again.
+ reassigning dir_name), then reenter and free dir_name again.
Thanks to Stefan Esser <s.esser@e-matters.de> for the fix.
diff --git a/contrib/cvs/src/Makefile.am b/contrib/cvs/src/Makefile.am
index 0195f56..c0ab617 100644
--- a/contrib/cvs/src/Makefile.am
+++ b/contrib/cvs/src/Makefile.am
@@ -1,6 +1,8 @@
## Process this file with automake to produce Makefile.in
# Makefile for GNU CVS program.
-# Copyright (C) 1986, 1988-1990, 2000 Free Software Foundation, Inc.
+# Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+# 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# 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
@@ -71,6 +73,7 @@ cvs_SOURCES = \
run.c \
scramble.c \
server.c \
+ stack.c \
status.c \
subr.c \
tag.c \
@@ -88,10 +91,12 @@ cvs_SOURCES = \
fileattr.h \
hardlink.h \
hash.h \
+ history.h \
myndbm.h \
rcs.h \
root.h \
server.h \
+ stack.h \
update.h \
watch.h
@@ -118,11 +123,11 @@ check-local: localcheck remotecheck
.PHONY: localcheck
localcheck:
- $(SHELL) $(srcdir)/sanity.sh `pwd`/cvs
+ $(SHELL) $(srcdir)/sanity.sh `pwd`/cvs$(EXEEXT)
.PHONY: remotecheck
remotecheck: all
- $(SHELL) $(srcdir)/sanity.sh -r `pwd`/cvs
+ $(SHELL) $(srcdir)/sanity.sh -r `pwd`/cvs$(EXEEXT)
## MAINTAINER Targets
diff --git a/contrib/cvs/src/Makefile.in b/contrib/cvs/src/Makefile.in
index 189cd28..c3aa0fc 100644
--- a/contrib/cvs/src/Makefile.in
+++ b/contrib/cvs/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.6.3 from Makefile.am.
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
-# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -15,7 +15,9 @@
@SET_MAKE@
# Makefile for GNU CVS program.
-# Copyright (C) 1986, 1988-1990, 2000 Free Software Foundation, Inc.
+# Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+# 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# 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
@@ -30,76 +32,114 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-bindir = @bindir@
-sbindir = @sbindir@
-libexecdir = @libexecdir@
-datadir = @datadir@
-sysconfdir = @sysconfdir@
-sharedstatedir = @sharedstatedir@
-localstatedir = @localstatedir@
-libdir = @libdir@
-infodir = @infodir@
-mandir = @mandir@
-includedir = @includedir@
-oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
-ACLOCAL = @ACLOCAL@
-AUTOCONF = @AUTOCONF@
-AUTOMAKE = @AUTOMAKE@
-AUTOHEADER = @AUTOHEADER@
-
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
-transform = @program_transform_name@
+transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
-
-EXEEXT = @EXEEXT@
-OBJEXT = @OBJEXT@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-
-SHELL = /bin/sh
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
CSH = @CSH@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
EDITOR = @EDITOR@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KRB4 = @KRB4@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MAKE_TARGETS_IN_VPATH_FALSE = @MAKE_TARGETS_IN_VPATH_FALSE@
+MAKE_TARGETS_IN_VPATH_TRUE = @MAKE_TARGETS_IN_VPATH_TRUE@
+MKTEMP = @MKTEMP@
+OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PR = @PR@
PS2PDF = @PS2PDF@
RANLIB = @RANLIB@
ROFF = @ROFF@
+SENDMAIL = @SENDMAIL@
+SET_MAKE = @SET_MAKE@
+
+SHELL = /bin/sh
STRIP = @STRIP@
TEXI2DVI = @TEXI2DVI@
VERSION = @VERSION@
YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_prefix_program = @ac_prefix_program@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
+am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
includeopt = @includeopt@
+infodir = @infodir@
install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
# $(includeopt) is CVS specific and set by configure
# FIXME - This includes line is dependant on its order. This means there is
@@ -157,6 +197,7 @@ cvs_SOURCES = \
run.c \
scramble.c \
server.c \
+ stack.c \
status.c \
subr.c \
tag.c \
@@ -174,10 +215,12 @@ cvs_SOURCES = \
fileattr.h \
hardlink.h \
hash.h \
+ history.h \
myndbm.h \
rcs.h \
root.h \
server.h \
+ stack.h \
update.h \
watch.h
@@ -203,6 +246,7 @@ EXTRA_DIST = \
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
@@ -223,20 +267,17 @@ am_cvs_OBJECTS = add.$(OBJEXT) admin.$(OBJEXT) annotate.$(OBJEXT) \
patch.$(OBJEXT) rcs.$(OBJEXT) rcscmds.$(OBJEXT) \
recurse.$(OBJEXT) release.$(OBJEXT) remove.$(OBJEXT) \
repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) scramble.$(OBJEXT) \
- server.$(OBJEXT) status.$(OBJEXT) subr.$(OBJEXT) tag.$(OBJEXT) \
- update.$(OBJEXT) version.$(OBJEXT) vers_ts.$(OBJEXT) \
- watch.$(OBJEXT) wrapper.$(OBJEXT) zlib.$(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)
-DEFS = @DEFS@
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/add.Po ./$(DEPDIR)/admin.Po \
@@ -261,28 +302,28 @@ am__depfiles_maybe = depfiles
@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)/status.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/subr.Po ./$(DEPDIR)/tag.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/update.Po ./$(DEPDIR)/vers_ts.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/version.Po ./$(DEPDIR)/watch.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/wrapper.Po ./$(DEPDIR)/zlib.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 $@
-CFLAGS = @CFLAGS@
DIST_SOURCES = $(cvs_SOURCES)
-DIST_COMMON = ChangeLog Makefile.am Makefile.in cvsbug.in
+DIST_COMMON = $(srcdir)/Makefile.in ChangeLog Makefile.am cvsbug.in
SOURCES = $(cvs_SOURCES)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+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
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
@@ -296,7 +337,7 @@ install-binPROGRAMS: $(bin_PROGRAMS)
; 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; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \
else :; fi; \
done
@@ -385,6 +426,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scramble.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag.Po@am__quote@
@@ -395,26 +437,35 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zlib.Po@am__quote@
-distclean-depend:
- -rm -rf ./$(DEPDIR)
-
.c.o:
-@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+@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
+@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)/'`$<
.c.obj:
-@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- $(COMPILE) -c `cygpath -w $<`
-CCDEPMODE = @CCDEPMODE@
+@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
+@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`
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
+CTAGS = ctags
+CTAGSFLAGS =
+
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
@@ -440,20 +491,41 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+ -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)
- @list='$(DISTFILES)'; for file in $$list; do \
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
@@ -480,7 +552,6 @@ all-am: Makefile $(PROGRAMS) $(SCRIPTS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(bindir)
-
install: install-am
install-exec: install-exec-am
install-data: install-data-am
@@ -492,7 +563,7 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- INSTALL_STRIP_FLAG=-s \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@@ -500,7 +571,7 @@ mostlyclean-generic:
clean-generic:
distclean-generic:
- -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f $(CONFIG_CLEAN_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@@ -511,9 +582,10 @@ clean: clean-am
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-am
-
-distclean-am: clean-am distclean-compile distclean-depend \
- distclean-generic distclean-tags
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
dvi: dvi-am
@@ -534,38 +606,47 @@ install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
uninstall-info-am
-.PHONY: GTAGS all all-am check check-am check-local clean \
- clean-binPROGRAMS clean-generic distclean distclean-compile \
- distclean-depend distclean-generic distclean-tags distdir dvi \
+.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 tags uninstall \
- uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS \
- uninstall-info-am
+ 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
.PHONY: localcheck
localcheck:
- $(SHELL) $(srcdir)/sanity.sh `pwd`/cvs
+ $(SHELL) $(srcdir)/sanity.sh `pwd`/cvs$(EXEEXT)
.PHONY: remotecheck
remotecheck: all
- $(SHELL) $(srcdir)/sanity.sh -r `pwd`/cvs
+ $(SHELL) $(srcdir)/sanity.sh -r `pwd`/cvs$(EXEEXT)
# for backwards compatibility with the old makefiles
.PHONY: realclean
diff --git a/contrib/cvs/src/add.c b/contrib/cvs/src/add.c
index 0ff6f69..d71716b 100644
--- a/contrib/cvs/src/add.c
+++ b/contrib/cvs/src/add.c
@@ -24,13 +24,15 @@
* file to be resurrected.
*/
+#include <assert.h>
#include "cvs.h"
#include "savecwd.h"
#include "fileattr.h"
static int add_directory PROTO ((struct file_info *finfo));
-static int build_entry PROTO((char *repository, char *user, char *options,
- char *message, List * entries, char *tag));
+static int build_entry PROTO((const char *repository, const char *user,
+ const char *options, const char *message,
+ List * entries, const char *tag));
static const char *const add_usage[] =
{
@@ -150,7 +152,7 @@ add (argc, argv)
#ifdef CLIENT_SUPPORT
if (current_parsed_root->isremote)
{
- int i;
+ int j;
if (argc == 0)
/* We snipped out all the arguments in the above sanity
@@ -180,7 +182,7 @@ add (argc, argv)
free (repository);
}
- for (i = 0; i < argc; ++i)
+ for (j = 0; j < argc; ++j)
{
/* FIXME: Does this erroneously call Create_Admin in error
conditions which are only detected once the server gets its
@@ -195,7 +197,7 @@ add (argc, argv)
"Directory %s added" message), and then Create_Admin,
which should also fix the error handling concerns. */
- if (isdir (argv[i]))
+ if (isdir (argv[j]))
{
char *tag;
char *date;
@@ -210,8 +212,11 @@ add (argc, argv)
if (save_cwd (&cwd))
error_exit ();
- filedir = xstrdup (argv[i]);
- p = last_component (filedir);
+ filedir = xstrdup (argv[j]);
+ /* Deliberately discard the const below since we know we just
+ * allocated filedir and can do what we like with it.
+ */
+ p = (char *)last_component (filedir);
if (p == filedir)
{
update_dir = "";
@@ -246,7 +251,7 @@ add (argc, argv)
rcsdir = xmalloc (strlen (repository) + strlen (p) + 5);
sprintf (rcsdir, "%s/%s", repository, p);
- Create_Admin (p, argv[i], rcsdir, tag, date,
+ Create_Admin (p, argv[j], rcsdir, tag, date,
nonbranch, 0, 1);
if (found_slash)
@@ -263,7 +268,7 @@ add (argc, argv)
free (rcsdir);
if (p == filedir)
- Subdir_Register ((List *) NULL, (char *) NULL, argv[i]);
+ Subdir_Register ((List *) NULL, (char *) NULL, argv[j]);
else
{
Subdir_Register ((List *) NULL, update_dir, p);
@@ -289,10 +294,7 @@ add (argc, argv)
int begin_added_files = added_files;
#endif
struct file_info finfo;
- char *p;
-#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE)
- char *found_name;
-#endif
+ char *filename, *p;
memset (&finfo, 0, sizeof finfo);
@@ -300,8 +302,12 @@ add (argc, argv)
error_exit ();
finfo.fullname = xstrdup (argv[i]);
- p = last_component (argv[i]);
- if (p == argv[i])
+ filename = xstrdup (argv[i]);
+ /* We know we can discard the const below since we just allocated
+ * filename and can do as we like with it.
+ */
+ p = (char *)last_component (filename);
+ if (p == filename)
{
finfo.update_dir = "";
finfo.file = p;
@@ -309,7 +315,7 @@ add (argc, argv)
else
{
p[-1] = '\0';
- finfo.update_dir = argv[i];
+ finfo.update_dir = filename;
finfo.file = p;
if (CVS_CHDIR (finfo.update_dir) < 0)
error (1, errno, "could not chdir to %s", finfo.update_dir);
@@ -325,7 +331,8 @@ add (argc, argv)
repository = Name_Repository (NULL, finfo.update_dir);
/* don't add stuff to Emptydir */
- if (strncmp (repository, current_parsed_root->directory, cvsroot_len) == 0
+ if (strncmp (repository, current_parsed_root->directory,
+ cvsroot_len) == 0
&& ISDIRSEP (repository[cvsroot_len])
&& strncmp (repository + cvsroot_len + 1,
CVSROOTADM,
@@ -340,65 +347,12 @@ add (argc, argv)
finfo.repository = repository;
finfo.entries = entries;
-#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE)
- if (ign_case)
- {
- /* Need to check whether there is a directory with the
- same name but different case. We'll check for files
- with the same name later (when Version_TS calls
- RCS_parse which calls fopen_case). If CVS some day
- records directories in the RCS files, then we should be
- able to skip the separate check here, which would be
- cleaner. */
- DIR *dirp;
- struct dirent *dp;
-
- dirp = CVS_OPENDIR (finfo.repository);
- if (dirp == NULL)
- error (1, errno, "cannot read directory %s", finfo.repository);
- found_name = NULL;
- errno = 0;
- while ((dp = CVS_READDIR (dirp)) != NULL)
- {
- if (cvs_casecmp (dp->d_name, finfo.file) == 0)
- {
- if (found_name != NULL)
- error (1, 0, "%s is ambiguous; could mean %s or %s",
- finfo.file, dp->d_name, found_name);
- found_name = xstrdup (dp->d_name);
- }
- }
- if (errno != 0)
- error (1, errno, "cannot read directory %s", finfo.repository);
- CVS_CLOSEDIR (dirp);
-
- if (found_name != NULL)
- {
- /* OK, we are about to patch up the name, so patch up
- the temporary directory too to match. The isdir
- should "always" be true (since files have ,v), but
- I guess we might as well make some attempt to not
- get confused by stray files in the repository. */
- if (isdir (finfo.file))
- {
- if (CVS_MKDIR (found_name, 0777) < 0
- && errno != EEXIST)
- error (0, errno, "cannot create %s", finfo.file);
- }
-
- /* OK, we found a directory with the same name, maybe in
- a different case. Treat it as if the name were the
- same. */
- finfo.file = found_name;
- }
- }
-#endif
-
/* We pass force_tag_match as 1. If the directory has a
sticky branch tag, and there is already an RCS file which
does not have that tag, then the head revision is
meaningless to us. */
vers = Version_TS (&finfo, options, NULL, NULL, 1, 0);
+
if (vers->vn_user == NULL)
{
/* No entry available, ts_rcs is invalid */
@@ -507,24 +461,90 @@ same name already exists in the repository.");
}
else
{
+ char *timestamp = NULL;
+ if (vers->ts_user == NULL)
+ {
+ /* If this file does not exist locally, assume that
+ * the last version on the branch is being
+ * resurrected.
+ *
+ * Compute previous revision. We assume that it
+ * exists and that it is not a revision on the
+ * trunk of the form X.1 (1.1, 2.1, 3.1, ...). We
+ * also assume that it is not dead, which seems
+ * fair since we know vers->vn_rcs is dead
+ * and we shouldn't see two dead revisions in a
+ * row.
+ */
+ char *prev = previous_rev (vers->srcfile,
+ vers->vn_rcs);
+ int status;
+ assert (prev != NULL);
+ if (!quiet)
+ error (0, 0,
+"Resurrecting file `%s' from revision %s.",
+ finfo.fullname, prev);
+ status = RCS_checkout (vers->srcfile, finfo.file,
+ prev, vers->tag,
+ vers->options, RUN_TTY,
+ NULL, NULL);
+ xchmod (finfo.file, 1);
+ if (status != 0)
+ {
+ error (0, 0, "Failed to resurrect revision %s",
+ prev);
+ err++;
+ }
+ else
+ {
+ /* I don't actually set vers->ts_user here
+ * because it would confuse server_update().
+ */
+ timestamp = time_stamp (finfo.file);
+ if (!really_quiet)
+ write_letter (&finfo, 'U');
+ }
+ free (prev);
+ }
if (!quiet)
{
if (vers->tag)
- error (0, 0, "\
-file `%s' will be added on branch `%s' from version %s",
- finfo.fullname, vers->tag, vers->vn_rcs);
+ error (0, 0,
+"file `%s' will be added on branch `%s' from version %s",
+ finfo.fullname, vers->tag,
+ vers->vn_rcs);
else
/* I'm not sure that mentioning
vers->vn_rcs makes any sense here; I
can't think of a way to word the
message which is not confusing. */
- error (0, 0, "\
-re-adding file %s (in place of dead revision %s)",
- finfo.fullname, vers->vn_rcs);
+ error (0, 0,
+"Re-adding file `%s' (in place of dead revision %s).",
+ finfo.fullname, vers->vn_rcs);
+ }
+ Register (entries, finfo.file, "0",
+ timestamp ? timestamp : vers->ts_user,
+ vers->options, vers->tag, vers->date, NULL);
+ if (timestamp) free (timestamp);
+#ifdef SERVER_SUPPORT
+ if (server_active && vers->ts_user == NULL)
+ {
+ /* If we resurrected the file from the archive, we
+ * need to tell the client about it.
+ */
+ server_updated (&finfo, vers,
+ SERVER_UPDATED,
+ (mode_t) -1, NULL, NULL);
+ /* This is kinda hacky or, at least, it renders the
+ * name "begin_added_files" obsolete, but we want
+ * the added_files to be counted without triggering
+ * the check that causes server_checked_in() to be
+ * called below since we have already called
+ * server_updated() to complete the resurrection.
+ */
+ ++begin_added_files;
}
- Register (entries, finfo.file, "0", vers->ts_user,
- vers->options,
- vers->tag, NULL, NULL);
+#endif
++added_files;
}
}
@@ -570,36 +590,56 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname);
}
else
{
-
+ int status;
/*
* There is an RCS file, so remove the "-" from the
* version number and restore the file
*/
- char *tmp = xmalloc (strlen (finfo.file) + 50);
-
+ char *tmp = xmalloc (strlen (vers->vn_user));
(void) strcpy (tmp, vers->vn_user + 1);
(void) strcpy (vers->vn_user, tmp);
- (void) sprintf (tmp, "Resurrected %s", finfo.file);
- Register (entries, finfo.file, vers->vn_user, tmp,
- vers->options,
- vers->tag, vers->date, vers->ts_conflict);
- free (tmp);
-
- /* XXX - bugs here; this really resurrect the head */
- /* Note that this depends on the Register above actually
- having written Entries, or else it won't really
- check the file out. */
- if (update (2, argv + i - 1) == 0)
+ free(tmp);
+ status = RCS_checkout (vers->srcfile, finfo.file,
+ vers->vn_user, vers->tag,
+ vers->options, RUN_TTY,
+ NULL, NULL);
+ xchmod (finfo.file, 1);
+ if (status != 0)
{
- error (0, 0, "%s, version %s, resurrected",
- finfo.fullname,
+ error (0, 0, "Failed to resurrect revision %s",
vers->vn_user);
+ err++;
+ tmp = NULL;
}
else
{
- error (0, 0, "could not resurrect %s", finfo.fullname);
- err++;
+ /* I don't actually set vers->ts_user here because it
+ * would confuse server_update().
+ */
+ tmp = time_stamp (finfo.file);
+ write_letter (&finfo, 'U');
+ if (!quiet)
+ error (0, 0, "%s, version %s, resurrected",
+ finfo.fullname, vers->vn_user);
+ }
+ Register (entries, finfo.file, vers->vn_user,
+ tmp, vers->options,
+ vers->tag, vers->date, NULL);
+ if (tmp) free (tmp);
+#ifdef SERVER_SUPPORT
+ if (server_active)
+ {
+ /* If we resurrected the file from the archive, we
+ * need to tell the client about it.
+ */
+ server_updated (&finfo, vers,
+ SERVER_UPDATED,
+ (mode_t) -1, NULL, NULL);
}
+ /* We don't increment added_files here because this isn't
+ * a change that needs to be committed.
+ */
+#endif
}
}
else
@@ -642,11 +682,11 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname);
error_exit ();
free_cwd (&cwd);
- free (finfo.fullname);
-#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE)
- if (ign_case && found_name != NULL)
- free (found_name);
-#endif
+ /* It's okay to discard the const to free this - we allocated this
+ * above. The const is for everybody else.
+ */
+ free ((char *) finfo.fullname);
+ free ((char *) filename);
}
if (added_files && !really_quiet)
error (0, 0, "use '%s commit' to add %s permanently",
@@ -672,9 +712,9 @@ static int
add_directory (finfo)
struct file_info *finfo;
{
- char *repository = finfo->repository;
+ const char *repository = finfo->repository;
List *entries = finfo->entries;
- char *dir = finfo->file;
+ const char *dir = finfo->file;
char *rcsdir = NULL;
struct saved_cwd cwd;
@@ -707,11 +747,11 @@ add_directory (finfo)
/* now, remember where we were, so we can get back */
if (save_cwd (&cwd))
- return (1);
- if ( CVS_CHDIR (dir) < 0)
+ return 1;
+ if (CVS_CHDIR (dir) < 0)
{
error (0, errno, "cannot chdir to %s", finfo->fullname);
- return (1);
+ return 1;
}
#ifdef SERVER_SUPPORT
if (!server_active && isfile (CVSADM))
@@ -737,7 +777,8 @@ add_directory (finfo)
+ 80
+ (tag == NULL ? 0 : strlen (tag) + 80)
+ (date == NULL ? 0 : strlen (date) + 80));
- (void) sprintf (message, "Directory %s added to the repository\n", rcsdir);
+ (void) sprintf (message, "Directory %s added to the repository\n",
+ rcsdir);
if (tag)
{
(void) strcat (message, "--> Using per-directory sticky tag `");
@@ -799,7 +840,7 @@ add_directory (finfo)
li->type = T_TITLE;
li->tag = xstrdup (tag);
li->rev_old = li->rev_new = NULL;
- p->data = (char *) li;
+ p->data = li;
(void) addnode (ulist, p);
Update_Logfile (rcsdir, message, (FILE *) NULL, ulist);
dellist (&ulist);
@@ -820,12 +861,13 @@ add_directory (finfo)
Subdir_Register (entries, (char *) NULL, dir);
- cvs_output (message, 0);
+ if (!really_quiet)
+ cvs_output (message, 0);
free (rcsdir);
free (message);
- return (0);
+ return 0;
out:
if (restore_cwd (&cwd, NULL))
@@ -836,18 +878,20 @@ out:
return (0);
}
+
+
/*
* Builds an entry for a new file and sets up "CVS/file",[pt] by
* interrogating the user. Returns non-zero on error.
*/
static int
build_entry (repository, user, options, message, entries, tag)
- char *repository;
- char *user;
- char *options;
- char *message;
+ const char *repository;
+ const char *user;
+ const char *options;
+ const char *message;
List *entries;
- char *tag;
+ const char *tag;
{
char *fname;
char *line;
diff --git a/contrib/cvs/src/admin.c b/contrib/cvs/src/admin.c
index 6a5649a..05067b8 100644
--- a/contrib/cvs/src/admin.c
+++ b/contrib/cvs/src/admin.c
@@ -15,9 +15,9 @@
#endif
#include <assert.h>
-static Dtype admin_dirproc PROTO ((void *callerdat, char *dir,
- char *repos, char *update_dir,
- List *entries));
+static Dtype admin_dirproc PROTO ((void *callerdat, const char *dir,
+ const char *repos, const char *update_dir,
+ List *entries));
static int admin_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static const char *const admin_usage[] =
@@ -367,7 +367,7 @@ admin (argc, argv)
/* getopt will have printed an error message. */
usage_error:
- /* Don't use command_name; it might be "server". */
+ /* Don't use cvs_cmd_name; it might be "server". */
error (1, 0, "specify %s -H admin for usage information",
program_name);
}
@@ -520,7 +520,8 @@ admin (argc, argv)
err = start_recursion (admin_fileproc, (FILESDONEPROC) NULL, admin_dirproc,
(DIRLEAVEPROC) NULL, (void *)&admin_data,
argc, argv, 0,
- W_LOCAL, 0, CVS_LOCK_NONE, (char *) NULL, 1);
+ W_LOCAL, 0, CVS_LOCK_NONE, (char *) NULL, 1,
+ (char *) NULL);
Lock_Cleanup ();
return_it:
@@ -564,15 +565,22 @@ admin_fileproc (callerdat, finfo)
if (version != NULL && strcmp (version, "0") == 0)
{
error (0, 0, "cannot admin newly added file `%s'", finfo->file);
+ status = 1;
goto exitfunc;
}
rcs = vers->srcfile;
+ if (rcs == NULL)
+ {
+ if (!really_quiet)
+ error (0, 0, "nothing known about %s", finfo->file);
+ status = 1;
+ goto exitfunc;
+ }
+
if (rcs->flags & PARTIAL)
RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL);
- status = 0;
-
if (!really_quiet)
{
cvs_output ("RCS file: ", 0);
@@ -776,7 +784,7 @@ admin_fileproc (callerdat, finfo)
error (0, 0,
"%s: symbolic name %s already bound to %s",
rcs->path,
- tag, n->data);
+ tag, (char *)n->data);
status = 1;
free (tag);
continue;
@@ -835,7 +843,7 @@ admin_fileproc (callerdat, finfo)
continue;
}
free (rev);
- delta = (RCSVers *) n->data;
+ delta = n->data;
free (delta->state);
delta->state = tag;
break;
@@ -849,20 +857,32 @@ admin_fileproc (callerdat, finfo)
status = 1;
continue;
}
- *p = '\0';
- rev = RCS_gettag (rcs, arg + 2, 0, NULL);
+ *p = '\0'; /* temporarily make arg+2 its own string */
+ rev = RCS_gettag (rcs, arg + 2, 1, NULL); /* Force tag match */
if (rev == NULL)
{
- error (0, 0, "%s: no such revision %s", rcs->path, rev);
+ error (0, 0, "%s: no such revision %s", rcs->path, arg+2);
status = 1;
+ *p = ':'; /* restore the full text of the -m argument */
continue;
}
- *p++ = ':';
- msg = p;
+ msg = p+1;
n = findnode (rcs->versions, rev);
+ /* tags may exist against non-existing versions */
+ if (n == NULL)
+ {
+ error (0, 0, "%s: no such revision %s: %s",
+ rcs->path, arg+2, rev);
+ status = 1;
+ *p = ':'; /* restore the full text of the -m argument */
+ free (rev);
+ continue;
+ }
+ *p = ':'; /* restore the full text of the -m argument */
free (rev);
- delta = (RCSVers *) n->data;
+
+ delta = n->data;
if (delta->text == NULL)
{
delta->text = (Deltatext *) xmalloc (sizeof (Deltatext));
@@ -911,9 +931,9 @@ admin_fileproc (callerdat, finfo)
static Dtype
admin_dirproc (callerdat, dir, repos, update_dir, entries)
void *callerdat;
- char *dir;
- char *repos;
- char *update_dir;
+ const char *dir;
+ const char *repos;
+ const char *update_dir;
List *entries;
{
if (!quiet)
diff --git a/contrib/cvs/src/annotate.c b/contrib/cvs/src/annotate.c
index 2e3cb89..8bf330f 100644
--- a/contrib/cvs/src/annotate.c
+++ b/contrib/cvs/src/annotate.c
@@ -54,7 +54,7 @@ annotate (argc, argv)
int err = 0;
int c;
- is_rannotate = (strcmp(command_name, "rannotate") == 0);
+ is_rannotate = (strcmp(cvs_cmd_name, "rannotate") == 0);
if (argc == -1)
usage (annotate_usage);
@@ -224,14 +224,12 @@ rannotate_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg)
free (repository);
return (1);
}
- free (repository);
/* End section which is identical to patch_proc. */
if (force_tag_match && tag != NULL)
which = W_REPOS | W_ATTIC;
else
which = W_REPOS;
- repository = NULL;
}
else
{
@@ -249,7 +247,11 @@ rannotate_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg)
err = start_recursion (annotate_fileproc, (FILESDONEPROC) NULL,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
argc - 1, argv + 1, local, which, 0, CVS_LOCK_READ,
- where, 1);
+ where, 1, repository);
+ if ( which & W_REPOS )
+ free ( repository );
+ if ( where != NULL )
+ free (where);
return err;
}
diff --git a/contrib/cvs/src/buffer.c b/contrib/cvs/src/buffer.c
index fd98d82..fb98e11 100644
--- a/contrib/cvs/src/buffer.c
+++ b/contrib/cvs/src/buffer.c
@@ -60,6 +60,11 @@ void
buf_free (buf)
struct buffer *buf;
{
+ if (buf->closure != NULL)
+ {
+ free (buf->closure);
+ buf->closure = NULL;
+ }
if (buf->data != NULL)
{
buf->last->next = free_buffer_data;
@@ -137,8 +142,23 @@ get_buffer_data ()
return ret;
}
-/* See whether a buffer is empty. */
+
+/* See whether a buffer and its file descriptor is empty. */
+int
+buf_empty (buf)
+ struct buffer *buf;
+{
+ /* Try and read any data on the file descriptor first.
+ * We already know the descriptor is non-blocking.
+ */
+ buf_input_data (buf, NULL);
+ return buf_empty_p (buf);
+}
+
+
+
+/* See whether a buffer is empty. */
int
buf_empty_p (buf)
struct buffer *buf;
@@ -151,6 +171,8 @@ buf_empty_p (buf)
return 1;
}
+
+
#ifdef SERVER_FLOWCONTROL
/*
* Count how much data is stored in the buffer..
@@ -1208,6 +1230,8 @@ buf_shutdown (buf)
return 0;
}
+
+
/* The simplest type of buffer is one built on top of a stdio FILE.
For simplicity, and because it is all that is required, we do not
implement setting this type of buffer into nonblocking mode. The
@@ -1218,14 +1242,17 @@ static int stdio_buffer_output PROTO((void *, const char *, int, int *));
static int stdio_buffer_flush PROTO((void *));
static int stdio_buffer_shutdown PROTO((struct buffer *buf));
-/* Initialize a buffer built on a stdio FILE. */
+
+/* Initialize a buffer built on a stdio FILE. */
struct stdio_buffer_closure
{
FILE *fp;
int child_pid;
};
+
+
struct buffer *
stdio_buffer_initialize (fp, child_pid, input, memory)
FILE *fp;
@@ -1351,8 +1378,9 @@ stdio_buffer_output (closure, data, have, wrote)
return 0;
}
-/* The buffer flush function for a buffer built on a stdio FILE. */
+
+/* The buffer flush function for a buffer built on a stdio FILE. */
static int
stdio_buffer_flush (closure)
void *closure;
@@ -1376,12 +1404,12 @@ static int
stdio_buffer_shutdown (buf)
struct buffer *buf;
{
- struct stdio_buffer_closure *bc = (struct stdio_buffer_closure *) buf->closure;
+ struct stdio_buffer_closure *bc = buf->closure;
struct stat s;
int closefp = 1;
/* Must be a pipe or a socket. What could go wrong? */
- assert (fstat ( fileno (bc->fp), &s ) != -1);
+ assert (fstat (fileno (bc->fp), &s) != -1);
/* Flush the buffer if we can */
if (buf->flush)
@@ -1392,30 +1420,11 @@ stdio_buffer_shutdown (buf)
if (buf->input)
{
- if ( !buf_empty_p (buf) )
- {
-# ifdef SERVER_SUPPORT
- if (server_active)
- /* FIXME: This should probably be sysloged since it doesn't
- * have anywhere else to go at this point.
- */
- error (0, 0, "dying gasps from client unexpected");
- else
-#endif
- error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname);
- }
- else if (ferror (bc->fp))
- {
-# ifdef SERVER_SUPPORT
- if (server_active)
- /* FIXME: This should probably be sysloged since it doesn't
- * have anywhere else to go at this point.
- */
- error (0, errno, "reading from client");
- else
-#endif
- error (0, errno, "reading from %s", current_parsed_root->hostname);
- }
+ /* There used to be a check here for unread data in the buffer of on
+ * the pipe, but it was deemed unnecessary and possibly dangerous. In
+ * some sense it could be second-guessing the caller who requested it
+ * closed, as well.
+ */
# ifdef SHUTDOWN_SERVER
if (current_parsed_root->method != server_method)
@@ -1423,8 +1432,8 @@ stdio_buffer_shutdown (buf)
# ifndef NO_SOCKET_TO_FD
{
/* shutdown() sockets */
- if (S_ISSOCK(s.st_mode))
- shutdown ( fileno (bc->fp), 0);
+ if (S_ISSOCK (s.st_mode))
+ shutdown (fileno (bc->fp), 0);
}
# endif /* NO_SOCKET_TO_FD */
# ifdef START_RSH_WITH_POPEN_RW
@@ -1446,13 +1455,13 @@ stdio_buffer_shutdown (buf)
* SHUTDOWN_SERVER_OUTPUT
*/
if (current_parsed_root->method == server_method)
- SHUTDOWN_SERVER ( fileno (bc->fp) );
+ SHUTDOWN_SERVER (fileno (bc->fp));
else
# endif
# ifndef NO_SOCKET_TO_FD
/* shutdown() sockets */
- if (S_ISSOCK(s.st_mode))
- shutdown ( fileno (bc->fp), 1);
+ if (S_ISSOCK (s.st_mode))
+ shutdown (fileno (bc->fp), 1);
# else
{
/* I'm not sure I like this empty block, but the alternative
@@ -1465,15 +1474,34 @@ stdio_buffer_shutdown (buf)
}
if (closefp && fclose (bc->fp) == EOF)
- error (1, errno,
- "closing down connection to %s",
- current_parsed_root->hostname);
+ {
+ if (0
+# ifdef SERVER_SUPPORT
+ || server_active
+# endif /* SERVER_SUPPORT */
+ )
+ {
+ /* Syslog this? */
+ }
+# ifdef CLIENT_SUPPORT
+ else
+ error (1, errno,
+ "closing down connection to %s",
+ current_parsed_root->hostname);
+# endif /* CLIENT_SUPPORT */
+ }
/* If we were talking to a process, make sure it exited */
- if (bc->child_pid
- && waitpid (bc->child_pid, (int *) 0, 0) == -1)
- error (1, errno, "waiting for process %d", bc->child_pid);
+ if (bc->child_pid)
+ {
+ int w;
+ do
+ w = waitpid (bc->child_pid, (int *) 0, 0);
+ while (w == -1 && errno == EINTR);
+ if (w == -1)
+ error (1, errno, "waiting for process %d", bc->child_pid);
+ }
return 0;
}
@@ -1872,8 +1900,9 @@ packetizing_buffer_output (closure, data, have, wrote)
return buf_send_output (pb->buf);
}
-/* Flush data to a packetizing buffer. */
+
+/* Flush data to a packetizing buffer. */
static int
packetizing_buffer_flush (closure)
void *closure;
@@ -1887,8 +1916,9 @@ packetizing_buffer_flush (closure)
return buf_flush (pb->buf, 0);
}
-/* The block routine for a packetizing buffer. */
+
+/* The block routine for a packetizing buffer. */
static int
packetizing_buffer_block (closure, block)
void *closure;
diff --git a/contrib/cvs/src/buffer.h b/contrib/cvs/src/buffer.h
index d76f43a..11d9aeb 100644
--- a/contrib/cvs/src/buffer.h
+++ b/contrib/cvs/src/buffer.h
@@ -119,6 +119,7 @@ extern struct buffer *packetizing_buffer_initialize
PROTO((struct buffer *, int (*) (void *, const char *, char *, int),
int (*) (void *, const char *, char *, int, int *), void *,
void (*) (struct buffer *)));
+extern int buf_empty PROTO((struct buffer *));
extern int buf_empty_p PROTO((struct buffer *));
extern void buf_output PROTO((struct buffer *, const char *, int));
extern void buf_output0 PROTO((struct buffer *, const char *));
diff --git a/contrib/cvs/src/checkin.c b/contrib/cvs/src/checkin.c
index 70fb74c..938b717 100644
--- a/contrib/cvs/src/checkin.c
+++ b/contrib/cvs/src/checkin.c
@@ -15,15 +15,15 @@
* Returns non-zero on error.
*/
+#include <assert.h>
#include "cvs.h"
#include "fileattr.h"
#include "edit.h"
int
-Checkin (type, finfo, rcs, rev, tag, options, message)
+Checkin (type, finfo, rev, tag, options, message)
int type;
struct file_info *finfo;
- char *rcs;
char *rev;
char *tag;
char *options;
@@ -53,10 +53,15 @@ Checkin (type, finfo, rcs, rev, tag, options, message)
}
}
- if (finfo->rcs == NULL)
- finfo->rcs = RCS_parse (finfo->file, finfo->repository);
+ /* There use to be a check for finfo->rcs == NULL here and then a
+ * call to RCS_parse when necessary, but Checkin() isn't called
+ * if the RCS file hasn't already been parsed in one of the
+ * check functions.
+ */
+ assert (finfo->rcs != NULL);
- switch (RCS_checkin (finfo->rcs, NULL, message, rev, RCS_FLAGS_KEEPFILE))
+ switch (RCS_checkin (finfo->rcs, finfo->file, message, rev,
+ RCS_FLAGS_KEEPFILE))
{
case 0: /* everything normal */
@@ -78,11 +83,12 @@ Checkin (type, finfo, rcs, rev, tag, options, message)
call RCS_checkout here, compare the resulting files
using xcmp, and rename if necessary. I think this
should be fixed in RCS_cmp_file. */
- if ((! preserve_perms
- && options != NULL
- && (strcmp (options, "-ko") == 0
- || strcmp (options, "-kb") == 0))
- || RCS_cmp_file (finfo->rcs, rev, options, finfo->file) == 0)
+ if( ( ! preserve_perms
+ && options != NULL
+ && ( strcmp( options, "-ko" ) == 0
+ || strcmp( options, "-kb" ) == 0 ) )
+ || RCS_cmp_file( finfo->rcs, rev, (char **)NULL, (char *)NULL,
+ options, finfo->file ) == 0 )
{
/* The existing file is correct. We don't have to do
anything. */
@@ -176,5 +182,5 @@ Checkin (type, finfo, rcs, rev, tag, options, message)
mark_up_to_date (finfo->file);
freevers_ts (&vers);
- return (0);
+ return 0;
}
diff --git a/contrib/cvs/src/checkout.c b/contrib/cvs/src/checkout.c
index fe30695..ee3bcb2 100644
--- a/contrib/cvs/src/checkout.c
+++ b/contrib/cvs/src/checkout.c
@@ -130,7 +130,7 @@ checkout (argc, argv)
* options to be default (like -kv) and takes care to remove the CVS
* directory when it has done its duty
*/
- if (strcmp (command_name, "export") == 0)
+ if (strcmp (cvs_cmd_name, "export") == 0)
{
m_type = EXPORT;
valid_options = "+Nnk:d:flRQqr:D:";
@@ -177,7 +177,7 @@ checkout (argc, argv)
#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
- command_name);
+ cvs_cmd_name);
break;
case 'l':
local = 1;
@@ -273,14 +273,6 @@ checkout (argc, argv)
ign_setup ();
- /* We have to expand names here because the "expand-modules"
- directive to the server has the side-effect of having the
- server send the check-in and update programs for the
- various modules/dirs requested. If we turn this off and
- simply request the names of the modules and directories (as
- below in !expand_modules), those files (CVS/Checkin.prog
- or CVS/Update.prog) don't get created. Grrr. */
-
expand_modules = (!cat && !pipeout
&& supported_request ("expand-modules"));
@@ -323,6 +315,7 @@ checkout (argc, argv)
option_with_arg ("-j", join_rev1);
if (join_rev2 != NULL)
option_with_arg ("-j", join_rev2);
+ send_arg ("--");
if (expand_modules)
{
@@ -398,39 +391,55 @@ checkout (argc, argv)
/* FIXME: This is and emptydir_name are in checkout.c for historical
reasons, probably want to move them. */
+/* int
+ * safe_location ( char *where )
+ *
+ * Return true if where is a safe destination for a checkout.
+ *
+ * INPUTS
+ * where The requested destination directory.
+ *
+ * GLOBALS
+ * current_parsed_root->directory
+ * current_parsed_root->isremote
+ * Used to locate our CVSROOT.
+ *
+ * RETURNS
+ * true If we are running in client mode or if where is not located
+ * within the CVSROOT.
+ * false Otherwise.
+ *
+ * ERRORS
+ * Exits with a fatal error message when various events occur, such as not
+ * being able to resolve a path or failing ot chdir to a path.
+ */
int
safe_location (where)
char *where;
{
char *current;
char *where_location;
- char hardpath[PATH_MAX+5];
+ char *hardpath;
size_t hardpath_len;
- int x;
int retval;
-#ifdef HAVE_READLINK
- /* FIXME-arbitrary limit: should be retrying this like xgetwd.
- But how does readlink let us know that the buffer was too small?
- (by returning sizeof hardpath - 1?). */
- x = readlink(current_parsed_root->directory, hardpath, sizeof hardpath - 1);
-#else
- x = -1;
-#endif
- if (x == -1)
- {
- strcpy(hardpath, current_parsed_root->directory);
- }
- else
- {
- hardpath[x] = '\0';
- }
+ if (trace)
+ (void) fprintf (stderr, "%s-> safe_location( where=%s )\n",
+ 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 */
/* set current - even if where is set we'll need to cd back... */
current = xgetwd ();
if (current == NULL)
error (1, errno, "could not get working directory");
+ hardpath = xresolvepath ( current_parsed_root->directory );
+
/* if where is set, set current to where, where - last_component( where ),
* or fail, depending on whether the directories exist or not.
*/
@@ -457,12 +466,16 @@ safe_location (where)
char *parent;
/* strip the last_component */
- where_location = xstrdup( where );
- parent = last_component( where_location );
+ where_location = xstrdup (where);
+ /* It's okay to cast out the const below since we know we just
+ * allocated where_location and can do what we like with it.
+ */
+ parent = (char *)last_component (where_location);
parent[-1] = '\0';
if( chdir( where_location ) != -1 )
{
+ free( where_location );
where_location = xgetwd();
if( where_location == NULL )
error( 1, errno, "could not get working directory (nominally `%s')", where_location );
@@ -505,6 +518,7 @@ safe_location (where)
else
retval = 1;
free (current);
+ free (hardpath);
return retval;
}
@@ -918,52 +932,48 @@ internal error: %s doesn't start with %s in checkout_proc",
/* clean up */
free (reposcopy);
+ /* The top-level CVSADM directory should always be
+ current_parsed_root->directory. Create it, but only if WHERE is
+ relative. If WHERE is absolute, our current directory
+ may not have a thing to do with where the sources are
+ being checked out. If it does, build_dirs_and_chdir
+ will take care of creating adm files here. */
+ /* FIXME: checking is_absolute (where) is a horrid kludge;
+ I suspect we probably can just skip the call to
+ build_one_dir whenever the -d command option was specified
+ to checkout. */
+
+ if (!isabsolute (where) && top_level_admin && m_type == CHECKOUT)
{
- int where_is_absolute = isabsolute (where);
-
- /* The top-level CVSADM directory should always be
- current_parsed_root->directory. Create it, but only if WHERE is
- relative. If WHERE is absolute, our current directory
- may not have a thing to do with where the sources are
- being checked out. If it does, build_dirs_and_chdir
- will take care of creating adm files here. */
- /* FIXME: checking where_is_absolute is a horrid kludge;
- I suspect we probably can just skip the call to
- build_one_dir whenever the -d command option was specified
- to checkout. */
-
- if (! where_is_absolute && top_level_admin && m_type == CHECKOUT)
- {
- /* It may be argued that we shouldn't set any sticky
- bits for the top-level repository. FIXME? */
- build_one_dir (current_parsed_root->directory, ".", argc <= 1);
+ /* It may be argued that we shouldn't set any sticky
+ bits for the top-level repository. FIXME? */
+ build_one_dir (current_parsed_root->directory, ".", argc <= 1);
#ifdef SERVER_SUPPORT
- /* We _always_ want to have a top-level admin
- directory. If we're running in client/server mode,
- send a "Clear-static-directory" command to make
- sure it is created on the client side. (See 5.10
- in cvsclient.dvi to convince yourself that this is
- OK.) If this is a duplicate command being sent, it
- will be ignored on the client side. */
+ /* We _always_ want to have a top-level admin
+ directory. If we're running in client/server mode,
+ send a "Clear-static-directory" command to make
+ sure it is created on the client side. (See 5.10
+ in cvsclient.dvi to convince yourself that this is
+ OK.) If this is a duplicate command being sent, it
+ will be ignored on the client side. */
- if (server_active)
- server_clear_entstat (".", current_parsed_root->directory);
+ if (server_active)
+ server_clear_entstat (".", current_parsed_root->directory);
#endif
- }
+ }
- /* Build dirs on the path if necessary and leave us in the
- bottom directory (where if where was specified) doesn't
- contain a CVS subdir yet, but all the others contain
- CVS and Entries.Static files */
+ /* Build dirs on the path if necessary and leave us in the
+ bottom directory (where if where was specified) doesn't
+ contain a CVS subdir yet, but all the others contain
+ CVS and Entries.Static files */
- if (build_dirs_and_chdir (head, argc <= 1) != 0)
- {
- error (0, 0, "ignoring module %s", omodule);
- err = 1;
- goto out;
- }
+ if (build_dirs_and_chdir (head, argc <= 1) != 0)
+ {
+ error (0, 0, "ignoring module %s", omodule);
+ err = 1;
+ goto out;
}
/* set up the repository (or make sure the old one matches) */
@@ -1086,7 +1096,8 @@ internal error: %s doesn't start with %s in checkout_proc",
force_tag_match, 0 /* !local */ ,
1 /* update -d */ , aflag, checkout_prune_dirs,
pipeout, which, join_rev1, join_rev2,
- preload_update_dir, m_type == CHECKOUT);
+ preload_update_dir, m_type == CHECKOUT,
+ repository);
goto out;
}
@@ -1142,7 +1153,8 @@ internal error: %s doesn't start with %s in checkout_proc",
err += do_update (argc - 1, argv + 1, options, tag, date,
force_tag_match, local_specified, 1 /* update -d */,
aflag, checkout_prune_dirs, pipeout, which, join_rev1,
- join_rev2, preload_update_dir, m_type == CHECKOUT);
+ join_rev2, preload_update_dir, m_type == CHECKOUT,
+ repository);
out:
free (preload_update_dir);
preload_update_dir = oldupdate;
@@ -1192,8 +1204,28 @@ emptydir_name ()
}
/* Build all the dirs along the path to DIRS with CVS subdirs with appropriate
- repositories. If ->repository is NULL, do not create a CVSADM directory
- for that subdirectory; just CVS_CHDIR into it. */
+ * repositories. If DIRS->repository is NULL or the directory already exists,
+ * do not create a CVSADM directory for that subdirectory; just CVS_CHDIR into
+ * it. Frees all storage used by DIRS.
+ *
+ * ASSUMPTIONS
+ * 1. Parent directories will be listed in DIRS before their children.
+ * 2. At most a single directory will need to be changed at one time. In
+ * other words, if we are in /a/b/c, and our final destination is
+ * /a/b/c/d/e/f, then we will build d, then d/e, then d/e/f.
+ *
+ * INPUTS
+ * dirs Simple list composed of dir_to_build structures, listing
+ * information about directories to build.
+ * sticky Passed to build_one_dir to tell it whether there are any sticky
+ * tags or dates to be concerned with.
+ *
+ * RETURNS
+ * 1 on error, 0 otherwise.
+ *
+ * ERRORS
+ * The only nonfatal error this function may return is if the CHDIR fails.
+ */
static int
build_dirs_and_chdir (dirs, sticky)
struct dir_to_build *dirs;
@@ -1204,7 +1236,7 @@ build_dirs_and_chdir (dirs, sticky)
while (dirs != NULL)
{
- char *dir = last_component (dirs->dirpath);
+ const char *dir = last_component (dirs->dirpath);
if (!dirs->just_chdir)
{
diff --git a/contrib/cvs/src/classify.c b/contrib/cvs/src/classify.c
index 285153c..7ce8235 100644
--- a/contrib/cvs/src/classify.c
+++ b/contrib/cvs/src/classify.c
@@ -266,7 +266,7 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp,
* There is no user file, so note that it was lost and
* extract a new version
*/
- /* Comparing the command_name against "update", in
+ /* Comparing the cvs_cmd_name against "update", in
addition to being an ugly way to operate, means
that this message does not get printed by the
server. That might be considered just a straight
@@ -274,7 +274,7 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp,
gets hit when a patch fails and the client fetches
a file. I'm not sure there is currently any way
for the server to distinguish those two cases. */
- if (strcmp (command_name, "update") == 0)
+ if (strcmp (cvs_cmd_name, "update") == 0)
if (!really_quiet)
error (0, 0, "warning: %s was lost", finfo->fullname);
ret = T_CHECKOUT;
@@ -344,7 +344,7 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp,
/* See comment at other "update" compare, for more
thoughts on this comparison. */
- if (strcmp (command_name, "update") == 0)
+ if (strcmp (cvs_cmd_name, "update") == 0)
if (!really_quiet)
error (0, 0, "warning: %s was lost", finfo->fullname);
ret = T_CHECKOUT;
diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c
index 94e902a..1b7f7c8 100644
--- a/contrib/cvs/src/client.c
+++ b/contrib/cvs/src/client.c
@@ -1,5 +1,3 @@
-/* JT thinks BeOS is worth the trouble. */
-
/* CVS client-related stuff.
This program is free software; you can redistribute it and/or modify
@@ -21,12 +19,13 @@
#include "getline.h"
#include "edit.h"
#include "buffer.h"
+#include "savecwd.h"
#ifdef CLIENT_SUPPORT
# include "md5.h"
-# if defined(AUTH_CLIENT_SUPPORT) || HAVE_KERBEROS || defined(SOCK_ERRNO) || defined(SOCK_STRERROR)
+# if defined(AUTH_CLIENT_SUPPORT) || defined(HAVE_KERBEROS) || defined(HAVE_GSSAPI) || defined(SOCK_ERRNO) || defined(SOCK_STRERROR)
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# else /* No winsock.h */
@@ -86,7 +85,20 @@ static int connect_to_gserver PROTO((cvsroot_t *, int, struct hostent *));
# endif /* HAVE_GSSAPI */
-static void add_prune_candidate PROTO((char *));
+
+
+/* Keep track of any paths we are sending for Max-dotdot so that we can verify
+ * that uplevel paths coming back form the server are valid.
+ *
+ * FIXME: The correct way to do this is probably provide some sort of virtual
+ * path map on the client side. This would be generic enough to be applied to
+ * absolute paths supplied by the user too.
+ */
+static List *uppaths = NULL;
+
+
+
+static void add_prune_candidate PROTO((const char *));
/* All the commands. */
int add PROTO((int argc, char **argv));
@@ -123,8 +135,6 @@ static void handle_set_static_directory PROTO((char *, int));
static void handle_clear_static_directory PROTO((char *, int));
static void handle_set_sticky PROTO((char *, int));
static void handle_clear_sticky PROTO((char *, int));
-static void handle_set_checkin_prog PROTO((char *, int));
-static void handle_set_update_prog PROTO((char *, int));
static void handle_module_expansion PROTO((char *, int));
static void handle_wrapper_rcs_option PROTO((char *, int));
static void handle_m PROTO((char *, int));
@@ -995,10 +1005,62 @@ handle_valid_requests (args, len)
}
}
-/* This variable holds the result of Entries_Open, so that we can
- close Entries_Close on it when we move on to a new directory, or
- when we finish. */
-static List *last_entries;
+
+
+/*
+ * This is a proc for walklist(). It inverts the error return premise of
+ * walklist.
+ *
+ * RETURNS
+ * True If this path is prefixed by one of the paths in walklist and
+ * does not step above the prefix path.
+ * False Otherwise.
+ */
+static
+int path_list_prefixed (p, closure)
+ Node *p;
+ void *closure;
+{
+ const char *questionable = closure;
+ const char *prefix = p->key;
+ if (strncmp (prefix, questionable, strlen (prefix))) return 0;
+ questionable += strlen (prefix);
+ while (ISDIRSEP (*questionable)) questionable++;
+ if (*questionable == '\0') return 1;
+ return pathname_levels (questionable);
+}
+
+
+
+/*
+ * Need to validate the client pathname. Disallowed paths include:
+ *
+ * 1. Absolute paths.
+ * 2. Pathnames that do not reference a specifically requested update
+ * directory.
+ *
+ * In case 2, we actually only check that the directory is under the uppermost
+ * directories mentioned on the command line.
+ *
+ * RETURNS
+ * True If the path is valid.
+ * False Otherwise.
+ */
+static
+int is_valid_client_path (pathname)
+ const char *pathname;
+{
+ /* 1. Absolute paths. */
+ if (isabsolute (pathname)) return 0;
+ /* 2. No up-references in path. */
+ if (pathname_levels (pathname) == 0) return 1;
+ /* 2. No Max-dotdot paths registered. */
+ if (uppaths == NULL) return 0;
+
+ return walklist (uppaths, path_list_prefixed, (void *)pathname);
+}
+
+
/*
* Do all the processing for PATHNAME, where pathname consists of the
@@ -1011,8 +1073,6 @@ static List *last_entries;
* SHORT_PATHNAME. When we call FUNC, the curent directory points to
* the directory portion of SHORT_PATHNAME. */
-static char *last_dir_name;
-
static void
call_in_directory (pathname, func, data)
char *pathname;
@@ -1020,6 +1080,8 @@ call_in_directory (pathname, func, data)
char *filename));
char *data;
{
+ /* This variable holds the result of Entries_Open. */
+ List *last_entries = NULL;
char *dir_name;
char *filename;
/* This is what we get when we hook up the directory (working directory
@@ -1049,6 +1111,7 @@ call_in_directory (pathname, func, data)
char *reposdirname;
char *rdirp;
int reposdirname_absolute;
+ int newdir = 0;
reposname = NULL;
read_line (&reposname);
@@ -1069,6 +1132,36 @@ call_in_directory (pathname, func, data)
short_repos = reposname;
}
}
+
+ /* Now that we have SHORT_REPOS, we can calculate the path to the file we
+ * are being requested to operate on.
+ */
+ filename = strrchr (short_repos, '/');
+ if (filename == NULL)
+ filename = short_repos;
+ else
+ ++filename;
+
+ short_pathname = xmalloc (strlen (pathname) + strlen (filename) + 5);
+ strcpy (short_pathname, pathname);
+ strcat (short_pathname, filename);
+
+ /* Now that we know the path to the file we were requested to operate on,
+ * we can verify that it is valid.
+ *
+ * For security reasons, if SHORT_PATHNAME is absolute or attempts to
+ * ascend outside of the current sanbbox, we abort. The server should not
+ * send us anything but relative paths which remain inside the sandbox
+ * here. Anything less means a trojan CVS server could create and edit
+ * arbitrary files on the client.
+ */
+ if (!is_valid_client_path (short_pathname))
+ {
+ error (0, 0,
+ "Server attempted to update a file via an invalid pathname:");
+ error (1, 0, "`%s'.", short_pathname);
+ }
+
reposdirname = xstrdup (short_repos);
p = strrchr (reposdirname, '/');
if (p == NULL)
@@ -1091,296 +1184,272 @@ call_in_directory (pathname, func, data)
if (client_prune_dirs)
add_prune_candidate (dir_name);
- filename = strrchr (short_repos, '/');
- if (filename == NULL)
- filename = short_repos;
- else
- ++filename;
-
- short_pathname = xmalloc (strlen (pathname) + strlen (filename) + 5);
- strcpy (short_pathname, pathname);
- strcat (short_pathname, filename);
-
- if (last_dir_name == NULL
- || strcmp (last_dir_name, dir_name) != 0)
+ if (toplevel_wd == NULL)
{
- int newdir;
-
- if (strcmp (command_name, "export") != 0)
- if (last_entries)
- Entries_Close (last_entries);
-
- if (last_dir_name)
- free (last_dir_name);
- last_dir_name = dir_name;
-
+ toplevel_wd = xgetwd ();
if (toplevel_wd == NULL)
- {
- toplevel_wd = xgetwd ();
- if (toplevel_wd == NULL)
- error (1, errno, "could not get working directory");
- }
-
- if (CVS_CHDIR (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
- newdir = 0;
-
- /* 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);
+ error (1, errno, "could not get working directory");
+ }
- free (repo);
- }
+ 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)
+ if (CVS_CHDIR (dir_name) < 0)
+ {
+ char *dir;
+ char *dirp;
+
+ if (! existence_error (errno))
+ error (1, errno, "could not chdir to %s", dir_name);
+
+ /* Directory does not exist, we need to create it. */
+ newdir = 1;
+
+ /* Provided we are willing to assume that directories get
+ created one at a time, we could simplify this a lot.
+ Do note that one aspect still would need to walk the
+ dir_name path: the checking for "fncmp (dir, CVSADM)". */
+
+ dir = xmalloc (strlen (dir_name) + 1);
+ dirp = dir_name;
+ rdirp = reposdirname;
+
+ /* This algorithm makes nested directories one at a time
+ and create CVS administration files in them. For
+ example, we're checking out foo/bar/baz from the
+ repository:
+
+ 1) create foo, point CVS/Repository to <root>/foo
+ 2) .. foo/bar .. <root>/foo/bar
+ 3) .. foo/bar/baz .. <root>/foo/bar/baz
+
+ As you can see, we're just stepping along DIR_NAME (with
+ DIRP) and REPOSDIRNAME (with RDIRP) respectively.
+
+ We need to be careful when we are checking out a
+ module, however, since DIR_NAME and REPOSDIRNAME are not
+ going to be the same. Since modules will not have any
+ slashes in their names, we should watch the output of
+ STRCHR to decide whether or not we should use STRCHR on
+ the RDIRP. That is, if we're down to a module name,
+ don't keep picking apart the repository directory name. */
+
+ do
{
- char *dir;
- char *dirp;
-
- if (! existence_error (errno))
- error (1, errno, "could not chdir to %s", dir_name);
-
- /* Directory does not exist, we need to create it. */
- newdir = 1;
-
- /* Provided we are willing to assume that directories get
- created one at a time, we could simplify this a lot.
- Do note that one aspect still would need to walk the
- dir_name path: the checking for "fncmp (dir, CVSADM)". */
-
- dir = xmalloc (strlen (dir_name) + 1);
- dirp = dir_name;
- rdirp = reposdirname;
-
- /* This algorithm makes nested directories one at a time
- and create CVS administration files in them. For
- example, we're checking out foo/bar/baz from the
- repository:
-
- 1) create foo, point CVS/Repository to <root>/foo
- 2) .. foo/bar .. <root>/foo/bar
- 3) .. foo/bar/baz .. <root>/foo/bar/baz
-
- As you can see, we're just stepping along DIR_NAME (with
- DIRP) and REPOSDIRNAME (with RDIRP) respectively.
-
- We need to be careful when we are checking out a
- module, however, since DIR_NAME and REPOSDIRNAME are not
- going to be the same. Since modules will not have any
- slashes in their names, we should watch the output of
- STRCHR to decide whether or not we should use STRCHR on
- the RDIRP. That is, if we're down to a module name,
- don't keep picking apart the repository directory name. */
-
- do
+ dirp = strchr (dirp, '/');
+ if (dirp)
{
- dirp = strchr (dirp, '/');
- if (dirp)
- {
- strncpy (dir, dir_name, dirp - dir_name);
- dir[dirp - dir_name] = '\0';
- /* Skip the slash. */
- ++dirp;
- if (rdirp == NULL)
- /* This just means that the repository string has
- fewer components than the dir_name string. But
- that is OK (e.g. see modules3-8 in testsuite). */
- ;
- else
- rdirp = strchr (rdirp, '/');
- }
+ strncpy (dir, dir_name, dirp - dir_name);
+ dir[dirp - dir_name] = '\0';
+ /* Skip the slash. */
+ ++dirp;
+ if (rdirp == NULL)
+ /* This just means that the repository string has
+ fewer components than the dir_name string. But
+ that is OK (e.g. see modules3-8 in testsuite). */
+ ;
else
- {
- /* If there are no more slashes in the dir name,
- we're down to the most nested directory -OR- to
- the name of a module. In the first case, we
- should be down to a DIRP that has no slashes,
- so it won't help/hurt to do another STRCHR call
- on DIRP. It will definitely hurt, however, if
- we're down to a module name, since a module
- name can point to a nested directory (that is,
- DIRP will still have slashes in it. Therefore,
- we should set it to NULL so the routine below
- copies the contents of REMOTEDIRNAME onto the
- root repository directory (does this if rdirp
- is set to NULL, because we used to do an extra
- STRCHR call here). */
-
- rdirp = NULL;
- strcpy (dir, dir_name);
- }
+ rdirp = strchr (rdirp, '/');
+ }
+ else
+ {
+ /* If there are no more slashes in the dir name,
+ we're down to the most nested directory -OR- to
+ the name of a module. In the first case, we
+ should be down to a DIRP that has no slashes,
+ so it won't help/hurt to do another STRCHR call
+ on DIRP. It will definitely hurt, however, if
+ we're down to a module name, since a module
+ name can point to a nested directory (that is,
+ DIRP will still have slashes in it. Therefore,
+ we should set it to NULL so the routine below
+ copies the contents of REMOTEDIRNAME onto the
+ root repository directory (does this if rdirp
+ is set to NULL, because we used to do an extra
+ STRCHR call here). */
+
+ rdirp = NULL;
+ strcpy (dir, dir_name);
+ }
+
+ if (fncmp (dir, CVSADM) == 0)
+ {
+ error (0, 0, "cannot create a directory named %s", dir);
+ error (0, 0, "because CVS uses \"%s\" for its own uses",
+ CVSADM);
+ error (1, 0, "rename the directory and try again");
+ }
+
+ if (mkdir_if_needed (dir))
+ {
+ /* It already existed, fine. Just keep going. */
+ }
+ else if (strcmp (cvs_cmd_name, "export") == 0)
+ /* Don't create CVSADM directories if this is export. */
+ ;
+ else
+ {
+ /*
+ * Put repository in CVS/Repository. For historical
+ * (pre-CVS/Root) reasons, this is an absolute pathname,
+ * but what really matters is the part of it which is
+ * relative to cvsroot.
+ */
+ char *repo;
+ char *r, *b;
- if (fncmp (dir, CVSADM) == 0)
+ repo = xmalloc (strlen (reposdirname)
+ + strlen (toplevel_repos)
+ + 80);
+ if (reposdirname_absolute)
+ r = repo;
+ else
{
- error (0, 0, "cannot create a directory named %s", dir);
- error (0, 0, "because CVS uses \"%s\" for its own uses",
- CVSADM);
- error (1, 0, "rename the directory and try again");
+ strcpy (repo, toplevel_repos);
+ strcat (repo, "/");
+ r = repo + strlen (repo);
}
- if (mkdir_if_needed (dir))
+ if (rdirp)
{
- /* It already existed, fine. Just keep going. */
+ /* See comment near start of function; the only
+ way that the server can put the right thing
+ in each CVS/Repository file is to create the
+ directories one at a time. I think that the
+ CVS server has been doing this all along. */
+ error (0, 0, "\
+warning: server is not creating directories one at a time");
+ strncpy (r, reposdirname, rdirp - reposdirname);
+ r[rdirp - reposdirname] = '\0';
}
- else if (strcmp (command_name, "export") == 0)
- /* Don't create CVSADM directories if this is export. */
- ;
else
- {
- /*
- * Put repository in CVS/Repository. For historical
- * (pre-CVS/Root) reasons, this is an absolute pathname,
- * but what really matters is the part of it which is
- * relative to cvsroot.
- */
- char *repo;
- char *r, *b;
-
- repo = xmalloc (strlen (reposdirname)
- + strlen (toplevel_repos)
- + 80);
- if (reposdirname_absolute)
- r = repo;
- else
- {
- strcpy (repo, toplevel_repos);
- strcat (repo, "/");
- r = repo + strlen (repo);
- }
+ strcpy (r, reposdirname);
- if (rdirp)
- {
- /* See comment near start of function; the only
- way that the server can put the right thing
- in each CVS/Repository file is to create the
- directories one at a time. I think that the
- CVS server has been doing this all along. */
- error (0, 0, "\
-warning: server is not creating directories one at a time");
- strncpy (r, reposdirname, rdirp - reposdirname);
- r[rdirp - reposdirname] = '\0';
- }
- else
- strcpy (r, reposdirname);
-
- Create_Admin (dir, dir, repo,
- (char *)NULL, (char *)NULL, 0, 0, 1);
- free (repo);
-
- b = strrchr (dir, '/');
- if (b == NULL)
- Subdir_Register ((List *) NULL, (char *) NULL, dir);
- else
- {
- *b = '\0';
- Subdir_Register ((List *) NULL, dir, b + 1);
- *b = '/';
- }
- }
+ Create_Admin (dir, dir, repo,
+ (char *)NULL, (char *)NULL, 0, 0, 1);
+ free (repo);
- if (rdirp != NULL)
+ b = strrchr (dir, '/');
+ if (b == NULL)
+ Subdir_Register ((List *) NULL, (char *) NULL, dir);
+ else
{
- /* Skip the slash. */
- ++rdirp;
+ *b = '\0';
+ Subdir_Register ((List *) NULL, dir, b + 1);
+ *b = '/';
}
+ }
- } while (dirp != NULL);
- free (dir);
- /* Now it better work. */
- if ( CVS_CHDIR (dir_name) < 0)
- error (1, errno, "could not chdir to %s", dir_name);
- }
- else if (strcmp (command_name, "export") == 0)
- /* Don't create CVSADM directories if this is export. */
- ;
- else if (!isdir (CVSADM))
- {
- /*
- * Put repository in CVS/Repository. For historical
- * (pre-CVS/Root) reasons, this is an absolute pathname,
- * but what really matters is the part of it which is
- * relative to cvsroot.
- */
- char *repo;
-
- if (reposdirname_absolute)
- repo = reposdirname;
- else
+ if (rdirp != NULL)
{
- repo = xmalloc (strlen (reposdirname)
- + strlen (toplevel_repos)
- + 10);
- strcpy (repo, toplevel_repos);
- strcat (repo, "/");
- strcat (repo, reposdirname);
+ /* Skip the slash. */
+ ++rdirp;
}
- Create_Admin (".", ".", repo, (char *)NULL, (char *)NULL, 0, 1, 1);
- if (repo != reposdirname)
- free (repo);
+ } while (dirp != NULL);
+ free (dir);
+ /* Now it better work. */
+ if ( CVS_CHDIR (dir_name) < 0)
+ error (1, errno, "could not chdir to %s", dir_name);
+ }
+ else if (strcmp (cvs_cmd_name, "export") == 0)
+ /* Don't create CVSADM directories if this is export. */
+ ;
+ else if (!isdir (CVSADM))
+ {
+ /*
+ * Put repository in CVS/Repository. For historical
+ * (pre-CVS/Root) reasons, this is an absolute pathname,
+ * but what really matters is the part of it which is
+ * relative to cvsroot.
+ */
+ char *repo;
+
+ if (reposdirname_absolute)
+ repo = reposdirname;
+ else
+ {
+ repo = xmalloc (strlen (reposdirname)
+ + strlen (toplevel_repos)
+ + 10);
+ strcpy (repo, toplevel_repos);
+ strcat (repo, "/");
+ strcat (repo, reposdirname);
}
- if (strcmp (command_name, "export") != 0)
+ Create_Admin (".", ".", repo, (char *)NULL, (char *)NULL, 0, 1, 1);
+ if (repo != reposdirname)
+ free (repo);
+ }
+
+ if (strcmp (cvs_cmd_name, "export") != 0)
+ {
+ last_entries = Entries_Open (0, dir_name);
+
+ /* If this is a newly created directory, we will record
+ all subdirectory information, so call Subdirs_Known in
+ case there are no subdirectories. If this is not a
+ newly created directory, it may be an old working
+ directory from before we recorded subdirectory
+ information in the Entries file. We force a search for
+ all subdirectories now, to make sure our subdirectory
+ information is up to date. If the Entries file does
+ record subdirectory information, then this call only
+ does list manipulation. */
+ if (newdir)
+ Subdirs_Known (last_entries);
+ else
{
- last_entries = Entries_Open (0, dir_name);
-
- /* If this is a newly created directory, we will record
- all subdirectory information, so call Subdirs_Known in
- case there are no subdirectories. If this is not a
- newly created directory, it may be an old working
- directory from before we recorded subdirectory
- information in the Entries file. We force a search for
- all subdirectories now, to make sure our subdirectory
- information is up to date. If the Entries file does
- record subdirectory information, then this call only
- does list manipulation. */
- if (newdir)
- Subdirs_Known (last_entries);
- else
- {
- List *dirlist;
+ List *dirlist;
- dirlist = Find_Directories ((char *) NULL, W_LOCAL,
- last_entries);
- dellist (&dirlist);
- }
+ dirlist = Find_Directories ((char *) NULL, W_LOCAL,
+ last_entries);
+ dellist (&dirlist);
}
}
- else
- free (dir_name);
free (reposdirname);
(*func) (data, last_entries, short_pathname, filename);
+ if (last_entries != NULL)
+ Entries_Close (last_entries);
+ free (dir_name);
free (short_pathname);
free (reposname);
}
@@ -1794,15 +1863,16 @@ update_entries (data_arg, ent_list, short_pathname, filename)
several causes: (1) something/someone creates the file
during the time that CVS is running, (2) the repository
has two files whose names clash for the client because
- of case-insensitivity or similar causes, (3) a special
- case of this is that a file gets renamed for example
- from a.c to A.C. A "cvs update" on a case-insensitive
- client will get this error. Repeating the update takes
- care of the problem, but is it clear to the user what
- is going on and what to do about it?, (4) the client
- has a file which the server doesn't know about (e.g. "?
- foo" file), and that name clashes with a file the
- server does know about, (5) classify.c will print the same
+ of case-insensitivity or similar causes, See 3 for
+ additional notes. (3) a special case of this is that a
+ file gets renamed for example from a.c to A.C. A
+ "cvs update" on a case-insensitive client will get this
+ error. In this case and in case 2, the filename
+ (short_pathname) printed in the error message will likely _not_
+ have the same case as seen by the user in a directory listing.
+ (4) the client has a file which the server doesn't know
+ about (e.g. "? foo" file), and that name clashes with a file
+ the server does know about, (5) classify.c will print the same
message for other reasons.
I hope the above paragraph makes it clear that making this
@@ -2127,9 +2197,8 @@ update_entries (data_arg, ent_list, short_pathname, filename)
struct utimbuf t;
memset (&t, 0, sizeof (t));
- /* There is probably little point in trying to preserved the
- actime (or is there? What about Checked-in?). */
- t.modtime = t.actime = stored_modtime;
+ t.modtime = stored_modtime;
+ (void) time (&t.actime);
#ifdef UTIME_EXPECTS_WRITABLE
if (!iswritable (filename))
@@ -2143,7 +2212,7 @@ update_entries (data_arg, ent_list, short_pathname, filename)
error (0, errno, "cannot set time on %s", filename);
#ifdef UTIME_EXPECTS_WRITABLE
- if (change_it_back == 1)
+ if (change_it_back)
{
xchmod (filename, 0);
change_it_back = 0;
@@ -2157,7 +2226,7 @@ update_entries (data_arg, ent_list, short_pathname, filename)
* Process the entries line. Do this after we've written the file,
* since we need the timestamp.
*/
- if (strcmp (command_name, "export") != 0)
+ if (strcmp (cvs_cmd_name, "export") != 0)
{
char *local_timestamp;
char *file_timestamp;
@@ -2181,7 +2250,7 @@ update_entries (data_arg, ent_list, short_pathname, filename)
{
local_timestamp = file_timestamp;
- /* Checking for command_name of "commit" doesn't seem like
+ /* Checking for cvs_cmd_name of "commit" doesn't seem like
the cleanest way to handle this, but it seem to roughly
parallel what the :local: code which calls
mark_up_to_date ends up amounting to. Some day, should
@@ -2189,7 +2258,7 @@ update_entries (data_arg, ent_list, short_pathname, filename)
vis-a-vis both Entries and Base and clarify
cvsclient.texi accordingly. */
- if (!strcmp (command_name, "commit"))
+ if (!strcmp (cvs_cmd_name, "commit"))
mark_up_to_date (filename);
}
@@ -2379,7 +2448,7 @@ handle_set_static_directory (args, len)
char *args;
int len;
{
- if (strcmp (command_name, "export") == 0)
+ if (strcmp (cvs_cmd_name, "export") == 0)
{
/* Swallow the repository. */
read_line (NULL);
@@ -2404,7 +2473,7 @@ handle_clear_static_directory (pathname, len)
char *pathname;
int len;
{
- if (strcmp (command_name, "export") == 0)
+ if (strcmp (cvs_cmd_name, "export") == 0)
{
/* Swallow the repository. */
read_line (NULL);
@@ -2459,7 +2528,7 @@ handle_set_sticky (pathname, len)
char *pathname;
int len;
{
- if (strcmp (command_name, "export") == 0)
+ if (strcmp (cvs_cmd_name, "export") == 0)
{
/* Swallow the repository. */
read_line (NULL);
@@ -2500,7 +2569,7 @@ handle_clear_sticky (pathname, len)
char *pathname;
int len;
{
- if (strcmp (command_name, "export") == 0)
+ if (strcmp (cvs_cmd_name, "export") == 0)
{
/* Swallow the repository. */
read_line (NULL);
@@ -2529,9 +2598,12 @@ template (data, ent_list, short_pathname, filename)
char *short_pathname;
char *filename;
{
- /* FIXME: should be computing second argument from CVSADM_TEMPLATE
- and short_pathname. */
- read_counted_file (CVSADM_TEMPLATE, "<CVS/Template file>");
+ char *buf = xmalloc ( strlen ( short_pathname )
+ + strlen ( CVSADM_TEMPLATE )
+ + 2 );
+ sprintf ( buf, "%s/%s", short_pathname, CVSADM_TEMPLATE );
+ read_counted_file ( CVSADM_TEMPLATE, buf );
+ free ( buf );
}
static void handle_template PROTO ((char *, int));
@@ -2544,111 +2616,8 @@ handle_template (pathname, len)
call_in_directory (pathname, template, NULL);
}
-
-struct save_prog {
- char *name;
- char *dir;
- struct save_prog *next;
-};
-
-static struct save_prog *checkin_progs;
-static struct save_prog *update_progs;
-
-/*
- * Unlike some responses this doesn't include the repository. So we can't
- * just call call_in_directory and have the right thing happen; we save up
- * the requests and do them at the end.
- */
-static void
-handle_set_checkin_prog (args, len)
- char *args;
- int len;
-{
- char *prog;
- struct save_prog *p;
-
- read_line (&prog);
- if (strcmp (command_name, "export") == 0)
- return;
-
- p = (struct save_prog *) xmalloc (sizeof (struct save_prog));
- p->next = checkin_progs;
- p->dir = xstrdup (args);
- p->name = prog;
- checkin_progs = p;
-}
-
-static void
-handle_set_update_prog (args, len)
- char *args;
- int len;
-{
- char *prog;
- struct save_prog *p;
-
- read_line (&prog);
- if (strcmp (command_name, "export") == 0)
- return;
-
- p = (struct save_prog *) xmalloc (sizeof (struct save_prog));
- p->next = update_progs;
- p->dir = xstrdup (args);
- p->name = prog;
- update_progs = p;
-}
-
-static void do_deferred_progs PROTO((void));
-static void
-do_deferred_progs ()
-{
- struct save_prog *p;
- struct save_prog *q;
- char *fname;
- FILE *f;
-
- if (toplevel_wd != NULL)
- {
- if (CVS_CHDIR (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
- }
- for (p = checkin_progs; p != NULL; )
- {
- fname = xmalloc (strlen (p->dir) + sizeof CVSADM_CIPROG + 10);
- sprintf (fname, "%s/%s", p->dir, CVSADM_CIPROG);
- f = open_file (fname, "w");
- if (fprintf (f, "%s\n", p->name) < 0)
- error (1, errno, "writing %s", fname);
- if (fclose (f) == EOF)
- error (1, errno, "closing %s", fname);
- free (p->name);
- free (p->dir);
- q = p->next;
- free (p);
- p = q;
- free (fname);
- }
- checkin_progs = NULL;
- for (p = update_progs; p != NULL; )
- {
- fname = xmalloc (strlen (p->dir) + sizeof CVSADM_UPROG + 10);
- sprintf (fname, "%s/%s", p->dir, CVSADM_UPROG);
- f = open_file (fname, "w");
- if (fprintf (f, "%s\n", p->name) < 0)
- error (1, errno, "writing %s", fname);
- if (fclose (f) == EOF)
- error (1, errno, "closing %s", fname);
- free (p->name);
- free (p->dir);
- q = p->next;
- free (p);
- p = q;
- free (fname);
- }
- update_progs = NULL;
-}
-
struct save_dir {
char *dir;
struct save_dir *next;
@@ -2658,7 +2627,7 @@ struct save_dir *prune_candidates;
static void
add_prune_candidate (dir)
- char *dir;
+ const char *dir;
{
struct save_dir *p;
@@ -2715,13 +2684,13 @@ process_prune_candidates ()
static char *last_repos;
static char *last_update_dir;
-static void send_repository PROTO((char *, char *, char *));
+static void send_repository PROTO((const char *, const char *, const char *));
static void
send_repository (dir, repos, update_dir)
- char *dir;
- char *repos;
- char *update_dir;
+ const char *dir;
+ const char *repos;
+ const char *update_dir;
{
char *adm_name;
@@ -2784,7 +2753,7 @@ send_repository (dir, repos, update_dir)
sort of duplicates code elsewhere, but each
case seems slightly different... */
char buf[1];
- char *p = update_dir;
+ const char *p = update_dir;
while (*p != '\0')
{
assert (*p != '\012');
@@ -2851,76 +2820,6 @@ send_repository (dir, repos, update_dir)
error (0, errno, "closing %s", adm_name);
}
}
- if (supported_request ("Checkin-prog"))
- {
- FILE *f;
- if (dir[0] == '\0')
- strcpy (adm_name, CVSADM_CIPROG);
- else
- sprintf (adm_name, "%s/%s", dir, CVSADM_CIPROG);
-
- f = CVS_FOPEN (adm_name, "r");
- if (f == NULL)
- {
- if (! existence_error (errno))
- error (1, errno, "reading %s", adm_name);
- }
- else
- {
- char line[80];
- char *nl = NULL;
-
- send_to_server ("Checkin-prog ", 0);
-
- while (fgets (line, sizeof (line), f) != NULL)
- {
- send_to_server (line, 0);
-
- nl = strchr (line, '\n');
- if (nl != NULL)
- break;
- }
- if (nl == NULL)
- send_to_server ("\012", 1);
- if (fclose (f) == EOF)
- error (0, errno, "closing %s", adm_name);
- }
- }
- if (supported_request ("Update-prog"))
- {
- FILE *f;
- if (dir[0] == '\0')
- strcpy (adm_name, CVSADM_UPROG);
- else
- sprintf (adm_name, "%s/%s", dir, CVSADM_UPROG);
-
- f = CVS_FOPEN (adm_name, "r");
- if (f == NULL)
- {
- if (! existence_error (errno))
- error (1, errno, "reading %s", adm_name);
- }
- else
- {
- char line[80];
- char *nl = NULL;
-
- send_to_server ("Update-prog ", 0);
-
- while (fgets (line, sizeof (line), f) != NULL)
- {
- send_to_server (line, 0);
-
- nl = strchr (line, '\n');
- if (nl != NULL)
- break;
- }
- if (nl == NULL)
- send_to_server ("\012", 1);
- if (fclose (f) == EOF)
- error (0, errno, "closing %s", adm_name);
- }
- }
free (adm_name);
if (last_repos != NULL)
free (last_repos);
@@ -2933,11 +2832,13 @@ send_repository (dir, repos, update_dir)
/* Send a Repository line and set toplevel_repos. */
void
-send_a_repository (dir, repository, update_dir)
- char *dir;
- char *repository;
- char *update_dir;
+send_a_repository (dir, repository, update_dir_in)
+ const char *dir;
+ const char *repository;
+ const char *update_dir_in;
{
+ char *update_dir = xstrdup (update_dir_in);
+
if (toplevel_repos == NULL && repository != NULL)
{
if (update_dir[0] == '\0'
@@ -3023,8 +2924,11 @@ send_a_repository (dir, repository, update_dir)
}
send_repository (dir, repository, update_dir);
+ free (update_dir);
}
-
+
+
+
/* The "expanded" modules. */
static int modules_count;
static int modules_allocated;
@@ -3406,10 +3310,6 @@ struct response responses[] =
rs_optional),
RSP_LINE("Template", handle_template, response_type_normal,
rs_optional),
- RSP_LINE("Set-checkin-prog", handle_set_checkin_prog, response_type_normal,
- rs_optional),
- RSP_LINE("Set-update-prog", handle_set_update_prog, response_type_normal,
- rs_optional),
RSP_LINE("Notified", handle_notified, response_type_normal, rs_optional),
RSP_LINE("Module-expansion", handle_module_expansion, response_type_normal,
rs_optional),
@@ -3438,7 +3338,7 @@ struct response responses[] =
*/
void
send_to_server (str, len)
- char *str;
+ const char *str;
size_t len;
{
static int nbytes;
@@ -3576,6 +3476,8 @@ get_server_responses ()
return 0;
}
+
+
/* Get the responses and then close the connection. */
/*
@@ -3594,14 +3496,20 @@ get_responses_and_close ()
int errs = get_server_responses ();
int status;
- if (last_entries != NULL)
+ /* The following is necessary when working with multiple cvsroots, at least
+ * with commit. It used to be buried nicely in do_deferred_progs() before
+ * that function was removed. I suspect it wouldn't be necessary if
+ * call_in_directory() saved its working directory via save_cwd() before
+ * changing its directory and restored the saved working directory via
+ * restore_cwd() before exiting. Of course, calling CVS_CHDIR only once,
+ * here, may be more efficient.
+ */
+ if( toplevel_wd != NULL )
{
- Entries_Close (last_entries);
- last_entries = NULL;
+ if( CVS_CHDIR( toplevel_wd ) < 0 )
+ error( 1, errno, "could not chdir to %s", toplevel_wd );
}
- do_deferred_progs ();
-
if (client_prune_dirs)
process_prune_candidates ();
@@ -3652,7 +3560,7 @@ supported_request (name)
-#if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS)
+#if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI)
static struct hostent *init_sockaddr PROTO ((struct sockaddr_in *, char *,
unsigned int));
@@ -3678,12 +3586,8 @@ init_sockaddr (name, hostname, port)
return hostinfo;
}
-#endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) */
-
-#ifdef AUTH_CLIENT_SUPPORT
-
/* Generic function to do port number lookup tasks.
*
* In order of precedence, will return:
@@ -3748,13 +3652,19 @@ get_cvs_port_number (root)
switch (root->method)
{
+# ifdef HAVE_GSSAPI
case gserver_method:
+# endif /* HAVE_GSSAPI */
+# ifdef AUTH_CLIENT_SUPPORT
case pserver_method:
+# endif /* AUTH_CLIENT_SUPPORT */
+# if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI)
return get_port_number ("CVS_CLIENT_PORT", "cvspserver", CVS_AUTH_PORT);
-#ifdef HAVE_KERBEROS
+# endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) */
+# ifdef HAVE_KERBEROS
case kserver_method:
return get_port_number ("CVS_CLIENT_PORT", "cvs", CVS_PORT);
-#endif
+# endif /* HAVE_KERBEROS */
default:
error(1, EINVAL, "internal error: get_cvs_port_number called for invalid connection method (%s)",
method_names[root->method]);
@@ -3778,7 +3688,7 @@ make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, is_sock)
FILE *to_server_fp;
FILE *from_server_fp;
-#ifdef NO_SOCKET_TO_FD
+# ifdef NO_SOCKET_TO_FD
if (is_sock)
{
assert (tofd == fromfd);
@@ -3788,7 +3698,7 @@ make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, is_sock)
(BUFMEMERRPROC) NULL);
}
else
-#endif /* NO_SOCKET_TO_FD */
+# endif /* NO_SOCKET_TO_FD */
{
/* todo: some OS's don't need these calls... */
close_on_exec (tofd);
@@ -3823,43 +3733,11 @@ make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, is_sock)
(BUFMEMERRPROC) NULL);
}
}
+#endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined(HAVE_GSSAPI) */
-/* Connect to a forked server process. */
-
-void
-connect_to_forked_server (to_server, from_server)
- struct buffer **to_server;
- struct buffer **from_server;
-{
- int tofd, fromfd;
- int child_pid;
-
- /* This is pretty simple. All we need to do is choose the correct
- cvs binary and call piped_child. */
-
- char *command[3];
-
- command[0] = getenv ("CVS_SERVER");
- if (! command[0])
- command[0] = program_path;
-
- command[1] = "server";
- command[2] = NULL;
-
- if (trace)
- {
- fprintf (stderr, " -> Forking server: %s %s\n", command[0], command[1]);
- }
-
- child_pid = piped_child (command, &tofd, &fromfd);
- if (child_pid < 0)
- error (1, 0, "could not fork server process");
-
- make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, 0);
-}
-
+#if defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI)
/* Connect to the authenticating server.
If VERIFY_ONLY is non-zero, then just verify that the password is
@@ -3968,7 +3846,7 @@ auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
/* Run the authorization mini-protocol before anything else. */
if (do_gssapi)
{
-#ifdef HAVE_GSSAPI
+# ifdef HAVE_GSSAPI
FILE *fp = stdio_buffer_get_file(lto_server);
int fd = fp ? fileno(fp) : -1;
struct stat s;
@@ -3984,12 +3862,13 @@ auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
"authorization failed: server %s rejected access to %s",
root->hostname, root->directory);
}
-#else
- error (1, 0, "This client does not support GSSAPI authentication");
-#endif
+# else /* ! HAVE_GSSAPI */
+ error (1, 0, "INTERNAL ERROR: This client does not support GSSAPI authentication");
+# endif /* HAVE_GSSAPI */
}
- else
+ else /* ! do_gssapi */
{
+# ifdef AUTH_CLIENT_SUPPORT
char *begin = NULL;
char *password = NULL;
char *end = NULL;
@@ -4035,7 +3914,10 @@ auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
/* Paranoia. */
memset (password, 0, strlen (password));
- }
+# else /* ! AUTH_CLIENT_SUPPORT */
+ error (1, 0, "INTERNAL ERROR: This client does not support pserver authentication");
+# endif /* AUTH_CLIENT_SUPPORT */
+ } /* if (do_gssapi) */
{
char *read_buf;
@@ -4110,12 +3992,53 @@ auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
}
}
}
-#endif /* AUTH_CLIENT_SUPPORT */
+#endif /* defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI) */
-#ifdef HAVE_KERBEROS
+#ifdef CLIENT_SUPPORT
+/* void
+ * connect_to_forked_server ( struct buffer **to_server,
+ * struct buffer **from_server )
+ *
+ * Connect to a forked server process.
+ */
+void
+connect_to_forked_server (to_server, from_server)
+ struct buffer **to_server;
+ struct buffer **from_server;
+{
+ int tofd, fromfd;
+ int child_pid;
+
+ /* This is pretty simple. All we need to do is choose the correct
+ cvs binary and call piped_child. */
+
+ const char *command[3];
+
+ command[0] = getenv ("CVS_SERVER");
+ if (! command[0])
+ command[0] = program_path;
+
+ command[1] = "server";
+ command[2] = NULL;
+
+ if (trace)
+ {
+ fprintf (stderr, " -> Forking server: %s %s\n", command[0], command[1]);
+ }
+ child_pid = piped_child (command, &tofd, &fromfd);
+ if (child_pid < 0)
+ error (1, 0, "could not fork server process");
+
+ make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, 0);
+}
+#endif /* CLIENT_SUPPORT */
+
+
+
+#ifdef HAVE_KERBEROS
/* This function has not been changed to deal with NO_SOCKET_TO_FD
(i.e., systems on which sockets cannot be converted to file
descriptors). The first person to try building a kerberos client
@@ -4142,8 +4065,7 @@ start_tcp_server (root, to_server, from_server)
hp = init_sockaddr (&sin, root->hostname, port);
- hname = xmalloc (strlen (hp->h_name) + 1);
- strcpy (hname, hp->h_name);
+ hname = xstrdup (hp->h_name);
if (trace)
{
@@ -4344,6 +4266,8 @@ connect_to_gserver (root, sock, hostinfo)
#endif /* HAVE_GSSAPI */
+
+
static int send_variable_proc PROTO ((Node *, void *));
static int
@@ -4359,6 +4283,8 @@ send_variable_proc (node, closure)
return 0;
}
+
+
/* Contact the server. */
void
start_server ()
@@ -4371,7 +4297,6 @@ start_server ()
free (toplevel_repos);
toplevel_repos = NULL;
-
/* Note that generally speaking we do *not* fall back to a different
way of connecting if the first one does not work. This is slow
(*really* slow on a 14.4kbps link); the clean way to have a CVS
@@ -4387,32 +4312,32 @@ start_server ()
*/
connect_to_pserver (current_parsed_root, &to_server, &from_server, 0, 0);
break;
-#endif
+#endif /* AUTH_CLIENT_SUPPORT */
#if HAVE_KERBEROS
case kserver_method:
start_tcp_server (current_parsed_root, &to_server, &from_server);
break;
-#endif
+#endif /* HAVE_KERBEROS */
#ifdef HAVE_GSSAPI
case gserver_method:
/* GSSAPI authentication is handled by the pserver. */
connect_to_pserver (current_parsed_root, &to_server, &from_server, 0, 1);
break;
-#endif
+#endif /* HAVE_GSSAPI */
case ext_method:
-#if defined (NO_EXT_METHOD)
+#ifdef NO_EXT_METHOD
error (0, 0, ":ext: method not supported by this port of CVS");
error (1, 0, "try :server: instead");
-#else
+#else /* ! NO_EXT_METHOD */
start_rsh_server (current_parsed_root, &to_server, &from_server);
-#endif
+#endif /* NO_EXT_METHOD */
break;
case server_method:
-#if defined(START_SERVER)
+#ifdef START_SERVER
{
int tofd, fromfd;
START_SERVER (&tofd, &fromfd, getcaller (),
@@ -4420,17 +4345,17 @@ start_server ()
current_parsed_root->directory);
# ifdef START_SERVER_RETURNS_SOCKET
make_bufs_from_fds (tofd, fromfd, 0, &to_server, &from_server, 1);
-# else
+# else /* ! START_SERVER_RETURNS_SOCKET */
make_bufs_from_fds (tofd, fromfd, 0, &to_server, &from_server, 0);
# endif /* START_SERVER_RETURNS_SOCKET */
}
-#else
+#else /* ! START_SERVER */
/* FIXME: It should be possible to implement this portably,
like pserver, which would get rid of the duplicated code
in {vms,windows-NT,...}/startserver.c. */
error (1, 0,
"the :server: access method is not supported by this port of CVS");
-#endif
+#endif /* START_SERVER */
break;
case fork_method:
@@ -4491,9 +4416,6 @@ start_server ()
if (toplevel_repos != NULL)
free (toplevel_repos);
toplevel_repos = NULL;
- if (last_dir_name != NULL)
- free (last_dir_name);
- last_dir_name = NULL;
if (last_repos != NULL)
free (last_repos);
last_repos = NULL;
@@ -4507,7 +4429,7 @@ start_server ()
stored_mode = NULL;
}
- rootless = (strcmp (command_name, "init") == 0);
+ rootless = (strcmp (cvs_cmd_name, "init") == 0);
if (!rootless)
{
send_to_server ("Root ", 0);
@@ -4599,16 +4521,6 @@ start_server ()
error (1, 0,
"This server does not support the global -t option.");
}
- if (logoff)
- {
- if (have_global)
- {
- send_to_server ("Global_option -l\012", 0);
- }
- else
- error (1, 0,
- "This server does not support the global -l option.");
- }
}
/* Find out about server-side cvswrappers. An extra network
@@ -4619,8 +4531,8 @@ start_server ()
reason to bother would be so we could make add work without
contacting the server, I suspect). */
- if ((strcmp (command_name, "import") == 0)
- || (strcmp (command_name, "add") == 0))
+ if ((strcmp (cvs_cmd_name, "import") == 0)
+ || (strcmp (cvs_cmd_name, "add") == 0))
{
if (supported_request ("wrapper-sendme-rcsOptions"))
{
@@ -4751,11 +4663,6 @@ start_server ()
#endif /* ! HAVE_GSSAPI */
}
-#ifdef FILENAMES_CASE_INSENSITIVE
- if (supported_request ("Case") && !rootless)
- send_to_server ("Case\012", 0);
-#endif
-
/* If "Set" is not supported, just silently fail to send the variables.
Users with an old server should get a useful error message when it
fails to recognize the ${=foo} syntax. This way if someone uses
@@ -4765,6 +4672,8 @@ start_server ()
walklist (variable_list, send_variable_proc, NULL);
}
+
+
#ifndef NO_EXT_METHOD
/* Contact the server by starting it with rsh. */
@@ -4901,8 +4810,8 @@ start_rsh_server (root, to_server, from_server)
sprintf (command, "%s server", cvs_server);
{
- char *argv[10];
- char **p = argv;
+ const char *argv[10];
+ const char **p = argv;
*p++ = cvs_rsh;
*p++ = root->hostname;
@@ -4969,8 +4878,10 @@ send_arg (string)
}
send_to_server ("\012", 1);
}
-
-static void send_modified PROTO ((char *, char *, Vers_TS *));
+
+
+
+static void send_modified PROTO ((const char *, const char *, Vers_TS *));
/* VERS->OPTIONS specifies whether the file is binary or not. NOTE: BEFORE
using any other fields of the struct vers, we would need to fix
@@ -4978,8 +4889,8 @@ static void send_modified PROTO ((char *, char *, Vers_TS *));
static void
send_modified (file, short_pathname, vers)
- char *file;
- char *short_pathname;
+ const char *file;
+ const char *short_pathname;
Vers_TS *vers;
{
/* File was modified, send it. */
@@ -5145,7 +5056,7 @@ send_fileproc (callerdat, finfo)
struct file_info xfinfo;
/* File name to actually use. Might differ in case from
finfo->file. */
- char *filename;
+ const char *filename;
send_a_repository ("", finfo->repository, finfo->update_dir);
@@ -5286,12 +5197,14 @@ warning: ignoring -k options due to server limitations");
return 0;
}
-static void send_ignproc PROTO ((char *, char *));
+
+
+static void send_ignproc PROTO ((const char *, const char *));
static void
send_ignproc (file, dir)
- char *file;
- char *dir;
+ const char *file;
+ const char *dir;
{
if (ign_inhibit_server || !supported_request ("Questionable"))
{
@@ -5308,14 +5221,17 @@ send_ignproc (file, dir)
}
}
-static int send_filesdoneproc PROTO ((void *, int, char *, char *, List *));
+
+
+static int send_filesdoneproc PROTO ((void *, int, const char *, const char *,
+ List *));
static int
send_filesdoneproc (callerdat, err, repository, update_dir, entries)
void *callerdat;
int err;
- char *repository;
- char *update_dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
/* if this directory has an ignore list, process it then free it */
@@ -5328,7 +5244,8 @@ send_filesdoneproc (callerdat, err, repository, update_dir, entries)
return (err);
}
-static Dtype send_dirent_proc PROTO ((void *, char *, char *, char *, List *));
+static Dtype send_dirent_proc PROTO ((void *, const char *, const char *,
+ const char *, List *));
/*
* send_dirent_proc () is called back by the recursion processor before a
@@ -5341,9 +5258,9 @@ static Dtype send_dirent_proc PROTO ((void *, char *, char *, char *, List *));
static Dtype
send_dirent_proc (callerdat, dir, repository, update_dir, entries)
void *callerdat;
- char *dir;
- char *repository;
- char *update_dir;
+ const char *dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
struct send_data *args = (struct send_data *) callerdat;
@@ -5413,7 +5330,10 @@ send_dirent_proc (callerdat, dir, repository, update_dir, entries)
return (dir_exists ? R_PROCESS : R_SKIP_ALL);
}
-static int send_dirleave_proc PROTO ((void *, char *, int, char *, List *));
+
+
+static int send_dirleave_proc PROTO ((void *, const char *, int, const char *,
+ List *));
/*
* send_dirleave_proc () is called back by the recursion code upon leaving
@@ -5424,9 +5344,9 @@ static int send_dirleave_proc PROTO ((void *, char *, int, char *, List *));
static int
send_dirleave_proc (callerdat, dir, err, update_dir, entries)
void *callerdat;
- char *dir;
+ const char *dir;
int err;
- char *update_dir;
+ const char *update_dir;
List *entries;
{
@@ -5470,8 +5390,8 @@ send_option_string (string)
}
-/* Send the names of all the argument files to the server. */
+/* Send the names of all the argument files to the server. */
void
send_file_names (argc, argv, flags)
int argc;
@@ -5479,89 +5399,116 @@ send_file_names (argc, argv, flags)
unsigned int flags;
{
int i;
- int level;
- int max_level;
/* The fact that we do this here as well as start_recursion is a bit
of a performance hit. Perhaps worth cleaning up someday. */
if (flags & SEND_EXPAND_WILD)
expand_wild (argc, argv, &argc, &argv);
- /* Send Max-dotdot if needed. */
- max_level = 0;
- for (i = 0; i < argc; ++i)
- {
- level = pathname_levels (argv[i]);
- if (level > max_level)
- max_level = level;
- }
- if (max_level > 0)
- {
- if (supported_request ("Max-dotdot"))
- {
- char buf[10];
- sprintf (buf, "%d", max_level);
-
- send_to_server ("Max-dotdot ", 0);
- send_to_server (buf, 0);
- send_to_server ("\012", 1);
- }
- else
- /*
- * "leading .." is not strictly correct, as this also includes
- * cases like "foo/../..". But trying to explain that in the
- * error message would probably just confuse users.
- */
- error (1, 0,
- "leading .. not supported by old (pre-Max-dotdot) servers");
- }
-
for (i = 0; i < argc; ++i)
{
char buf[1];
- char *p = argv[i];
- char *line = NULL;
+ char *p;
+#ifdef FILENAMES_CASE_INSENSITIVE
+ char *line = xmalloc (1);
+ *line = '\0';
+#endif /* FILENAMES_CASE_INSENSITIVE */
if (arg_should_not_be_sent_to_server (argv[i]))
continue;
#ifdef FILENAMES_CASE_INSENSITIVE
- /* We want to send the file name as it appears
- in CVS/Entries. We put this inside an ifdef
+ /* We want to send the path as it appears in the
+ CVS/Entries files. We put this inside an ifdef
to avoid doing all these system calls in
cases where fncmp is just strcmp anyway. */
- /* For now just do this for files in the local
- directory. Would be nice to handle the
- non-local case too, though. */
- /* The isdir check could more gracefully be replaced
+ /* The isdir (CVSADM) check could more gracefully be replaced
with a way of having Entries_Open report back the
error to us and letting us ignore existence_error.
Or some such. */
- if (p == last_component (p) && isdir (CVSADM))
{
- List *entries;
- Node *node;
-
- /* If we were doing non-local directory,
- we would save_cwd, CVS_CHDIR
- like in update.c:isemptydir. */
- /* Note that if we are adding a directory,
- the following will read the entry
- that we just wrote there, that is, we
- will get the case specified on the
- command line, not the case of the
- directory in the filesystem. This
- is correct behavior. */
- entries = Entries_Open (0, NULL);
- node = findnode_fn (entries, p);
- if (node != NULL)
+ List *stack;
+ size_t line_len = 0;
+ char *q, *r;
+ struct saved_cwd sdir;
+
+ /* Split the argument onto the stack. */
+ stack = getlist();
+ r = xstrdup (argv[i]);
+ /* It's okay to discard the const from the last_component return
+ * below since we know we passed in an arg that was not const.
+ */
+ while ((q = (char *)last_component (r)) != r)
{
- line = xstrdup (node->key);
- p = line;
- delnode (node);
+ push (stack, xstrdup (q));
+ *--q = '\0';
}
- Entries_Close (entries);
+ push (stack, r);
+
+ /* Normalize the path into outstr. */
+ save_cwd (&sdir);
+ while (q = pop (stack))
+ {
+ Node *node = NULL;
+ if (isdir (CVSADM))
+ {
+ List *entries;
+
+ /* Note that if we are adding a directory,
+ the following will read the entry
+ that we just wrote there, that is, we
+ will get the case specified on the
+ command line, not the case of the
+ directory in the filesystem. This
+ is correct behavior. */
+ entries = Entries_Open (0, NULL);
+ node = findnode_fn (entries, q);
+ if (node != NULL)
+ {
+ /* Add the slash unless this is our first element. */
+ if (line_len)
+ xrealloc_and_strcat (&line, &line_len, "/");
+ xrealloc_and_strcat (&line, &line_len, node->key);
+ delnode (node);
+ }
+ Entries_Close (entries);
+ }
+
+ /* If node is still NULL then we either didn't find CVSADM or
+ * we didn't find an entry there.
+ */
+ if (node == NULL)
+ {
+ /* Add the slash unless this is our first element. */
+ if (line_len)
+ xrealloc_and_strcat (&line, &line_len, "/");
+ xrealloc_and_strcat (&line, &line_len, q);
+ break;
+ }
+
+ /* And descend the tree. */
+ if (isdir (q))
+ CVS_CHDIR (q);
+ free (q);
+ }
+ restore_cwd (&sdir, NULL);
+ free_cwd (&sdir);
+
+ /* Now put everything we didn't find entries for back on. */
+ while (q = pop (stack))
+ {
+ if (line_len)
+ xrealloc_and_strcat (&line, &line_len, "/");
+ xrealloc_and_strcat (&line, &line_len, q);
+ free (q);
+ }
+
+ p = line;
+
+ dellist (&stack);
}
+#else /* !FILENAMES_CASE_INSENSITIVE */
+ p = argv[i];
#endif /* FILENAMES_CASE_INSENSITIVE */
send_to_server ("Argument ", 0);
@@ -5585,8 +5532,9 @@ send_file_names (argc, argv, flags)
++p;
}
send_to_server ("\012", 1);
- if (line != NULL)
- free (line);
+#ifdef FILENAMES_CASE_INSENSITIVE
+ free (line);
+#endif /* FILENAMES_CASE_INSENSITIVE */
}
if (flags & SEND_EXPAND_WILD)
@@ -5599,6 +5547,51 @@ send_file_names (argc, argv, flags)
}
+
+/* Calculate and send max-dotdot to the server */
+static void
+send_max_dotdot (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ int level = 0;
+ int max_level = 0;
+
+ /* Send Max-dotdot if needed. */
+ for (i = 0; i < argc; ++i)
+ {
+ level = pathname_levels (argv[i]);
+ if (level > 0)
+ {
+ if (uppaths == NULL) uppaths = getlist();
+ push_string (uppaths, xstrdup (argv[i]));
+ }
+ if (level > max_level)
+ max_level = level;
+ }
+
+ if (max_level > 0)
+ {
+ if (supported_request ("Max-dotdot"))
+ {
+ char buf[10];
+ sprintf (buf, "%d", max_level);
+
+ send_to_server ("Max-dotdot ", 0);
+ send_to_server (buf, 0);
+ send_to_server ("\012", 1);
+ }
+ else
+ {
+ error (1, 0,
+"backreference in path (`..') not supported by old (pre-Max-dotdot) servers");
+ }
+ }
+}
+
+
+
/* Send Repository, Modified and Entry. argc and argv contain only
the files to operate on (or empty for everything), not options.
local is nonzero if we should not recurse (-l option). flags &
@@ -5619,6 +5612,8 @@ send_files (argc, argv, local, aflag, flags)
struct send_data args;
int err;
+ send_max_dotdot (argc, argv);
+
/*
* aflag controls whether the tag/date is copied into the vers_ts.
* But we don't actually use it, so I don't think it matters what we pass
@@ -5631,7 +5626,8 @@ send_files (argc, argv, local, aflag, flags)
err = start_recursion
(send_fileproc, send_filesdoneproc,
send_dirent_proc, send_dirleave_proc, (void *) &args,
- argc, argv, local, W_LOCAL, aflag, CVS_LOCK_NONE, (char *)NULL, 0);
+ argc, argv, local, W_LOCAL, aflag, CVS_LOCK_NONE, (char *) NULL, 0,
+ (char *) NULL);
if (err)
error_exit ();
if (toplevel_repos == NULL)
@@ -5764,7 +5760,9 @@ client_import_done ()
toplevel_repos = xstrdup (current_parsed_root->directory);
send_repository ("", toplevel_repos, ".");
}
-
+
+
+
static void
notified_a_file (data, ent_list, short_pathname, filename)
char *data;
@@ -5883,11 +5881,11 @@ handle_notified (args, len)
void
client_notify (repository, update_dir, filename, notif_type, val)
- char *repository;
- char *update_dir;
- char *filename;
+ const char *repository;
+ const char *update_dir;
+ const char *filename;
int notif_type;
- char *val;
+ const char *val;
{
char buf[2];
diff --git a/contrib/cvs/src/client.h b/contrib/cvs/src/client.h
index d7f3392..cdc880e 100644
--- a/contrib/cvs/src/client.h
+++ b/contrib/cvs/src/client.h
@@ -60,6 +60,8 @@ extern int client_prune_dirs;
# ifdef AUTH_CLIENT_SUPPORT
extern int use_authenticating_server;
+# endif /* AUTH_CLIENT_SUPPORT */
+# if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI)
void connect_to_pserver PROTO ((cvsroot_t *,
struct buffer **,
struct buffer **,
@@ -67,7 +69,7 @@ void connect_to_pserver PROTO ((cvsroot_t *,
# ifndef CVS_AUTH_PORT
# define CVS_AUTH_PORT 2401
# endif /* CVS_AUTH_PORT */
-# endif /* AUTH_CLIENT_SUPPORT */
+# endif /* (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) */
# if HAVE_KERBEROS
# ifndef CVS_PORT
@@ -75,16 +77,8 @@ void connect_to_pserver PROTO ((cvsroot_t *,
# endif
# endif /* HAVE_KERBEROS */
-# if defined (AUTH_SERVER_SUPPORT) || (defined (SERVER_SUPPORT) && defined (HAVE_GSSAPI))
-extern void pserver_authenticate_connection PROTO ((void));
-# endif
-
-# if defined (SERVER_SUPPORT) && defined (HAVE_KERBEROS)
-extern void kserver_authenticate_connection PROTO ((void));
-# endif
-
/* Talking to the server. */
-void send_to_server PROTO((char *str, size_t len));
+void send_to_server PROTO((const char *str, size_t len));
void read_from_server PROTO((char *buf, size_t len));
/* Internal functions that handle client communication to server, etc. */
@@ -131,7 +125,8 @@ send_arg PROTO((char *string));
void
send_option_string PROTO((char *string));
-extern void send_a_repository PROTO ((char *, char *, char *));
+extern void send_a_repository PROTO ((const char *, const char *,
+ const char *));
#endif /* CLIENT_SUPPORT */
@@ -209,5 +204,6 @@ extern int client_process_import_file
int targc, char *targv[], char *repository, int all_files_binary,
int modtime));
extern void client_import_done PROTO((void));
-extern void client_notify PROTO((char *, char *, char *, int, char *));
+extern void client_notify PROTO((const char *, const char *, const char *, int,
+ const char *));
#endif /* CLIENT_SUPPORT */
diff --git a/contrib/cvs/src/commit.c b/contrib/cvs/src/commit.c
index 0d19d31..1548045 100644
--- a/contrib/cvs/src/commit.c
+++ b/contrib/cvs/src/commit.c
@@ -21,40 +21,44 @@
#include "fileattr.h"
#include "hardlink.h"
-static Dtype check_direntproc PROTO ((void *callerdat, char *dir,
- char *repos, char *update_dir,
- List *entries));
+static Dtype check_direntproc PROTO ((void *callerdat, const char *dir,
+ const char *repos,
+ const char *update_dir,
+ List *entries));
static int check_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static int check_filesdoneproc PROTO ((void *callerdat, int err,
- char *repos, char *update_dir,
- List *entries));
-static int checkaddfile PROTO((char *file, char *repository, char *tag,
- char *options, RCSNode **rcsnode));
-static Dtype commit_direntproc PROTO ((void *callerdat, char *dir,
- char *repos, char *update_dir,
- List *entries));
-static int commit_dirleaveproc PROTO ((void *callerdat, char *dir,
- int err, char *update_dir,
- List *entries));
+ const char *repos,
+ const char *update_dir,
+ List *entries));
+static int checkaddfile PROTO((const char *file, const char *repository,
+ const char *tag, const char *options,
+ RCSNode **rcsnode));
+static Dtype commit_direntproc PROTO ((void *callerdat, const char *dir,
+ const char *repos,
+ const char *update_dir,
+ List *entries));
+static int commit_dirleaveproc PROTO ((void *callerdat, const char *dir,
+ int err, const char *update_dir,
+ List *entries));
static int commit_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static int commit_filesdoneproc PROTO ((void *callerdat, int err,
- char *repository, char *update_dir,
- List *entries));
+ const char *repository,
+ const char *update_dir,
+ List *entries));
static int finaladd PROTO((struct file_info *finfo, char *revision, char *tag,
char *options));
static int findmaxrev PROTO((Node * p, void *closure));
-static int lock_RCS PROTO((char *user, RCSNode *rcs, char *rev,
- char *repository));
+static int lock_RCS PROTO((const char *user, RCSNode *rcs, const char *rev,
+ const char *repository));
static int precommit_list_proc PROTO((Node * p, void *closure));
-static int precommit_proc PROTO((char *repository, char *filter));
+static int precommit_proc PROTO((const char *repository, const char *filter));
static int remove_file PROTO ((struct file_info *finfo, char *tag,
char *message));
-static void fixaddfile PROTO((char *file, char *repository));
+static void fixaddfile PROTO((const char *rcs));
static void fixbranch PROTO((RCSNode *, char *branch));
static void unlockrcs PROTO((RCSNode *rcs));
static void ci_delproc PROTO((Node *p));
static void masterlist_delproc PROTO((Node *p));
-static char *locate_rcs PROTO((char *file, char *repository));
struct commit_info
{
@@ -71,7 +75,6 @@ struct master_lists
static int force_ci = 0;
static int got_message;
-static int run_module_prog = 1;
static int aflag;
static char *saved_tag;
static char *write_dirtag;
@@ -84,8 +87,7 @@ static time_t last_register_time;
static const char *const commit_usage[] =
{
- "Usage: %s %s [-nRlf] [-m msg | -F logfile] [-r rev] files...\n",
- " -n Do not run the module program (if any).\n",
+ "Usage: %s %s [-Rlf] [-m msg | -F logfile] [-r rev] files...\n",
" -R Process directories recursively.\n",
" -l Local directory only (not recursive).\n",
" -f Force the file to be committed; disables recursion.\n",
@@ -124,23 +126,26 @@ struct find_data {
/* Only good within functions called from the filesdoneproc. Stores
the repository (pointer into storage managed by the recursion
processor. */
- char *repository;
+ const char *repository;
/* Non-zero if we should force the commit. This is enabled by
either -f or -r options, unlike force_ci which is just -f. */
int force;
};
-static Dtype find_dirent_proc PROTO ((void *callerdat, char *dir,
- char *repository, char *update_dir,
- List *entries));
+
+
+static Dtype find_dirent_proc PROTO ((void *callerdat, const char *dir,
+ const char *repository,
+ const char *update_dir,
+ List *entries));
static Dtype
find_dirent_proc (callerdat, dir, repository, update_dir, entries)
void *callerdat;
- char *dir;
- char *repository;
- char *update_dir;
+ const char *dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
struct find_data *find_data = (struct find_data *)callerdat;
@@ -164,16 +169,20 @@ find_dirent_proc (callerdat, dir, repository, update_dir, entries)
return R_PROCESS;
}
+
+
/* Here as a static until we get around to fixing ignore_files to pass
it along as an argument. */
static struct find_data *find_data_static;
-static void find_ignproc PROTO ((char *, char *));
+
+
+static void find_ignproc PROTO ((const char *, const char *));
static void
find_ignproc (file, dir)
- char *file;
- char *dir;
+ const char *file;
+ const char *dir;
{
struct question *p;
@@ -185,16 +194,19 @@ find_ignproc (file, dir)
find_data_static->questionables = p;
}
+
+
static int find_filesdoneproc PROTO ((void *callerdat, int err,
- char *repository, char *update_dir,
- List *entries));
+ const char *repository,
+ const char *update_dir,
+ List *entries));
static int
find_filesdoneproc (callerdat, err, repository, update_dir, entries)
void *callerdat;
int err;
- char *repository;
- char *update_dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
struct find_data *find_data = (struct find_data *)callerdat;
@@ -258,27 +270,43 @@ find_fileproc (callerdat, finfo)
freevers_ts (&vers);
return 1;
}
- if (vers->ts_user == NULL)
+ if (vers->vn_user[0] == '-')
+ {
+ if (vers->ts_user != NULL)
+ {
+ error (0, 0,
+ "`%s' should be removed and is still there (or is back"
+ " again)", finfo->fullname);
+ freevers_ts (&vers);
+ return 1;
+ }
+ /* else */
+ status = T_REMOVED;
+ }
+ else if (strcmp (vers->vn_user, "0") == 0)
{
- if (strcmp (vers->vn_user, "0") == 0)
+ if (vers->ts_user == NULL)
+ {
/* This happens when one has `cvs add'ed a file, but it no
longer exists in the working directory at commit time.
FIXME: What classify_file does in this case is print
"new-born %s has disappeared" and removes the entry.
We probably should do the same. */
- status = T_ADDED;
- else if (vers->vn_user[0] == '-')
- status = T_REMOVED;
- else
- {
- /* FIXME: What classify_file does in this case is print
- "%s was lost". We probably should do the same. */
- freevers_ts (&vers);
- return 0;
+ if (!really_quiet)
+ error (0, 0, "warning: new-born %s has disappeared",
+ finfo->fullname);
+ status = T_REMOVE_ENTRY;
}
+ else
+ status = T_ADDED;
+ }
+ else if (vers->ts_user == NULL)
+ {
+ /* FIXME: What classify_file does in this case is print
+ "%s was lost". We probably should do the same. */
+ freevers_ts (&vers);
+ return 0;
}
- else if (strcmp (vers->vn_user, "0") == 0)
- status = T_ADDED;
else if (vers->ts_rcs != NULL
&& (args->force || strcmp (vers->ts_user, vers->ts_rcs) != 0))
/* If we are forcing commits, pretend that the file is
@@ -304,7 +332,7 @@ find_fileproc (callerdat, finfo)
node->type = UPDATE;
node->delproc = update_delproc;
- node->data = (char *) data;
+ node->data = data;
(void)addnode (args->ulist, node);
++args->argc;
@@ -326,6 +354,11 @@ copy_ulist (node, data)
}
#endif /* CLIENT_SUPPORT */
+#ifdef SERVER_SUPPORT
+# define COMMIT_OPTIONS "+nlRm:fF:r:"
+#else /* !SERVER_SUPPORT */
+# define COMMIT_OPTIONS "+lRm:fF:r:"
+#endif /* SERVER_SUPPORT */
int
commit (argc, argv)
int argc;
@@ -364,13 +397,17 @@ commit (argc, argv)
#endif /* CVS_BADROOT */
optind = 0;
- while ((c = getopt (argc, argv, "+nlRm:fF:r:")) != -1)
+ while( ( c = getopt( argc, argv, COMMIT_OPTIONS ) ) != -1 )
{
switch (c)
{
+#ifdef SERVER_SUPPORT
case 'n':
- run_module_prog = 0;
+ /* Silently ignore -n for compatibility with old
+ * clients.
+ */
break;
+#endif /* SERVER_SUPPORT */
case 'm':
#ifdef FORCE_USE_EDITOR
use_editor = 1;
@@ -425,7 +462,8 @@ commit (argc, argv)
/* strip trailing dots and leading zeros */
while (*--p == '.') ;
p[1] = '\0';
- while (*saved_tag == '0') ++saved_tag;
+ while (saved_tag[0] == '0' && isdigit ((unsigned char) saved_tag[1]))
+ ++saved_tag;
}
/* some checks related to the "-F logfile" option */
@@ -462,7 +500,7 @@ commit (argc, argv)
find_dirent_proc, (DIRLEAVEPROC) NULL,
(void *)&find_args,
argc, argv, local, W_LOCAL, 0, CVS_LOCK_NONE,
- (char *)NULL, 0);
+ (char *) NULL, 0, (char *) NULL);
if (err)
error (1, 0, "correct above errors first!");
@@ -551,8 +589,6 @@ commit (argc, argv)
send_arg("-l");
if (force_ci)
send_arg("-f");
- if (!run_module_prog)
- send_arg("-n");
option_with_arg ("-r", saved_tag);
send_arg ("--");
@@ -643,7 +679,7 @@ commit (argc, argv)
err = start_recursion (check_fileproc, check_filesdoneproc,
check_direntproc, (DIRLEAVEPROC) NULL, NULL, argc,
argv, local, W_LOCAL, aflag, CVS_LOCK_NONE,
- (char *) NULL, 1);
+ (char *) NULL, 1, (char *) NULL);
if (err)
{
Lock_Cleanup ();
@@ -658,7 +694,7 @@ commit (argc, argv)
err = start_recursion (commit_fileproc, commit_filesdoneproc,
commit_direntproc, commit_dirleaveproc, NULL,
argc, argv, local, W_LOCAL, aflag, CVS_LOCK_NONE,
- (char *) NULL, 1);
+ (char *) NULL, 1, (char *) NULL);
/*
* Unlock all the dirs and clean up
@@ -778,7 +814,7 @@ check_fileproc (callerdat, finfo)
struct file_info *finfo;
{
Ctype status;
- char *xdir;
+ const char *xdir;
Node *p;
List *ulist, *cilist;
Vers_TS *vers;
@@ -832,7 +868,8 @@ check_fileproc (callerdat, finfo)
* - can't have a sticky date
* - can't have a sticky tag that is not a branch
* Also,
- * - if status is T_REMOVED, can't have a numeric tag
+ * - if status is T_REMOVED, file must not exist and its entry
+ * can't have a numeric sticky tag.
* - if status is T_ADDED, rcs file must not exist unless on
* a branch or head is dead
* - if status is T_ADDED, can't have a non-trunk numeric rev
@@ -862,29 +899,13 @@ check_fileproc (callerdat, finfo)
}
if (status == T_MODIFIED && !force_ci && vers->ts_conflict)
{
- char *filestamp;
- int retcode;
-
/*
* 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.
*/
-#ifdef SERVER_SUPPORT
- if (server_active)
- retcode = vers->ts_conflict[0] != '=';
- else {
- filestamp = time_stamp (finfo->file);
- retcode = strcmp (vers->ts_conflict, filestamp);
- free (filestamp);
- }
-#else
- filestamp = time_stamp (finfo->file);
- retcode = strcmp (vers->ts_conflict, filestamp);
- free (filestamp);
-#endif
- if (retcode == 0)
+ if ( file_has_conflict ( finfo, vers->ts_conflict ) )
{
error (0, 0,
"file `%s' had a conflict and has not been modified",
@@ -912,20 +933,30 @@ warning: file `%s' seems to still contain conflict indicators",
}
}
- if (status == T_REMOVED
- && vers->tag
- && isdigit ((unsigned char) *vers->tag))
+ if (status == T_REMOVED)
{
- /* Remove also tries to forbid this, but we should check
- here. I'm only _sure_ about somewhat obscure cases
- (hacking the Entries file, using an old version of
- CVS for the remove and a new one for the commit), but
- there might be other cases. */
- error (0, 0,
- "cannot remove file `%s' which has a numeric sticky tag of `%s'",
- finfo->fullname, vers->tag);
- freevers_ts (&vers);
- return (1);
+ if (vers->ts_user != NULL)
+ {
+ error (0, 0,
+ "`%s' should be removed and is still there (or is"
+ " back again)", finfo->fullname);
+ freevers_ts (&vers);
+ return 1;
+ }
+
+ if (vers->tag && isdigit ((unsigned char) *vers->tag))
+ {
+ /* Remove also tries to forbid this, but we should check
+ here. I'm only _sure_ about somewhat obscure cases
+ (hacking the Entries file, using an old version of
+ CVS for the remove and a new one for the commit), but
+ there might be other cases. */
+ error (0, 0,
+ "cannot remove file `%s' which has a numeric sticky"
+ " tag of `%s'", finfo->fullname, vers->tag);
+ freevers_ts (&vers);
+ return (1);
+ }
}
if (status == T_ADDED)
{
@@ -975,7 +1006,7 @@ warning: file `%s' seems to still contain conflict indicators",
xmalloc (sizeof (struct master_lists));
ml->ulist = ulist;
ml->cilist = cilist;
- p->data = (char *) ml;
+ p->data = ml;
p->delproc = masterlist_delproc;
(void) addnode (mulist, p);
}
@@ -991,7 +1022,7 @@ warning: file `%s' seems to still contain conflict indicators",
li->tag = xstrdup (vers->tag);
li->rev_old = xstrdup (vers->vn_rcs);
li->rev_new = NULL;
- p->data = (char *) li;
+ p->data = li;
(void) addnode (ulist, p);
p = getnode ();
@@ -1009,7 +1040,7 @@ warning: file `%s' seems to still contain conflict indicators",
ci->rev = (char *) NULL;
ci->tag = xstrdup (vers->tag);
ci->options = xstrdup(vers->options);
- p->data = (char *) ci;
+ p->data = ci;
(void) addnode (cilist, p);
#ifdef PRESERVE_PERMISSIONS_SUPPORT
@@ -1042,7 +1073,7 @@ warning: file `%s' seems to still contain conflict indicators",
hlinfo = (struct hardlink_info *)
xmalloc (sizeof (struct hardlink_info));
hlinfo->status = status;
- linkp->data = (char *) hlinfo;
+ linkp->data = hlinfo;
}
}
#endif
@@ -1063,6 +1094,8 @@ warning: file `%s' seems to still contain conflict indicators",
return (0);
}
+
+
/*
* By default, return the code that tells do_recursion to examine all
* directories
@@ -1071,9 +1104,9 @@ warning: file `%s' seems to still contain conflict indicators",
static Dtype
check_direntproc (callerdat, dir, repos, update_dir, entries)
void *callerdat;
- char *dir;
- char *repos;
- char *update_dir;
+ const char *dir;
+ const char *repos;
+ const char *update_dir;
List *entries;
{
if (!isdir (dir))
@@ -1093,9 +1126,7 @@ precommit_list_proc (p, closure)
Node *p;
void *closure;
{
- struct logfile_info *li;
-
- li = (struct logfile_info *) p->data;
+ struct logfile_info *li = p->data;
if (li->type == T_ADDED
|| li->type == T_MODIFIED
|| li->type == T_REMOVED)
@@ -1110,8 +1141,8 @@ precommit_list_proc (p, closure)
*/
static int
precommit_proc (repository, filter)
- char *repository;
- char *filter;
+ const char *repository;
+ const char *filter;
{
/* see if the filter is there, only if it's a full path */
if (isabsolute (filter))
@@ -1148,8 +1179,8 @@ static int
check_filesdoneproc (callerdat, err, repos, update_dir, entries)
void *callerdat;
int err;
- char *repos;
- char *update_dir;
+ const char *repos;
+ const char *update_dir;
List *entries;
{
int n;
@@ -1244,7 +1275,7 @@ commit_fileproc (callerdat, finfo)
if (p == NULL)
return (0);
- ci = (struct commit_info *) p->data;
+ ci = p->data;
if (ci->status == T_MODIFIED)
{
if (finfo->rcs == NULL)
@@ -1262,7 +1293,8 @@ commit_fileproc (callerdat, finfo)
if (checkaddfile (finfo->file, finfo->repository, ci->tag, ci->options,
&finfo->rcs) != 0)
{
- fixaddfile (finfo->file, finfo->repository);
+ if (finfo->rcs != NULL)
+ fixaddfile (finfo->rcs->path);
err = 1;
goto out;
}
@@ -1282,7 +1314,7 @@ commit_fileproc (callerdat, finfo)
if (ci->rev)
free (ci->rev);
ci->rev = RCS_whatbranch (finfo->rcs, ci->tag);
- err = Checkin ('A', finfo, finfo->rcs->path, ci->rev,
+ err = Checkin ('A', finfo, ci->rev,
ci->tag, ci->options, saved_message);
if (err != 0)
{
@@ -1327,8 +1359,7 @@ commit_fileproc (callerdat, finfo)
}
else if (ci->status == T_MODIFIED)
{
- err = Checkin ('M', finfo,
- finfo->rcs->path, ci->rev, ci->tag,
+ err = Checkin ('M', finfo, ci->rev, ci->tag,
ci->options, saved_message);
(void) time (&last_register_time);
@@ -1376,7 +1407,7 @@ out:
copy it into the log information (see logmsg.c
(logfile_write) for more details). We should only update
the version number for files that have been added or
- modified but not removed. Why? classify_file_internal
+ modified but not removed since classify_file_internal
will return the version number of a file even after it has
been removed from the archive, which is not the behavior we
want for our commitlog messages; we want the old version
@@ -1391,7 +1422,7 @@ out:
struct logfile_info *li;
(void) classify_file_internal (finfo, &vers);
- li = (struct logfile_info *) p->data;
+ li = p->data;
li->rev_new = xstrdup (vers->vn_rcs);
freevers_ts (&vers);
}
@@ -1411,8 +1442,8 @@ static int
commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
void *callerdat;
int err;
- char *repository;
- char *update_dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
Node *p;
@@ -1426,12 +1457,11 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
got_message = 0;
-
Update_Logfile (repository, saved_message, (FILE *) 0, ulist);
/* Build the administrative files if necessary. */
{
- char *p;
+ const char *p;
if (strncmp (current_parsed_root->directory, repository,
strlen (current_parsed_root->directory)) != 0)
@@ -1464,63 +1494,13 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
cvs_output (program_name, 0);
cvs_output (" ", 1);
- cvs_output (command_name, 0);
+ cvs_output (cvs_cmd_name, 0);
cvs_output (": Rebuilding administrative file database\n", 0);
mkmodules (admin_dir);
free (admin_dir);
}
}
- if (err == 0 && run_module_prog)
- {
- FILE *fp;
-
- if ((fp = CVS_FOPEN (CVSADM_CIPROG, "r")) != NULL)
- {
- char *line;
- int line_length;
- size_t line_chars_allocated;
- char *repos;
-
- line = NULL;
- line_chars_allocated = 0;
- line_length = getline (&line, &line_chars_allocated, fp);
- if (line_length > 0)
- {
- /* Remove any trailing newline. */
- if (line[line_length - 1] == '\n')
- line[--line_length] = '\0';
- repos = Name_Repository ((char *) NULL, update_dir);
- run_setup (line);
- run_arg (repos);
- cvs_output (program_name, 0);
- cvs_output (" ", 1);
- cvs_output (command_name, 0);
- cvs_output (": Executing '", 0);
- run_print (stdout);
- cvs_output ("'\n", 0);
- cvs_flushout ();
- (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- free (repos);
- }
- else
- {
- if (ferror (fp))
- error (0, errno, "warning: error reading %s",
- CVSADM_CIPROG);
- }
- if (line != NULL)
- free (line);
- if (fclose (fp) < 0)
- error (0, errno, "warning: cannot close %s", CVSADM_CIPROG);
- }
- else
- {
- if (! existence_error (errno))
- error (0, errno, "warning: cannot open %s", CVSADM_CIPROG);
- }
- }
-
return (err);
}
@@ -1531,9 +1511,9 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
static Dtype
commit_direntproc (callerdat, dir, repos, update_dir, entries)
void *callerdat;
- char *dir;
- char *repos;
- char *update_dir;
+ const char *dir;
+ const char *repos;
+ const char *update_dir;
List *entries;
{
Node *p;
@@ -1575,9 +1555,9 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries)
static int
commit_dirleaveproc (callerdat, dir, err, update_dir, entries)
void *callerdat;
- char *dir;
+ const char *dir;
int err;
- char *update_dir;
+ const char *update_dir;
List *entries;
{
/* update the per-directory tag info */
@@ -1604,15 +1584,14 @@ findmaxrev (p, closure)
void *closure;
{
int thisrev;
- Entnode *entdata;
+ Entnode *entdata = p->data;
- entdata = (Entnode *) p->data;
if (entdata->type != ENT_FILE)
- return (0);
+ return 0;
thisrev = atoi (entdata->version);
if (thisrev > maxrev)
maxrev = thisrev;
- return (0);
+ return 0;
}
/*
@@ -1657,11 +1636,11 @@ remove_file (finfo, tag, message)
error (0, retcode == -1 ? errno : 0,
"failed to remove tag `%s' from `%s'", tag,
finfo->fullname);
- return (1);
+ return 1;
}
RCS_rewrite (finfo->rcs, NULL, NULL);
Scratch_Entry (finfo->entries, finfo->file);
- return (0);
+ return 0;
}
/* we are removing the file from either the head or a branch */
@@ -1691,12 +1670,12 @@ remove_file (finfo, tag, message)
/* no revision exists on this branch. use the previous
revision but do not lock. */
corev = RCS_gettag (finfo->rcs, tag, 1, (int *) NULL);
- prev_rev = xstrdup(rev);
+ prev_rev = xstrdup (corev);
lockflag = 0;
} else
{
corev = xstrdup (rev);
- prev_rev = xstrdup(branchname);
+ prev_rev = xstrdup (branchname);
free (branchname);
}
@@ -1788,10 +1767,8 @@ finaladd (finfo, rev, tag, options)
char *options;
{
int ret;
- char *rcs;
- rcs = locate_rcs (finfo->file, finfo->repository);
- ret = Checkin ('A', finfo, rcs, rev, tag, options, saved_message);
+ ret = Checkin ('A', finfo, rev, tag, options, saved_message);
if (ret == 0)
{
char *tmp = xmalloc (strlen (finfo->file) + sizeof (CVSADM)
@@ -1802,11 +1779,10 @@ finaladd (finfo, rev, tag, options)
error (0, errno, "cannot remove %s", tmp);
free (tmp);
}
- else
- fixaddfile (finfo->file, finfo->repository);
+ else if (finfo->rcs != NULL)
+ fixaddfile (finfo->rcs->path);
(void) time (&last_register_time);
- free (rcs);
return (ret);
}
@@ -1827,19 +1803,22 @@ unlockrcs (rcs)
RCS_rewrite (rcs, NULL, NULL);
}
+
+
/*
* remove a partially added file. if we can parse it, leave it alone.
+ *
+ * FIXME: Every caller that calls this function can access finfo->rcs (the
+ * parsed RCSNode data), so we should be able to detect that the file needs
+ * to be removed without reparsing the file as we do below.
*/
static void
-fixaddfile (file, repository)
- char *file;
- char *repository;
+fixaddfile (rcs)
+ const char *rcs;
{
RCSNode *rcsfile;
- char *rcs;
int save_really_quiet;
- rcs = locate_rcs (file, repository);
save_really_quiet = really_quiet;
really_quiet = 1;
if ((rcsfile = RCS_parsercsfile (rcs)) == NULL)
@@ -1850,9 +1829,10 @@ fixaddfile (file, repository)
else
freercsnode (&rcsfile);
really_quiet = save_really_quiet;
- free (rcs);
}
+
+
/*
* put the branch back on an rcs file
*/
@@ -1876,25 +1856,46 @@ fixbranch (rcs, branch)
* do the initial part of a file add for the named file. if adding
* with a tag, put the file in the Attic and point the symbolic tag
* at the committed revision.
+ *
+ * INPUTS
+ * file The name of the file in the workspace.
+ * repository The repository directory to expect to find FILE,v in.
+ * tag The name or rev num of the branch being added to, if any.
+ * options Any RCS keyword expansion options specified by the user.
+ * rcsnode A pointer to the pre-parsed RCSNode for this file, if the file
+ * exists in the repository. If this is NULL, assume the file
+ * does not yet exist.
+ *
+ * RETURNS
+ * 0 on success.
+ * 1 on errors, after printing any appropriate error messages.
+ *
+ * ERRORS
+ * This function will return an error when any of the following functions do:
+ * add_rcs_file
+ * RCS_setattic
+ * lock_RCS
+ * RCS_checkin
+ * RCS_parse (called to verify the newly created archive file)
+ * RCS_settag
*/
static int
checkaddfile (file, repository, tag, options, rcsnode)
- char *file;
- char *repository;
- char *tag;
- char *options;
+ const char *file;
+ const char *repository;
+ const char *tag;
+ const char *options;
RCSNode **rcsnode;
{
- char *rcs;
+ RCSNode *rcs;
char *fname;
- mode_t omask;
- int retcode = 0;
- int newfile = 0;
- RCSNode *rcsfile = NULL;
- int retval;
+ int newfile = 0; /* Set to 1 if we created a new RCS archive. */
+ int retval = 1;
int adding_on_branch;
+ assert (rcsnode != NULL);
+
/* Callers expect to be able to use either "" or NULL to mean the
default keyword expansion. */
if (options != NULL && options[0] == '\0')
@@ -1906,103 +1907,49 @@ checkaddfile (file, repository, tag, options, rcsnode)
this. */
adding_on_branch = tag != NULL && !isdigit ((unsigned char) tag[0]);
- if (adding_on_branch)
- {
- rcs = xmalloc (strlen (repository) + strlen (file)
- + sizeof (RCSEXT) + sizeof (CVSATTIC) + 10);
- (void) sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
- if (! isreadable (rcs))
- {
- (void) sprintf(rcs, "%s/%s", repository, CVSATTIC);
- omask = umask (cvsumask);
- if (CVS_MKDIR (rcs, 0777) != 0 && errno != EEXIST)
- error (1, errno, "cannot make directory `%s'", rcs);;
- (void) umask (omask);
- (void) sprintf (rcs, "%s/%s/%s%s", repository, CVSATTIC, file,
- RCSEXT);
- }
- }
- else
- rcs = locate_rcs (file, repository);
-
- if (isreadable (rcs))
+ if (*rcsnode == NULL)
{
- /* file has existed in the past. Prepare to resurrect. */
- char *rev;
- char *oldexpand;
+ char *rcsname;
+ char *desc = NULL;
+ size_t descalloc = 0;
+ size_t desclen = 0;
+ const char *opt;
- if ((rcsfile = *rcsnode) == NULL)
+ if ( adding_on_branch )
{
- error (0, 0, "could not find parsed rcsfile %s", file);
- retval = 1;
- goto out;
- }
-
- oldexpand = RCS_getexpand (rcsfile);
- if ((oldexpand != NULL
- && options != NULL
- && strcmp (options + 2, oldexpand) != 0)
- || (oldexpand == NULL && options != NULL))
- {
- /* We tell the user about this, because it means that the
- old revisions will no longer retrieve the way that they
- used to. */
- error (0, 0, "changing keyword expansion mode to %s", options);
- RCS_setexpand (rcsfile, options + 2);
- }
-
- if (!adding_on_branch)
- {
- /* We are adding on the trunk, so move the file out of the
- Attic. */
- if (!(rcsfile->flags & INATTIC))
- {
- error (0, 0, "warning: expected %s to be in Attic",
- rcsfile->path);
- }
-
- sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
-
- /* Begin a critical section around the code that spans the
- first commit on the trunk of a file that's already been
- committed on a branch. */
- SIG_beginCrSect ();
-
- if (RCS_setattic (rcsfile, 0))
- {
- retval = 1;
- goto out;
- }
+ mode_t omask;
+ rcsname = xmalloc (strlen (repository)
+ + sizeof (CVSATTIC)
+ + strlen (file)
+ + sizeof (RCSEXT)
+ + 3);
+ (void) sprintf (rcsname, "%s/%s", repository, CVSATTIC);
+ omask = umask ( cvsumask );
+ if (CVS_MKDIR (rcsname, 0777 ) != 0 && errno != EEXIST)
+ error (1, errno, "cannot make directory `%s'", rcsname);
+ (void) umask ( omask );
+ (void) sprintf (rcsname,
+ "%s/%s/%s%s",
+ repository,
+ CVSATTIC,
+ file,
+ RCSEXT);
}
-
- rev = RCS_getversion (rcsfile, tag, NULL, 1, (int *) NULL);
- /* and lock it */
- if (lock_RCS (file, rcsfile, rev, repository))
+ else
{
- error (0, 0, "cannot lock `%s'.", rcs);
- if (rev != NULL)
- free (rev);
- retval = 1;
- goto out;
+ rcsname = xmalloc (strlen (repository)
+ + strlen (file)
+ + sizeof (RCSEXT)
+ + 2);
+ (void) sprintf (rcsname,
+ "%s/%s%s",
+ repository,
+ file,
+ RCSEXT);
}
- if (rev != NULL)
- free (rev);
- }
- else
- {
/* this is the first time we have ever seen this file; create
- an rcs file. */
-
- char *desc;
- size_t descalloc;
- size_t desclen;
-
- char *opt;
-
- desc = NULL;
- descalloc = 0;
- desclen = 0;
+ an RCS file. */
fname = xmalloc (strlen (file) + sizeof (CVSADM)
+ sizeof (CVSEXT_LOG) + 10);
(void) sprintf (fname, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
@@ -2036,25 +1983,79 @@ checkaddfile (file, repository, tag, options, rcsnode)
RCS_checkin indicate that this is a new file? Or does the
"RCS file" message serve some function?). */
cvs_output ("RCS file: ", 0);
- cvs_output (rcs, 0);
+ cvs_output (rcsname, 0);
cvs_output ("\ndone\n", 0);
- if (add_rcs_file (NULL, rcs, file, NULL, opt,
+ if (add_rcs_file (NULL, rcsname, file, NULL, opt,
NULL, NULL, 0, NULL,
desc, desclen, NULL) != 0)
{
- retval = 1;
+ if (rcsname != NULL)
+ free (rcsname);
goto out;
}
- rcsfile = RCS_parsercsfile (rcs);
+ rcs = RCS_parsercsfile (rcsname);
newfile = 1;
+ if (rcsname != NULL)
+ free (rcsname);
if (desc != NULL)
free (desc);
- if (rcsnode != NULL)
+ *rcsnode = rcs;
+ }
+ else
+ {
+ /* file has existed in the past. Prepare to resurrect. */
+ char *rev;
+ char *oldexpand;
+
+ rcs = *rcsnode;
+
+ oldexpand = RCS_getexpand (rcs);
+ if ((oldexpand != NULL
+ && options != NULL
+ && strcmp (options + 2, oldexpand) != 0)
+ || (oldexpand == NULL && options != NULL))
+ {
+ /* We tell the user about this, because it means that the
+ old revisions will no longer retrieve the way that they
+ used to. */
+ error (0, 0, "changing keyword expansion mode to %s", options);
+ RCS_setexpand (rcs, options + 2);
+ }
+
+ if (!adding_on_branch)
+ {
+ /* We are adding on the trunk, so move the file out of the
+ Attic. */
+ if (!(rcs->flags & INATTIC))
+ {
+ error (0, 0, "warning: expected %s to be in Attic",
+ rcs->path);
+ }
+
+ /* Begin a critical section around the code that spans the
+ first commit on the trunk of a file that's already been
+ committed on a branch. */
+ SIG_beginCrSect ();
+
+ if (RCS_setattic (rcs, 0))
+ {
+ goto out;
+ }
+ }
+
+ rev = RCS_getversion (rcs, tag, NULL, 1, (int *) NULL);
+ /* and lock it */
+ if (lock_RCS (file, rcs, rev, repository))
{
- assert (*rcsnode == NULL);
- *rcsnode = rcsfile;
+ error (0, 0, "cannot lock `%s'.", rcs->path);
+ if (rev != NULL)
+ free (rev);
+ goto out;
}
+
+ if (rev != NULL)
+ free (rev);
}
/* when adding a file for the first time, and using a tag, we need
@@ -2065,6 +2066,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
{
char *tmp;
FILE *fp;
+ int retcode;
/* move the new file out of the way. */
fname = xmalloc (strlen (file) + sizeof (CVSADM)
@@ -2084,14 +2086,13 @@ 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 (rcsfile, NULL, tmp, NULL,
+ retcode = RCS_checkin (rcs, NULL, tmp, NULL,
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);
- retval = 1;
+ "could not create initial dead revision %s", rcs->path);
goto out;
}
@@ -2100,56 +2101,39 @@ checkaddfile (file, repository, tag, options, rcsnode)
free (fname);
/* double-check that the file was written correctly */
- freercsnode (&rcsfile);
- rcsfile = RCS_parse (file, repository);
- if (rcsfile == NULL)
+ freercsnode (&rcs);
+ rcs = RCS_parse (file, repository);
+ if (rcs == NULL)
{
- error (0, 0, "could not read %s", rcs);
- retval = 1;
+ error (0, 0, "could not read %s", rcs->path);
goto out;
}
- if (rcsnode != NULL)
- *rcsnode = rcsfile;
+ *rcsnode = rcs;
/* and lock it once again. */
- if (lock_RCS (file, rcsfile, NULL, repository))
+ if (lock_RCS (file, rcs, NULL, repository))
{
- error (0, 0, "cannot lock `%s'.", rcs);
- retval = 1;
+ error (0, 0, "cannot lock `%s'.", rcs->path);
goto out;
}
}
/* when adding with a tag, we need to stub a branch, if it
doesn't already exist. */
-
- if (rcsfile == NULL)
- {
- if (rcsnode != NULL && *rcsnode != NULL)
- rcsfile = *rcsnode;
- else
- {
- rcsfile = RCS_parse (file, repository);
- if (rcsfile == NULL)
- {
- error (0, 0, "could not read %s", rcs);
- retval = 1;
- goto out;
- }
- }
- }
-
- if (!RCS_nodeisbranch (rcsfile, tag))
+ if (!RCS_nodeisbranch (rcs, tag))
{
/* branch does not exist. Stub it. */
char *head;
char *magicrev;
+ int retcode;
+
+ fixbranch (rcs, sbranch);
- head = RCS_getversion (rcsfile, NULL, NULL, 0, (int *) NULL);
- magicrev = RCS_magicrev (rcsfile, head);
+ head = RCS_getversion (rcs, NULL, NULL, 0, (int *) NULL);
+ magicrev = RCS_magicrev (rcs, head);
- retcode = RCS_settag (rcsfile, tag, magicrev);
- RCS_rewrite (rcsfile, NULL, NULL);
+ retcode = RCS_settag (rcs, tag, magicrev);
+ RCS_rewrite (rcs, NULL, NULL);
free (head);
free (magicrev);
@@ -2157,26 +2141,24 @@ checkaddfile (file, repository, tag, options, rcsnode)
if (retcode != 0)
{
error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "could not stub branch %s for %s", tag, rcs);
- retval = 1;
+ "could not stub branch %s for %s", tag, rcs->path);
goto out;
}
}
else
{
/* lock the branch. (stubbed branches need not be locked.) */
- if (lock_RCS (file, rcsfile, NULL, repository))
+ if (lock_RCS (file, rcs, NULL, repository))
{
- error (0, 0, "cannot lock `%s'.", rcs);
- retval = 1;
+ error (0, 0, "cannot lock `%s'.", rcs->path);
goto out;
}
}
- if (rcsnode && *rcsnode != rcsfile)
+ if (*rcsnode != rcs)
{
freercsnode(rcsnode);
- *rcsnode = rcsfile;
+ *rcsnode = rcs;
}
}
@@ -2204,7 +2186,6 @@ checkaddfile (file, repository, tag, options, rcsnode)
out:
if (retval != 0 && SIG_inCrSect ())
SIG_endCrSect ();
- free (rcs);
return retval;
}
@@ -2216,10 +2197,10 @@ checkaddfile (file, repository, tag, options, rcsnode)
*/
static int
lock_RCS (user, rcs, rev, repository)
- char *user;
+ const char *user;
RCSNode *rcs;
- char *rev;
- char *repository;
+ const char *rev;
+ const char *repository;
{
char *branch = NULL;
int err = 0;
@@ -2248,11 +2229,11 @@ lock_RCS (user, rcs, rev, repository)
return (1);
}
}
- err = RCS_lock(rcs, NULL, 1);
+ err = RCS_lock (rcs, NULL, 1);
}
else
{
- (void) RCS_lock(rcs, rev, 1);
+ RCS_lock (rcs, rev, 1);
}
/* We used to call RCS_rewrite here, and that might seem
@@ -2298,9 +2279,8 @@ void
update_delproc (p)
Node *p;
{
- struct logfile_info *li;
+ struct logfile_info *li = p->data;
- li = (struct logfile_info *) p->data;
if (li->tag)
free (li->tag);
if (li->rev_old)
@@ -2317,9 +2297,8 @@ static void
ci_delproc (p)
Node *p;
{
- struct commit_info *ci;
+ struct commit_info *ci = p->data;
- ci = (struct commit_info *) p->data;
if (ci->rev)
free (ci->rev);
if (ci->tag)
@@ -2336,37 +2315,9 @@ static void
masterlist_delproc (p)
Node *p;
{
- struct master_lists *ml;
+ struct master_lists *ml = p->data;
- ml = (struct master_lists *) p->data;
dellist (&ml->ulist);
dellist (&ml->cilist);
free (ml);
}
-
-/* Find an RCS file in the repository. Most parts of CVS will want to
- rely instead on RCS_parse which performs a similar operation and is
- called by recurse.c which then puts the result in useful places
- like the rcs field of struct file_info.
-
- REPOSITORY is the repository (including the directory) and FILE is
- the filename within that directory (without RCSEXT). Returns a
- newly-malloc'd array containing the absolute pathname of the RCS
- file that was found. */
-static char *
-locate_rcs (file, repository)
- char *file;
- char *repository;
-{
- char *rcs;
-
- rcs = xmalloc (strlen (repository) + strlen (file) + sizeof (RCSEXT) + 10);
- (void) sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
- if (!isreadable (rcs))
- {
- (void) sprintf (rcs, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
- if (!isreadable (rcs))
- (void) sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
- }
- return rcs;
-}
diff --git a/contrib/cvs/src/create_adm.c b/contrib/cvs/src/create_adm.c
index 779bd0d..bccb4a2 100644
--- a/contrib/cvs/src/create_adm.c
+++ b/contrib/cvs/src/create_adm.c
@@ -24,11 +24,11 @@
int
Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn,
dotemplate)
- char *dir;
- char *update_dir;
- char *repository;
- char *tag;
- char *date;
+ const char *dir;
+ const char *update_dir;
+ const char *repository;
+ const char *tag;
+ const char *date;
int nonbranch;
int warn;
int dotemplate;
diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h
index 9b8a8b4..42c08f5 100644
--- a/contrib/cvs/src/cvs.h
+++ b/contrib/cvs/src/cvs.h
@@ -84,6 +84,7 @@ extern int errno;
#include "system.h"
#include "hash.h"
+#include "stack.h"
#include "root.h"
@@ -127,8 +128,6 @@ extern int errno;
#define CVSADM_ENTSTAT "CVS/Entries.Static"
#define CVSADM_REP "CVS/Repository."
#define CVSADM_ROOT "CVS/Root."
-#define CVSADM_CIPROG "CVS/Checkin.prog"
-#define CVSADM_UPROG "CVS/Update.prog"
#define CVSADM_TAG "CVS/Tag."
#define CVSADM_NOTIFY "CVS/Notify."
#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
@@ -144,8 +143,6 @@ extern int errno;
#define CVSADM_ENTSTAT "CVS/Entries.Static"
#define CVSADM_REP "CVS/Repository"
#define CVSADM_ROOT "CVS/Root"
-#define CVSADM_CIPROG "CVS/Checkin.prog"
-#define CVSADM_UPROG "CVS/Update.prog"
#define CVSADM_TAG "CVS/Tag"
#define CVSADM_NOTIFY "CVS/Notify"
#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
@@ -363,7 +360,7 @@ typedef enum direnter_type Dtype;
#define CVS_LOCK_READ 1
#define CVS_LOCK_WRITE 2
-extern char *program_name, *program_path, *command_name;
+extern const char *program_name, *program_path, *cvs_cmd_name;
extern char *Tmpdir, *Editor;
extern int cvsadmin_root;
extern char *CurDir;
@@ -409,7 +406,8 @@ extern char hostname[];
/* Externs that are included directly in the CVS sources */
-int RCS_merge PROTO((RCSNode *, char *, char *, char *, char *, char *));
+int RCS_merge PROTO((RCSNode *, const char *, const char *, const char *,
+ const char *, const char *));
/* Flags used by RCS_* functions. See the description of the individual
functions for which flags mean what for each function. */
#define RCS_FLAGS_FORCE 1
@@ -419,14 +417,14 @@ int RCS_merge PROTO((RCSNode *, char *, char *, char *, char *, char *));
#define RCS_FLAGS_KEEPFILE 16
extern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile,
- char *opts, char *options,
- char *rev1, char *rev2,
- char *label1, char *label2,
- char *workfile));
-extern int diff_exec PROTO ((char *file1, char *file2,
- char *label1, char *label2,
- char *options, char *out));
-
+ const char *opts, 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));
+
#include "error.h"
@@ -445,34 +443,36 @@ void date_to_internet PROTO ((char *, const char *));
void date_to_tm PROTO ((struct tm *, const char *));
void tm_to_internet PROTO ((char *, const struct tm *));
-char *Name_Repository PROTO((char *dir, char *update_dir));
-char *Short_Repository PROTO((char *repository));
+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((char *root));
-cvsroot_t *local_cvsroot PROTO((char *dir));
-void Create_Root PROTO((char *dir, char *rootdir));
+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 *gca PROTO((const char *rev1, const char *rev2));
+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 **));
-char *getcaller PROTO((void));
-char *time_stamp PROTO((char *file));
+char *getcaller PROTO ((void));
+char *time_stamp PROTO ((const char *file));
void *xmalloc PROTO((size_t bytes));
void *xrealloc PROTO((void *ptr, size_t bytes));
void expand_string PROTO ((char **, size_t *, size_t));
void xrealloc_and_strcat PROTO ((char **, size_t *, const char *));
char *xstrdup PROTO((const char *str));
-void strip_trailing_newlines PROTO((char *str));
-int pathname_levels PROTO ((char *path));
+int strip_trailing_newlines PROTO((char *str));
+int pathname_levels PROTO ((const char *path));
-typedef int (*CALLPROC) PROTO((char *repository, char *value));
-int Parse_Info PROTO((char *infofile, char *repository, CALLPROC callproc, int all));
+typedef int (*CALLPROC) PROTO((const char *repository, const char *value));
+int Parse_Info PROTO((const char *infofile, const char *repository,
+ CALLPROC callproc, int all));
extern int parse_config PROTO ((char *));
typedef RETSIGTYPE (*SIGCLEANUPPROC) PROTO(());
@@ -485,8 +485,11 @@ int isreadable PROTO((const char *file));
int iswritable PROTO((const char *file));
int isaccessible PROTO((const char *file, const int mode));
int isabsolute PROTO((const char *filename));
+#ifdef HAVE_READLINK
char *xreadlink PROTO((const char *link));
-char *last_component PROTO((char *path));
+#endif
+char *xresolvepath PROTO((const char *path));
+const char *last_component PROTO((const char *path));
char *get_homedir PROTO ((void));
char *strcat_filename_onto_homedir PROTO ((const char *, const char *));
char *cvs_temp_name PROTO ((void));
@@ -497,16 +500,57 @@ char *increment_revnum PROTO ((const char *));
int compare_revnums PROTO ((const char *, const char *));
int unlink_file PROTO((const char *f));
int unlink_file_dir PROTO((const char *f));
+
+
+
+/* This is the structure that the recursion processor passes to the
+ fileproc to tell it about a particular file. */
+struct file_info
+{
+ /* Name of the file, without any directory component. */
+ const char *file;
+
+ /* Name of the directory we are in, relative to the directory in
+ which this command was issued. We have cd'd to this directory
+ (either in the working directory or in the repository, depending
+ on which sort of recursion we are doing). If we are in the directory
+ in which the command was issued, this is "". */
+ const char *update_dir;
+
+ /* update_dir and file put together, with a slash between them as
+ necessary. This is the proper way to refer to the file in user
+ messages. */
+ const char *fullname;
+
+ /* Name of the directory corresponding to the repository which contains
+ this file. */
+ const char *repository;
+
+ /* The pre-parsed entries for this directory. */
+ List *entries;
+
+ RCSNode *rcs;
+};
+
+
+
int update PROTO((int argc, char *argv[]));
+/* The only place this is currently used outside of update.c is add.c.
+ * Restricting its use to update.c seems to be in the best interest of
+ * modularity, but I can't think of a good way to get an update of a
+ * resurrected file done and print the fact otherwise.
+ */
+void write_letter PROTO ((struct file_info *finfo, int letter));
int xcmp PROTO((const char *file1, const char *file2));
int yesno PROTO((void));
void *valloc PROTO((size_t bytes));
time_t get_date PROTO((char *date, struct timeb *now));
-extern int Create_Admin PROTO ((char *dir, char *update_dir,
- char *repository, char *tag, char *date,
- int nonbranch, int warn, int dotemplate));
-extern int expand_at_signs PROTO ((char *, off_t, FILE *));
-
+extern int Create_Admin PROTO ((const char *dir, const char *update_dir,
+ const char *repository, const char *tag,
+ const char *date,
+ int nonbranch, int warn, int dotemplate));
+extern int expand_at_signs PROTO ((const char *, off_t, FILE *));
+
/* Locking subsystem (implemented in lock.c). */
int Reader_Lock PROTO((char *xrepository));
@@ -522,11 +566,12 @@ extern void lock_dir_for_write PROTO ((char *));
/* LockDir setting from CVSROOT/config. */
extern char *lock_dir;
-
-void Scratch_Entry PROTO((List * list, char *fname));
+
+void Scratch_Entry PROTO((List * list, const char *fname));
void ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
-void WriteTag PROTO ((char *dir, char *tag, char *date, int nonbranch,
- char *update_dir, char *repository));
+void WriteTag PROTO ((const char *dir, const char *tag, const char *date,
+ int nonbranch, const char *update_dir,
+ const char *repository));
void cat_module PROTO((int status));
void check_entries PROTO((char *dir));
void close_module PROTO((DBM * db));
@@ -539,18 +584,17 @@ void ign_add PROTO((char *ign, int hold));
void ign_add_file PROTO((char *file, int hold));
void ign_setup PROTO((void));
void ign_dir_add PROTO((char *name));
-int ignore_directory PROTO((char *name));
-typedef void (*Ignore_proc) PROTO ((char *, char *));
-extern void ignore_files PROTO ((List *, List *, char *, Ignore_proc));
+int ignore_directory PROTO((const char *name));
+typedef void (*Ignore_proc) PROTO ((const char *, const char *));
+extern void ignore_files PROTO ((List *, List *, const char *, Ignore_proc));
extern int ign_inhibit_server;
-extern int ign_case;
#include "update.h"
void line2argv PROTO ((int *pargc, char ***argv, char *line, char *sepchars));
void make_directories PROTO((const char *name));
void make_directory PROTO((const char *name));
-extern int mkdir_if_needed PROTO ((char *name));
+extern int mkdir_if_needed PROTO ((const char *name));
void rename_file PROTO((const char *from, const char *to));
/* Expand wildcards in each element of (ARGC,ARGV). This is according to the
files which exist in the current directory, and accordingly to OS-specific
@@ -563,68 +607,41 @@ extern void expand_wild PROTO ((int argc, char **argv,
int *pargc, char ***pargv));
#ifdef SERVER_SUPPORT
-extern int cvs_casecmp PROTO ((char *, char *));
+extern int cvs_casecmp PROTO ((const char *, const char *));
extern int fopen_case PROTO ((char *, char *, FILE **, char **));
#endif
void strip_trailing_slashes PROTO((char *path));
void update_delproc PROTO((Node * p));
void usage PROTO((const char *const *cpp));
-void xchmod PROTO((char *fname, int writable));
+void xchmod PROTO((const char *fname, int writable));
char *xgetwd PROTO((void));
List *Find_Names PROTO((char *repository, int which, int aflag,
- List ** optentries));
-void Register PROTO((List * list, char *fname, char *vn, char *ts,
- char *options, char *tag, char *date, char *ts_conflict));
-void Update_Logfile PROTO((char *repository, char *xmessage, FILE * xlogfp,
- List * xchanges));
-void do_editor PROTO((char *dir, char **messagep,
- char *repository, List * changes));
+ List **optentries));
+void Register PROTO((List * list, const char *fname, const char *vn,
+ const char *ts, const char *options, const char *tag,
+ const char *date, const char *ts_conflict));
+void Update_Logfile PROTO((const char *repository, const char *xmessage,
+ FILE * xlogfp, List * xchanges));
+void do_editor PROTO((const char *dir, char **messagep,
+ const char *repository, List * changes));
-void do_verify PROTO((char **messagep, char *repository));
+void do_verify PROTO((char **messagep, const char *repository));
typedef int (*CALLBACKPROC) PROTO((int argc, char *argv[], char *where,
char *mwhere, char *mfile, int shorten, int local_specified,
char *omodule, char *msg));
-/* This is the structure that the recursion processor passes to the
- fileproc to tell it about a particular file. */
-struct file_info
-{
- /* Name of the file, without any directory component. */
- char *file;
-
- /* Name of the directory we are in, relative to the directory in
- which this command was issued. We have cd'd to this directory
- (either in the working directory or in the repository, depending
- on which sort of recursion we are doing). If we are in the directory
- in which the command was issued, this is "". */
- char *update_dir;
-
- /* update_dir and file put together, with a slash between them as
- necessary. This is the proper way to refer to the file in user
- messages. */
- char *fullname;
-
- /* Name of the directory corresponding to the repository which contains
- this file. */
- char *repository;
-
- /* The pre-parsed entries for this directory. */
- List *entries;
-
- RCSNode *rcs;
-};
-
typedef int (*FILEPROC) PROTO ((void *callerdat, struct file_info *finfo));
typedef int (*FILESDONEPROC) PROTO ((void *callerdat, int err,
- char *repository, char *update_dir,
- List *entries));
-typedef Dtype (*DIRENTPROC) PROTO ((void *callerdat, char *dir,
- char *repos, char *update_dir,
+ const char *repository,
+ const char *update_dir,
+ List *entries));
+typedef Dtype (*DIRENTPROC) PROTO ((void *callerdat, const char *dir,
+ const char *repos, const char *update_dir,
List *entries));
-typedef int (*DIRLEAVEPROC) PROTO ((void *callerdat, char *dir, int err,
- char *update_dir, List *entries));
+typedef int (*DIRLEAVEPROC) PROTO ((void *callerdat, const char *dir, int err,
+ const char *update_dir, List *entries));
extern int mkmodules PROTO ((char *dir));
extern int init PROTO ((int argc, char **argv));
@@ -633,20 +650,22 @@ int do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg,
CALLBACKPROC callback_proc, char *where, int shorten,
int local_specified, int run_module_prog, int build_dirs,
char *extra_arg));
-void history_write PROTO((int type, char *update_dir, char *revs, char *name,
- char *repository));
+void history_write PROTO((int type, const char *update_dir, const char *revs,
+ const char *name, const char *repository));
int start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
void *callerdat,
int argc, char *argv[], int local, int which,
int aflag, int locktype, char *update_preload,
- int dosrcs));
+ int dosrcs, char *repository));
void SIG_beginCrSect PROTO((void));
void SIG_endCrSect PROTO((void));
int SIG_inCrSect PROTO((void));
-void read_cvsrc PROTO((int *argc, char ***argv, char *cmdname));
+void read_cvsrc PROTO((int *argc, char ***argv, const char *cmdname));
-char *make_message_rcslegal PROTO((char *message));
+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 *));
@@ -656,13 +675,13 @@ extern void resolve_symlink PROTO ((char **filename));
void sleep_past PROTO ((time_t desttime));
/* flags for run_exec(), the fast system() for CVS */
-#define RUN_NORMAL 0x0000 /* no special behaviour */
-#define RUN_COMBINED 0x0001 /* stdout is duped to stderr */
-#define RUN_REALLY 0x0002 /* do the exec, even if noexec is on */
-#define RUN_STDOUT_APPEND 0x0004 /* append to stdout, don't truncate */
-#define RUN_STDERR_APPEND 0x0008 /* append to stderr, don't truncate */
-#define RUN_SIGIGNORE 0x0010 /* ignore interrupts for command */
-#define RUN_TTY (char *)0 /* for the benefit of lint */
+#define RUN_NORMAL 0x0000 /* no special behaviour */
+#define RUN_COMBINED 0x0001 /* stdout is duped to stderr */
+#define RUN_REALLY 0x0002 /* do the exec, even if noexec is on */
+#define RUN_STDOUT_APPEND 0x0004 /* append to stdout, don't truncate */
+#define RUN_STDERR_APPEND 0x0008 /* append to stderr, don't truncate */
+#define RUN_SIGIGNORE 0x0010 /* ignore interrupts for command */
+#define RUN_TTY (char *)0 /* for the benefit of lint */
void run_arg PROTO((const char *s));
void run_print PROTO((FILE * fp));
@@ -672,7 +691,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((char **, int *, int *));
+int piped_child PROTO((const char **, int *, int *));
void close_on_exec PROTO((int));
pid_t waitpid PROTO((pid_t, int *, int));
@@ -755,7 +774,7 @@ void freevers_ts PROTO ((Vers_TS ** versp));
/* Miscellaneous CVS infrastructure which layers on top of the recursion
processor (for example, needs struct file_info). */
-int Checkin PROTO ((int type, struct file_info *finfo, char *rcs, char *rev,
+int Checkin PROTO ((int type, struct file_info *finfo, char *rev,
char *tag, char *options, char *message));
int No_Difference PROTO ((struct file_info *finfo, Vers_TS *vers));
/* TODO: can the finfo argument to special_file_mismatch be changed? -twp */
@@ -829,15 +848,15 @@ void wrap_send PROTO ((void));
#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
void wrap_unparse_rcs_options PROTO ((char **, int));
#endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
-
+
/* Pathname expansion */
-char *expand_path PROTO((char *name, char *file, int line));
+char *expand_path PROTO((const char *name, const char *file, int line));
/* User variables. */
extern List *variable_list;
extern void variable_set PROTO ((char *nameval));
-
+
int watch PROTO ((int argc, char **argv));
int edit PROTO ((int argc, char **argv));
int unedit PROTO ((int argc, char **argv));
@@ -898,4 +917,4 @@ extern void cvs_output_binary PROTO ((char *, size_t));
extern void cvs_outerr PROTO ((const char *, size_t));
extern void cvs_flusherr PROTO ((void));
extern void cvs_flushout PROTO ((void));
-extern void cvs_output_tagged PROTO ((char *, char *));
+extern void cvs_output_tagged PROTO ((const char *, const char *));
diff --git a/contrib/cvs/src/cvsbug.in b/contrib/cvs/src/cvsbug.in
index db46f6e..efc156d 100755
--- a/contrib/cvs/src/cvsbug.in
+++ b/contrib/cvs/src/cvsbug.in
@@ -48,16 +48,17 @@ DEFAULT_ORGANIZATION="net"
## # Newer config information?
## [ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config
+# Hack mktemp on systems that don't have it.
+@MKTEMP_SH_FUNCTION@
+MKTEMP="@MKTEMP@"
+
# What mailer to use. This must come after the config file, since it is
# host-dependent.
-if [ -f /usr/sbin/sendmail ]; then
- MAIL_AGENT="/usr/sbin/sendmail -oi -t"
-else
- MAIL_AGENT="/usr/lib/sendmail -oi -t"
-fi
+SENDMAIL="@SENDMAIL@"
+MAIL_AGENT="$SENDMAIL -oi -t"
MAILER=`echo $MAIL_AGENT | sed -e 's, .*,,'`
if [ ! -f "$MAILER" ] ; then
- echo "$COMMAND: Cannot file mail program \"$MAILER\"."
+ echo "$COMMAND: Cannot find mail program \"$MAILER\"."
echo "$COMMAND: Please fix the MAIL_AGENT entry in the $COMMAND file."
exit 1
fi
@@ -85,9 +86,9 @@ fi
[ -z "$TMPDIR" ] && TMPDIR=/tmp
-TEMP=$TMPDIR/p$$
-BAD=$TMPDIR/pbad$$
-REF=$TMPDIR/pf$$
+TEMP="`$MKTEMP $TMPDIR/p.XXXXXX`"
+BAD="`$MKTEMP $TMPDIR/pbad.XXXXXX`"
+REF="`$MKTEMP $TMPDIR/pf.XXXXXX`"
if [ -z "$LOGNAME" -a -n "$USER" ]; then
LOGNAME=$USER
diff --git a/contrib/cvs/src/cvsrc.c b/contrib/cvs/src/cvsrc.c
index 5c870ce..9aed694 100644
--- a/contrib/cvs/src/cvsrc.c
+++ b/contrib/cvs/src/cvsrc.c
@@ -30,7 +30,7 @@ void
read_cvsrc (argc, argv, cmdname)
int *argc;
char ***argv;
- char *cmdname;
+ const char *cmdname;
{
char *homedir;
char *homeinit;
diff --git a/contrib/cvs/src/diff.c b/contrib/cvs/src/diff.c
index 88af651..2e7aea2 100644
--- a/contrib/cvs/src/diff.c
+++ b/contrib/cvs/src/diff.c
@@ -14,6 +14,7 @@
* files.
*/
+#include <assert.h>
#include "cvs.h"
enum diff_file
@@ -25,18 +26,21 @@ enum diff_file
DIFF_SAME
};
-static Dtype diff_dirproc PROTO ((void *callerdat, char *dir,
- char *pos_repos, char *update_dir,
- List *entries));
+static Dtype diff_dirproc PROTO ((void *callerdat, const char *dir,
+ const char *pos_repos,
+ const char *update_dir,
+ List *entries));
static int diff_filesdoneproc PROTO ((void *callerdat, int err,
- char *repos, char *update_dir,
- List *entries));
-static int diff_dirleaveproc PROTO ((void *callerdat, char *dir,
- int err, char *update_dir,
- List *entries));
-static enum diff_file diff_file_nodiff PROTO ((struct file_info *finfo,
+ const char *repos,
+ const char *update_dir,
+ List *entries));
+static int diff_dirleaveproc PROTO ((void *callerdat, const char *dir,
+ int err, const char *update_dir,
+ List *entries));
+static enum diff_file diff_file_nodiff PROTO(( struct file_info *finfo,
Vers_TS *vers,
- enum diff_file));
+ enum diff_file,
+ char **rev1_cache ));
static int diff_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static void diff_mark_errors PROTO((int err));
@@ -270,6 +274,13 @@ diff (argc, argv)
diff_date2 = NULL;
optind = 0;
+ /* FIXME: This should really be allocating an argv to be passed to diff
+ * later rather than strcatting onto the opts variable. We have some
+ * handling routines that can already handle most of the argc/argv
+ * maintenance for us and currently, if anyone were to attempt to pass a
+ * quoted string in here, it would be split on spaces and tabs on its way
+ * to diff.
+ */
while ((c = getopt_long (argc, argv,
"+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:W:k:r:",
longopts, &option_index)) != -1)
@@ -422,7 +433,8 @@ diff (argc, argv)
/* start the recursion processor */
err = start_recursion (diff_fileproc, diff_filesdoneproc, diff_dirproc,
diff_dirleaveproc, NULL, argc, argv, local,
- which, 0, CVS_LOCK_READ, (char *) NULL, 1);
+ which, 0, CVS_LOCK_READ, (char *) NULL, 1,
+ (char *) NULL);
/* clean up */
free (options);
@@ -448,16 +460,12 @@ diff_fileproc (callerdat, finfo)
int status, err = 2; /* 2 == trouble, like rcsdiff */
Vers_TS *vers;
enum diff_file empty_file = DIFF_DIFFERENT;
- char *tmp;
- char *tocvsPath;
- char *fname;
+ char *tmp = NULL;
+ char *tocvsPath = NULL;
+ char *fname = NULL;
char *label1;
char *label2;
-
- /* Initialize these solely to avoid warnings from gcc -Wall about
- variables that might be used uninitialized. */
- tmp = NULL;
- fname = NULL;
+ char *rev1_cache = NULL;
user_file_rev = 0;
vers = Version_TS (finfo, NULL, NULL, NULL, 1, 0);
@@ -505,30 +513,69 @@ diff_fileproc (callerdat, finfo)
error (0, 0,
"%s no longer exists, no comparison available",
finfo->fullname);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
+ goto out;
}
}
else
{
error (0, 0, "I know nothing about %s", finfo->fullname);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
+ goto out;
}
}
else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
{
- if (empty_files)
- empty_file = DIFF_ADDED;
- else
+ /* The file was added locally. */
+ int exists = 0;
+
+ if (vers->srcfile != NULL)
{
- error (0, 0, "%s is a new entry, no comparison available",
- finfo->fullname);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
+ /* The file does exist in the repository. */
+
+ if ((diff_rev1 != NULL || diff_date1 != NULL))
+ {
+ /* special handling for TAG_HEAD */
+ if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
+ {
+ char *head =
+ (vers->vn_rcs == NULL
+ ? NULL
+ : RCS_branch_head (vers->srcfile, vers->vn_rcs));
+ exists = head != NULL && !RCS_isdead(vers->srcfile, head);
+ if (head != NULL)
+ free (head);
+ }
+ else
+ {
+ Vers_TS *xvers;
+
+ xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1,
+ 1, 0);
+ exists = xvers->vn_rcs != NULL
+ && !RCS_isdead (xvers->srcfile, xvers->vn_rcs);
+ freevers_ts (&xvers);
+ }
+ }
+ else
+ {
+ /* The file was added locally, but an RCS archive exists. Our
+ * base revision must be dead.
+ */
+ /* No need to set, exists = 0, here. That's the default. */
+ }
+ }
+ if (!exists)
+ {
+ /* If we got here, then either the RCS archive does not exist or
+ * the relevant revision is dead.
+ */
+ if (empty_files)
+ empty_file = DIFF_ADDED;
+ else
+ {
+ error (0, 0, "%s is a new entry, no comparison available",
+ finfo->fullname);
+ goto out;
+ }
}
}
else if (vers->vn_user[0] == '-')
@@ -539,9 +586,7 @@ diff_fileproc (callerdat, finfo)
{
error (0, 0, "%s was removed, no comparison available",
finfo->fullname);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
+ goto out;
}
}
else
@@ -550,18 +595,14 @@ diff_fileproc (callerdat, finfo)
{
error (0, 0, "cannot find revision control file for %s",
finfo->fullname);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
+ goto out;
}
else
{
if (vers->ts_user == NULL)
{
error (0, 0, "cannot find %s", finfo->fullname);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
+ goto out;
}
else if (!strcmp (vers->ts_user, vers->ts_rcs))
{
@@ -573,73 +614,21 @@ diff_fileproc (callerdat, finfo)
}
}
- empty_file = diff_file_nodiff (finfo, vers, empty_file);
- if (empty_file == DIFF_SAME || empty_file == DIFF_ERROR)
+ empty_file = diff_file_nodiff( finfo, vers, empty_file, &rev1_cache );
+ if( empty_file == DIFF_SAME )
{
- freevers_ts (&vers);
- if (empty_file == DIFF_SAME)
- {
- /* In the server case, would be nice to send a "Checked-in"
- response, so that the client can rewrite its timestamp.
- server_checked_in by itself isn't the right thing (it
- needs a server_register), but I'm not sure what is.
- It isn't clear to me how "cvs status" handles this (that
- is, for a client which sends Modified not Is-modified to
- "cvs status"), but it does. */
- return (0);
- }
- else
- {
- diff_mark_errors (err);
- return (err);
- }
- }
-
- if (empty_file == DIFF_DIFFERENT)
- {
- int dead1, dead2;
-
- if (use_rev1 == NULL)
- dead1 = 0;
- else
- dead1 = RCS_isdead (vers->srcfile, use_rev1);
- if (use_rev2 == NULL)
- dead2 = 0;
- else
- dead2 = RCS_isdead (vers->srcfile, use_rev2);
-
- if (dead1 && dead2)
- {
- freevers_ts (&vers);
- return (0);
- }
- else if (dead1)
- {
- if (empty_files)
- empty_file = DIFF_ADDED;
- else
- {
- error (0, 0, "%s is a new entry, no comparison available",
- finfo->fullname);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
- }
- }
- else if (dead2)
- {
- if (empty_files)
- empty_file = DIFF_REMOVED;
- else
- {
- error (0, 0, "%s was removed, no comparison available",
- finfo->fullname);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
- }
- }
+ /* In the server case, would be nice to send a "Checked-in"
+ response, so that the client can rewrite its timestamp.
+ server_checked_in by itself isn't the right thing (it
+ needs a server_register), but I'm not sure what is.
+ It isn't clear to me how "cvs status" handles this (that
+ is, for a client which sends Modified not Is-modified to
+ "cvs status"), but it does. */
+ err = 0;
+ goto out;
}
+ else if( empty_file == DIFF_ERROR )
+ goto out;
/* Output an "Index:" line for patch to use */
cvs_output ("Index: ", 0);
@@ -647,7 +636,7 @@ diff_fileproc (callerdat, finfo)
cvs_output ("\n", 1);
tocvsPath = wrap_tocvs_process_file(finfo->file);
- if (tocvsPath)
+ if( tocvsPath != NULL )
{
/* Backup the current version of the file to CVS/,,filename */
fname = xmalloc (strlen (finfo->file)
@@ -676,7 +665,8 @@ diff_fileproc (callerdat, finfo)
make_file_label (DEVNULL, NULL, NULL);
else
label1 =
- make_file_label (finfo->fullname, use_rev1, vers ? vers->srcfile : NULL);
+ make_file_label (finfo->fullname, use_rev1,
+ vers ? vers->srcfile : NULL);
}
if (!have_rev2_label)
@@ -686,7 +676,8 @@ diff_fileproc (callerdat, finfo)
make_file_label (DEVNULL, NULL, NULL);
else
label2 =
- make_file_label (finfo->fullname, use_rev2, vers ? vers->srcfile : NULL);
+ make_file_label (finfo->fullname, use_rev2,
+ vers ? vers->srcfile : NULL);
}
if (empty_file == DIFF_ADDED || empty_file == DIFF_REMOVED)
@@ -709,7 +700,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, opts,
+ RUN_TTY);
else
{
int retcode;
@@ -722,11 +714,8 @@ RCS file: ", 0);
: vers->options),
tmp, (RCSCHECKOUTPROC) NULL,
(void *) NULL);
- if (retcode != 0)
- {
- diff_mark_errors (err);
- return err;
- }
+ if( retcode != 0 )
+ goto out;
status = diff_exec (DEVNULL, tmp, label1, label2, opts, RUN_TTY);
}
@@ -742,26 +731,24 @@ RCS file: ", 0);
tmp, (RCSCHECKOUTPROC) NULL,
(void *) NULL);
if (retcode != 0)
- {
- diff_mark_errors (err);
- return err;
- }
+ goto out;
status = diff_exec (tmp, DEVNULL, label1, label2, opts, RUN_TTY);
}
}
else
{
- status = RCS_exec_rcsdiff (vers->srcfile, opts,
- *options ? options : vers->options,
- use_rev1, use_rev2,
- label1, label2,
- finfo->file);
-
- if (label1) free (label1);
- if (label2) free (label2);
+ status = RCS_exec_rcsdiff(vers->srcfile, opts,
+ *options ? options : vers->options,
+ use_rev1, rev1_cache, use_rev2,
+ label1, label2,
+ finfo->file);
+
}
+ if (label1) free (label1);
+ if (label2) free (label2);
+
switch (status)
{
case -1: /* fork failed */
@@ -775,7 +762,8 @@ RCS file: ", 0);
break;
}
- if (tocvsPath)
+out:
+ if( tocvsPath != NULL )
{
if (unlink_file_dir (finfo->file) < 0)
if (! existence_error (errno))
@@ -787,17 +775,25 @@ RCS file: ", 0);
free (fname);
}
- if (empty_file == DIFF_REMOVED
- || (empty_file == DIFF_ADDED && use_rev2 != NULL))
+ /* Call CVS_UNLINK() rather than unlink_file() below to avoid the check
+ * for noexec.
+ */
+ if( tmp != NULL )
{
- if (CVS_UNLINK (tmp) < 0)
+ if (CVS_UNLINK(tmp) < 0)
error (0, errno, "cannot remove %s", tmp);
free (tmp);
}
+ if( rev1_cache != NULL )
+ {
+ if( CVS_UNLINK( rev1_cache ) < 0 )
+ error( 0, errno, "cannot remove %s", rev1_cache );
+ free( rev1_cache );
+ }
freevers_ts (&vers);
diff_mark_errors (err);
- return (err);
+ return err;
}
/*
@@ -820,9 +816,9 @@ diff_mark_errors (err)
static Dtype
diff_dirproc (callerdat, dir, pos_repos, update_dir, entries)
void *callerdat;
- char *dir;
- char *pos_repos;
- char *update_dir;
+ const char *dir;
+ const char *pos_repos;
+ const char *update_dir;
List *entries;
{
/* XXX - check for dirs we don't want to process??? */
@@ -844,8 +840,8 @@ static int
diff_filesdoneproc (callerdat, err, repos, update_dir, entries)
void *callerdat;
int err;
- char *repos;
- char *update_dir;
+ const char *repos;
+ const char *update_dir;
List *entries;
{
return (diff_errors);
@@ -858,9 +854,9 @@ diff_filesdoneproc (callerdat, err, repos, update_dir, entries)
static int
diff_dirleaveproc (callerdat, dir, err, update_dir, entries)
void *callerdat;
- char *dir;
+ const char *dir;
int err;
- char *update_dir;
+ const char *update_dir;
List *entries;
{
return (diff_errors);
@@ -870,10 +866,13 @@ diff_dirleaveproc (callerdat, dir, err, update_dir, entries)
* verify that a file is different
*/
static enum diff_file
-diff_file_nodiff (finfo, vers, empty_file)
+diff_file_nodiff( finfo, vers, empty_file, rev1_cache )
struct file_info *finfo;
Vers_TS *vers;
enum diff_file empty_file;
+ char **rev1_cache; /* Cache the content of rev1 if we have to look
+ * it up.
+ */
{
Vers_TS *xvers;
int retcode;
@@ -889,9 +888,10 @@ diff_file_nodiff (finfo, vers, empty_file)
{
/* special handling for TAG_HEAD */
if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
- use_rev1 = ((vers->vn_rcs == NULL || vers->srcfile == NULL)
- ? NULL
- : RCS_branch_head (vers->srcfile, vers->vn_rcs));
+ {
+ if (vers->vn_rcs != NULL && vers->srcfile != NULL)
+ use_rev1 = RCS_branch_head (vers->srcfile, vers->vn_rcs);
+ }
else
{
xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1, 1, 0);
@@ -904,9 +904,10 @@ diff_file_nodiff (finfo, vers, empty_file)
{
/* special handling for TAG_HEAD */
if (diff_rev2 && strcmp (diff_rev2, TAG_HEAD) == 0)
- use_rev2 = ((vers->vn_rcs == NULL || vers->srcfile == NULL)
- ? NULL
- : RCS_branch_head (vers->srcfile, vers->vn_rcs));
+ {
+ if (vers->vn_rcs != NULL && vers->srcfile != NULL)
+ use_rev2 = RCS_branch_head (vers->srcfile, vers->vn_rcs);
+ }
else
{
xvers = Version_TS (finfo, NULL, diff_rev2, diff_date2, 1, 0);
@@ -915,19 +916,39 @@ diff_file_nodiff (finfo, vers, empty_file)
freevers_ts (&xvers);
}
- if (use_rev1 == NULL)
+ if( use_rev1 == NULL || RCS_isdead( vers->srcfile, use_rev1 ) )
{
/* The first revision does not exist. If EMPTY_FILES is
true, treat this as an added file. Otherwise, warn
about the missing tag. */
- if (use_rev2 == NULL)
+ if( use_rev2 == NULL || RCS_isdead( vers->srcfile, use_rev2 ) )
/* At least in the case where DIFF_REV1 and DIFF_REV2
- are both numeric, we should be returning some kind
- of error (see basicb-8a0 in testsuite). The symbolic
- case may be more complicated. */
+ * are both numeric (and non-existant (NULL), as opposed to
+ * dead?), we should be returning some kind of error (see
+ * basicb-8a0 in testsuite). The symbolic case may be more
+ * complicated.
+ */
return DIFF_SAME;
- else if (empty_files)
+ if( empty_files )
return DIFF_ADDED;
+ if( use_rev1 != NULL )
+ {
+ if (diff_rev1)
+ {
+ error( 0, 0,
+ "Tag %s refers to a dead (removed) revision in file `%s'.",
+ diff_rev1, finfo->fullname );
+ }
+ else
+ {
+ error( 0, 0,
+ "Date %s refers to a dead (removed) revision in file `%s'.",
+ diff_date1, finfo->fullname );
+ }
+ error( 0, 0,
+ "No comparison available. Pass `-N' to `%s diff'?",
+ program_name );
+ }
else if (diff_rev1)
error (0, 0, "tag %s is not in file %s", diff_rev1,
finfo->fullname);
@@ -937,13 +958,32 @@ diff_file_nodiff (finfo, vers, empty_file)
return DIFF_ERROR;
}
- if (use_rev2 == NULL)
+ assert( use_rev1 != NULL );
+ if( use_rev2 == NULL || RCS_isdead( vers->srcfile, use_rev2 ) )
{
/* The second revision does not exist. If EMPTY_FILES is
true, treat this as a removed file. Otherwise warn
about the missing tag. */
if (empty_files)
return DIFF_REMOVED;
+ if( use_rev2 != NULL )
+ {
+ if (diff_rev2)
+ {
+ error( 0, 0,
+ "Tag %s refers to a dead (removed) revision in file `%s'.",
+ diff_rev2, finfo->fullname );
+ }
+ else
+ {
+ error( 0, 0,
+ "Date %s refers to a dead (removed) revision in file `%s'.",
+ diff_date2, finfo->fullname );
+ }
+ error( 0, 0,
+ "No comparison available. Pass `-N' to `%s diff'?",
+ program_name );
+ }
else if (diff_rev2)
error (0, 0, "tag %s is not in file %s", diff_rev2,
finfo->fullname);
@@ -952,15 +992,23 @@ diff_file_nodiff (finfo, vers, empty_file)
diff_date2, finfo->fullname);
return DIFF_ERROR;
}
-
- /* now, see if we really need to do the diff */
- if (strcmp (use_rev1, use_rev2) == 0)
+ /* Now, see if we really need to do the diff. We can't assume that the
+ * files are different when the revs are.
+ */
+ assert( use_rev2 != NULL );
+ if( strcmp (use_rev1, use_rev2) == 0 )
return DIFF_SAME;
- else
- return DIFF_DIFFERENT;
+ /* else fall through and do the diff */
}
- if ((diff_rev1 || diff_date1) && use_rev1 == NULL)
+ /* If we had a r1/d1 & r2/d2, then at this point we must have a C3P0...
+ * err... ok, then both rev1 & rev2 must have resolved to an existing,
+ * live version due to if statement we just closed.
+ */
+ assert (!(diff_rev2 || diff_date2) || (use_rev1 && use_rev2));
+
+ if ((diff_rev1 || diff_date1) &&
+ (use_rev1 == NULL || RCS_isdead (vers->srcfile, use_rev1)))
{
/* The first revision does not exist, and no second revision
was given. */
@@ -968,25 +1016,39 @@ diff_file_nodiff (finfo, vers, empty_file)
{
if (empty_file == DIFF_REMOVED)
return DIFF_SAME;
- else
- {
- if (user_file_rev && use_rev2 == NULL)
- use_rev2 = xstrdup (user_file_rev);
- return DIFF_ADDED;
- }
+ if( user_file_rev && use_rev2 == NULL )
+ use_rev2 = xstrdup( user_file_rev );
+ return DIFF_ADDED;
}
- else
+ if( use_rev1 != NULL )
{
if (diff_rev1)
- error (0, 0, "tag %s is not in file %s", diff_rev1,
- finfo->fullname);
+ {
+ error( 0, 0,
+ "Tag %s refers to a dead (removed) revision in file `%s'.",
+ diff_rev1, finfo->fullname );
+ }
else
- error (0, 0, "no revision for date %s in file %s",
- diff_date1, finfo->fullname);
- return DIFF_ERROR;
+ {
+ error( 0, 0,
+ "Date %s refers to a dead (removed) revision in file `%s'.",
+ diff_date1, finfo->fullname );
+ }
+ error( 0, 0,
+ "No comparison available. Pass `-N' to `%s diff'?",
+ program_name );
}
+ else if ( diff_rev1 )
+ error( 0, 0, "tag %s is not in file %s", diff_rev1,
+ finfo->fullname );
+ else
+ error( 0, 0, "no revision for date %s in file %s",
+ diff_date1, finfo->fullname );
+ return DIFF_ERROR;
}
+ assert( !diff_rev1 || use_rev1 );
+
if (user_file_rev)
{
/* drop user_file_rev into first unused use_rev */
@@ -995,20 +1057,25 @@ diff_file_nodiff (finfo, vers, empty_file)
else if (!use_rev2)
use_rev2 = xstrdup (user_file_rev);
/* and if not, it wasn't needed anyhow */
- user_file_rev = 0;
+ user_file_rev = NULL;
}
- /* now, see if we really need to do the diff */
- if (use_rev1 && use_rev2)
+ /* Now, see if we really need to do the diff. We can't assume that the
+ * files are different when the revs are.
+ */
+ if( use_rev1 && use_rev2)
{
if (strcmp (use_rev1, use_rev2) == 0)
return DIFF_SAME;
- else
- return DIFF_DIFFERENT;
+ /* Fall through and do the diff. */
}
-
- if (use_rev1 == NULL
- || (vers->vn_user != NULL && strcmp (use_rev1, vers->vn_user) == 0))
+ /* Don't want to do the timestamp check with both use_rev1 & use_rev2 set.
+ * The timestamp check is just for the default case of diffing the
+ * workspace file against its base revision.
+ */
+ else if( use_rev1 == NULL
+ || ( vers->vn_user != NULL
+ && strcmp( use_rev1, vers->vn_user ) == 0 ) )
{
if (empty_file == DIFF_DIFFERENT
&& vers->ts_user != NULL
@@ -1033,13 +1100,12 @@ diff_file_nodiff (finfo, vers, empty_file)
return empty_file;
/*
- * with 0 or 1 -r option specified, run a quick diff to see if we
- * should bother with it at all.
+ * Run a quick cmp to see if we should bother with a full diff.
*/
- retcode = RCS_cmp_file (vers->srcfile, use_rev1,
- *options ? options : vers->options,
- finfo->file);
+ retcode = RCS_cmp_file( vers->srcfile, use_rev1, rev1_cache,
+ use_rev2, *options ? options : vers->options,
+ finfo->file );
return retcode == 0 ? DIFF_SAME : DIFF_DIFFERENT;
}
diff --git a/contrib/cvs/src/edit.c b/contrib/cvs/src/edit.c
index cde03f9..fe4c21f 100644
--- a/contrib/cvs/src/edit.c
+++ b/contrib/cvs/src/edit.c
@@ -36,14 +36,17 @@ onoff_fileproc (callerdat, finfo)
return 0;
}
-static int onoff_filesdoneproc PROTO ((void *, int, char *, char *, List *));
+
+
+static int onoff_filesdoneproc PROTO ((void *, int, const char *, const char *,
+ List *));
static int
onoff_filesdoneproc (callerdat, err, repository, update_dir, entries)
void *callerdat;
int err;
- char *repository;
- char *update_dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
if (setting_default)
@@ -104,7 +107,7 @@ watch_onoff (argc, argv)
err = start_recursion (onoff_fileproc, onoff_filesdoneproc,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
argc, argv, local, W_LOCAL, 0, CVS_LOCK_NONE,
- (char *)NULL, 0);
+ (char *) NULL, 0, (char *) NULL);
Lock_Cleanup ();
return err;
@@ -238,7 +241,7 @@ send_notifications (argc, argv, local)
notifications stay in CVSADM_NOTIFY to be sent next time. */
if (current_parsed_root->isremote)
{
- if (strcmp (command_name, "release") != 0)
+ if (strcmp (cvs_cmd_name, "release") != 0)
{
start_server ();
ign_setup ();
@@ -247,10 +250,10 @@ send_notifications (argc, argv, local)
err += start_recursion (dummy_fileproc, (FILESDONEPROC) NULL,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
argc, argv, local, W_LOCAL, 0, 0, (char *)NULL,
- 0);
+ 0, (char *) NULL);
send_to_server ("noop\012", 0);
- if (strcmp (command_name, "release") == 0)
+ if (strcmp (cvs_cmd_name, "release") == 0)
err += get_server_responses ();
else
err += get_responses_and_close ();
@@ -264,7 +267,7 @@ send_notifications (argc, argv, local)
err += start_recursion (ncheck_fileproc, (FILESDONEPROC) NULL,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
argc, argv, local, W_LOCAL, 0, 0, (char *)NULL,
- 0);
+ 0, (char *) NULL);
Lock_Cleanup ();
}
return err;
@@ -443,8 +446,8 @@ edit (argc, argv)
repository. */
err = start_recursion (edit_fileproc, (FILESDONEPROC) NULL,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
- argc, argv, local, W_LOCAL, 0, 0, (char *)NULL,
- 0);
+ argc, argv, local, W_LOCAL, 0, 0, (char *) NULL,
+ 0, (char *) NULL);
err += send_notifications (argc, argv, local);
@@ -534,7 +537,7 @@ unedit_fileproc (callerdat, finfo)
now. */
if (node != NULL)
{
- entdata = (Entnode *) node->data;
+ entdata = node->data;
if (baserev == NULL)
{
/* This can only happen if the CVS/Baserev file got
@@ -613,7 +616,7 @@ unedit (argc, argv)
err = start_recursion (unedit_fileproc, (FILESDONEPROC) NULL,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
argc, argv, local, W_LOCAL, 0, 0, (char *)NULL,
- 0);
+ 0, (char *) NULL);
err += send_notifications (argc, argv, local);
@@ -622,7 +625,7 @@ unedit (argc, argv)
void
mark_up_to_date (file)
- char *file;
+ const char *file;
{
char *base;
@@ -637,12 +640,13 @@ mark_up_to_date (file)
free (base);
}
-
+
+
void
editor_set (filename, editor, val)
- char *filename;
- char *editor;
- char *val;
+ const char *filename;
+ const char *editor;
+ const char *val;
{
char *edlist;
char *newlist;
@@ -663,32 +667,36 @@ editor_set (filename, editor, val)
struct notify_proc_args {
/* What kind of notification, "edit", "tedit", etc. */
- char *type;
+ const char *type;
/* User who is running the command which causes notification. */
- char *who;
+ const char *who;
/* User to be notified. */
- char *notifyee;
+ const char *notifyee;
/* File. */
- char *file;
+ const char *file;
};
+
+
/* Pass as a static until we get around to fixing Parse_Info to pass along
a void * where we can stash it. */
static struct notify_proc_args *notify_args;
-static int notify_proc PROTO ((char *repository, char *filter));
+
+
+static int notify_proc PROTO ((const char *repository, const char *filter));
static int
notify_proc (repository, filter)
- char *repository;
- char *filter;
+ const char *repository;
+ const char *filter;
{
FILE *pipefp;
char *prog;
char *expanded_prog;
- char *p;
+ const char *p;
char *q;
- char *srepos;
+ const char *srepos;
struct notify_proc_args *args = notify_args;
srepos = Short_Repository (repository);
@@ -751,11 +759,11 @@ notify_proc (repository, filter)
void
notify_do (type, filename, who, val, watches, repository)
int type;
- char *filename;
- char *who;
- char *val;
- char *watches;
- char *repository;
+ const char *filename;
+ const char *who;
+ const char *val;
+ const char *watches;
+ const char *repository;
{
static struct addremove_args blank;
struct addremove_args args;
@@ -919,9 +927,11 @@ notify_do (type, filename, who, val, watches, repository)
if (args.notifyee == NULL)
{
- args.notifyee = xmalloc (endp - p + 1);
- strncpy (args.notifyee, p, endp - p);
- args.notifyee[endp - p] = '\0';
+ char *tmp;
+ tmp = xmalloc (endp - p + 1);
+ strncpy (tmp, p, endp - p);
+ tmp[endp - p] = '\0';
+ args.notifyee = tmp;
}
notify_args = &args;
@@ -930,7 +940,12 @@ notify_do (type, filename, who, val, watches, repository)
args.file = filename;
(void) Parse_Info (CVSROOTADM_NOTIFY, repository, notify_proc, 1);
- free (args.notifyee);
+
+ /* It's okay to cast out the const for the free() below since we
+ * just allocated this a few lines above. The const was for
+ * everybody else.
+ */
+ free ((char *)args.notifyee);
}
p = nextp;
@@ -969,8 +984,8 @@ notify_do (type, filename, who, val, watches, repository)
/* Check and send notifications. This is only for the client. */
void
notify_check (repository, update_dir)
- char *repository;
- char *update_dir;
+ const char *repository;
+ const char *update_dir;
{
FILE *fp;
char *line = NULL;
@@ -1136,6 +1151,6 @@ editors (argc, argv)
return start_recursion (editors_fileproc, (FILESDONEPROC) NULL,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
- argc, argv, local, W_LOCAL, 0, 1, (char *)NULL,
- 0);
+ argc, argv, local, W_LOCAL, 0, 1, (char *) NULL,
+ 0, (char *) NULL);
}
diff --git a/contrib/cvs/src/edit.h b/contrib/cvs/src/edit.h
index 7c274a6..5c8635a 100644
--- a/contrib/cvs/src/edit.h
+++ b/contrib/cvs/src/edit.h
@@ -17,7 +17,8 @@ extern int watch_off PROTO ((int argc, char **argv));
/* Check to see if any notifications are sitting around in need of being
sent. These are the notifications stored in CVSADM_NOTIFY (edit,unedit);
commit calls notify_do directly. */
-extern void notify_check PROTO ((char *repository, char *update_dir));
+extern void notify_check PROTO ((const char *repository,
+ const char *update_dir));
#endif /* CLIENT_SUPPORT */
/* Issue a notification for file FILENAME. TYPE is 'E' for edit, 'U'
@@ -25,14 +26,16 @@ extern void notify_check PROTO ((char *repository, char *update_dir));
For TYPE 'E', VAL is the time+host+directory data which goes in
_editors, and WATCHES is zero or more of E,U,C, in that order, to specify
what kinds of temporary watches to set. */
-extern void notify_do PROTO ((int type, char *filename, char *who,
- char *val, char *watches, char *repository));
+extern void notify_do PROTO ((int type, const char *filename, const char *who,
+ const char *val, const char *watches,
+ const char *repository));
/* Set attributes to reflect the fact that EDITOR is editing FILENAME.
VAL is time+host+directory, or NULL if we are to say that EDITOR is
*not* editing FILENAME. */
-extern void editor_set PROTO ((char *filename, char *editor, char *val));
+extern void editor_set PROTO ((const char *filename, const char *editor,
+ const char *val));
/* Take note of the fact that FILE is up to date (this munges CVS/Base;
processing of CVS/Entries is done separately). */
-extern void mark_up_to_date PROTO ((char *file));
+extern void mark_up_to_date PROTO ((const char *file));
diff --git a/contrib/cvs/src/entries.c b/contrib/cvs/src/entries.c
index 686244d..fe927d3 100644
--- a/contrib/cvs/src/entries.c
+++ b/contrib/cvs/src/entries.c
@@ -24,6 +24,8 @@ static Entnode *subdir_record PROTO((int, const char *, const char *));
static FILE *entfile;
static char *entfilename; /* for error messages */
+
+
/*
* Construct an Entnode
*/
@@ -90,9 +92,7 @@ write_ent_proc (node, closure)
Node *node;
void *closure;
{
- Entnode *entnode;
-
- entnode = (Entnode *) node->data;
+ Entnode *entnode = node->data;
if (closure != NULL && entnode->type != ENT_FILE)
*(int *) closure = 1;
@@ -145,7 +145,7 @@ write_entries (list)
/* We didn't write out any directories. Check the list
private data to see whether subdirectory information is
known. If it is, we need to write out an empty D line. */
- sdtp = (struct stickydirtag *) list->list->data;
+ sdtp = list->list->data;
if (sdtp == NULL || sdtp->subdirs)
if (fprintf (entfile, "D\n") < 0)
error (1, errno, "cannot write %s", entfilename);
@@ -162,13 +162,15 @@ write_entries (list)
error (0, errno, "cannot remove %s", CVSADM_ENTLOG);
}
+
+
/*
* Removes the argument file from the Entries file if necessary.
*/
void
Scratch_Entry (list, fname)
List *list;
- char *fname;
+ const char *fname;
{
Node *node;
@@ -202,6 +204,8 @@ Scratch_Entry (list, fname)
}
}
+
+
/*
* Enters the given file name/version/time-stamp into the Entries file,
* removing the old entry first, if necessary.
@@ -209,13 +213,13 @@ Scratch_Entry (list, fname)
void
Register (list, fname, vn, ts, options, tag, date, ts_conflict)
List *list;
- char *fname;
- char *vn;
- char *ts;
- char *options;
- char *tag;
- char *date;
- char *ts_conflict;
+ const char *fname;
+ const char *vn;
+ const char *ts;
+ const char *options;
+ const char *tag;
+ const char *date;
+ const char *ts_conflict;
{
Entnode *entnode;
Node *node;
@@ -270,9 +274,8 @@ static void
freesdt (p)
Node *p;
{
- struct stickydirtag *sdtp;
+ struct stickydirtag *sdtp = p->data;
- sdtp = (struct stickydirtag *) p->data;
if (sdtp->tag)
free (sdtp->tag);
if (sdtp->date)
@@ -488,7 +491,7 @@ Entries_Open (aflag, update_dir)
sdtp->nonbranch = dirnonbranch;
/* feed it into the list-private area */
- entries->list->data = (char *) sdtp;
+ entries->list->data = sdtp;
entries->list->delproc = freesdt;
}
@@ -553,7 +556,7 @@ Entries_Open (aflag, update_dir)
sdtp = (struct stickydirtag *) xmalloc (sizeof (*sdtp));
memset ((char *) sdtp, 0, sizeof (*sdtp));
sdtp->subdirs = 0;
- entries->list->data = (char *) sdtp;
+ entries->list->data = sdtp;
entries->list->delproc = freesdt;
}
@@ -592,9 +595,8 @@ static void
Entries_delproc (node)
Node *node;
{
- Entnode *p;
+ Entnode *p = node->data;
- p = (Entnode *) node->data;
Entnode_Destroy(p);
}
@@ -626,7 +628,7 @@ AddEntryNode (list, entdata)
assume that the key is dynamically allocated. The user's free proc
should be responsible for freeing the key. */
p->key = xstrdup (entdata->user);
- p->data = (char *) entdata;
+ p->data = entdata;
/* put the node into the list */
addnode (list, p);
@@ -638,12 +640,12 @@ AddEntryNode (list, entdata)
*/
void
WriteTag (dir, tag, date, nonbranch, update_dir, repository)
- char *dir;
- char *tag;
- char *date;
+ const char *dir;
+ const char *tag;
+ const char *date;
int nonbranch;
- char *update_dir;
- char *repository;
+ const char *update_dir;
+ const char *repository;
{
FILE *fout;
char *tmp;
@@ -796,11 +798,10 @@ void
Subdirs_Known (entries)
List *entries;
{
- struct stickydirtag *sdtp;
+ struct stickydirtag *sdtp = entries->list->data;
/* If there is no list private data, that means that the
subdirectory information is known. */
- sdtp = (struct stickydirtag *) entries->list->data;
if (sdtp != NULL && ! sdtp->subdirs)
{
FILE *fp;
diff --git a/contrib/cvs/src/error.c b/contrib/cvs/src/error.c
index 9655a97..129ba9b 100644
--- a/contrib/cvs/src/error.c
+++ b/contrib/cvs/src/error.c
@@ -128,12 +128,12 @@ error (status, errnum, message, va_alist)
char buf[100];
cvs_outerr (program_name, 0);
- if (command_name && *command_name)
+ if (cvs_cmd_name && *cvs_cmd_name)
{
cvs_outerr (" ", 1);
if (status != 0)
cvs_outerr ("[", 1);
- cvs_outerr (command_name, 0);
+ cvs_outerr (cvs_cmd_name, 0);
if (status != 0)
cvs_outerr (" aborted]", 0);
}
diff --git a/contrib/cvs/src/expand_path.c b/contrib/cvs/src/expand_path.c
index f46b39b..5aa1063 100644
--- a/contrib/cvs/src/expand_path.c
+++ b/contrib/cvs/src/expand_path.c
@@ -15,9 +15,11 @@
#include "cvs.h"
#include <sys/types.h>
-static char *expand_variable PROTO((char *env, char *file, int line));
+static char *expand_variable PROTO((const char *env, const char *file,
+ int line));
+
+
-
/* User variables. */
List *variable_list = NULL;
@@ -79,7 +81,9 @@ variable_set (nameval)
free (name);
}
}
-
+
+
+
/* This routine will expand the pathname to account for ~ and $
characters as described above. Returns a pointer to a newly
malloc'd string. If an error occurs, an error message is printed
@@ -89,11 +93,11 @@ variable_set (nameval)
known. */
char *
expand_path (name, file, line)
- char *name;
- char *file;
+ const char *name;
+ const char *file;
int line;
{
- char *s;
+ const char *s;
char *d;
char *mybuf = NULL;
@@ -179,8 +183,9 @@ expand_path (name, file, line)
if (*s++ == '~')
{
char *t;
- char *p=s;
- if (*s=='/' || *s==0)
+ char *p, *pstart;
+ pstart = p = xstrdup (s);
+ if (*pstart=='/' || *pstart==0)
t = get_homedir ();
else
{
@@ -201,14 +206,14 @@ expand_path (name, file, line)
for (; *p!='/' && *p; p++)
;
*p = 0;
- ps = getpwnam (s);
+ ps = getpwnam (pstart);
if (ps == 0)
{
if (line != 0)
error (0, 0, "%s:%d: no such user %s",
- file, line, s);
+ file, line, pstart);
else
- error (0, 0, "%s: no such user %s", file, s);
+ error (0, 0, "%s: no such user %s", file, pstart);
return NULL;
}
t = ps->pw_dir;
@@ -227,9 +232,8 @@ expand_path (name, file, line)
d = buf + doff;
}
--d;
- if (*p == 0)
- *p = '/'; /* always add / */
- s=p;
+ s+=p-pstart;
+ free (pstart);
}
else
--s;
@@ -267,12 +271,12 @@ expand_path (name, file, line)
static char *
expand_variable (name, file, line)
- char *name;
- char *file;
+ const char *name;
+ const char *file;
int line;
{
if (strcmp (name, CVSROOT_ENV) == 0)
- return current_parsed_root->original;
+ return current_parsed_root->directory;
else if (strcmp (name, "RCSBIN") == 0)
{
error (0, 0, "RCSBIN internal variable is no longer supported");
diff --git a/contrib/cvs/src/fileattr.c b/contrib/cvs/src/fileattr.c
index bae03a6..9b10851 100644
--- a/contrib/cvs/src/fileattr.c
+++ b/contrib/cvs/src/fileattr.c
@@ -43,7 +43,7 @@ static struct unrecog *unrecog_head;
no open(), no nothing. */
void
fileattr_startdir (repos)
- char *repos;
+ const char *repos;
{
assert (fileattr_stored_repos == NULL);
fileattr_stored_repos = xstrdup (repos);
diff --git a/contrib/cvs/src/fileattr.h b/contrib/cvs/src/fileattr.h
index 046b975..507807c 100644
--- a/contrib/cvs/src/fileattr.h
+++ b/contrib/cvs/src/fileattr.h
@@ -56,7 +56,7 @@
/* Prepare for a new directory with repository REPOS. If REPOS is NULL,
then prepare for a "non-directory"; the caller can call fileattr_write
and fileattr_free, but must not call fileattr_get or fileattr_set. */
-extern void fileattr_startdir PROTO ((char *repos));
+extern void fileattr_startdir PROTO ((const char *repos));
/* Get the attribute ATTRNAME for file FILENAME. The return value
points into memory managed by the fileattr_* routines, should not
diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c
index 381945d..57511f4 100644
--- a/contrib/cvs/src/filesubr.c
+++ b/contrib/cvs/src/filesubr.c
@@ -327,12 +327,13 @@ make_directories (name)
existed. */
int
mkdir_if_needed (name)
- char *name;
+ const char *name;
{
if (mkdir (name, 0777) < 0)
{
- if (errno != EEXIST && !isdir (name))
- error (1, errno, "cannot make directory %s", name);
+ int save_errno = errno;
+ if (save_errno != EEXIST && !isdir (name))
+ error (1, save_errno, "cannot make directory %s", name);
return 1;
}
return 0;
@@ -347,7 +348,7 @@ mkdir_if_needed (name)
*/
void
xchmod (fname, writable)
- char *fname;
+ const char *fname;
int writable;
{
struct stat sb;
@@ -609,6 +610,7 @@ xcmp (file1, file2)
/* If FILE1 and FILE2 are symlinks, they are equal if they point to
the same thing. */
+#ifdef S_ISLNK
if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode))
{
int result;
@@ -619,6 +621,7 @@ xcmp (file1, file2)
free (buf2);
return result;
}
+#endif
/* If FILE1 and FILE2 are devices, they are equal if their device
numbers match. */
@@ -766,8 +769,8 @@ FILE *cvs_temp_file (filename)
if (fd == -1) fp = NULL;
else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL)
{
- /* attempt to close and unlink the file since mkstemp returned sucessfully and
- * we believe it's been created and opened
+ /* Attempt to close and unlink the file since mkstemp returned
+ * sucessfully and we believe it's been created and opened.
*/
int save_errno = errno;
if (close (fd))
@@ -845,31 +848,33 @@ FILE *cvs_temp_file (filename)
return fp;
}
-/* Return non-zero iff FILENAME is absolute.
- Trivial under Unix, but more complicated under other systems. */
-int
-isabsolute (filename)
- const char *filename;
-{
- return filename[0] == '/';
-}
-/*
- * Return a string (dynamically allocated) with the name of the file to which
- * LINK is symlinked.
+
+#ifdef HAVE_READLINK
+/* char *
+ * xreadlink ( const char *link )
+ *
+ * Like the X/OPEN and 4.4BSD readlink() function, but allocates and returns
+ * its own buf.
+ *
+ * INPUTS
+ * link The original path.
+ *
+ * RETURNS
+ * The resolution of the final symbolic link in the path.
+ *
+ * ERRORS
+ * This function exits with a fatal error if it fails to read the link for
+ * any reason.
*/
char *
xreadlink (link)
const char *link;
{
char *file = NULL;
- char *tfile;
int buflen = 128;
int link_name_len;
- if (!islink (link))
- return NULL;
-
/* 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 */
@@ -886,19 +891,59 @@ xreadlink (link)
file[link_name_len] = '\0';
- tfile = xstrdup (file);
- free (file);
+ return file;
+}
+#endif /* HAVE_READLINK */
+
- return tfile;
+
+/* char *
+ * xresolvepath ( const char *path )
+ *
+ * Like xreadlink(), but resolve all links in a path.
+ *
+ * INPUTS
+ * path The original path.
+ *
+ * RETURNS
+ * The path with any symbolic links expanded.
+ *
+ * ERRORS
+ * This function exits with a fatal error if it fails to read the link for
+ * any reason.
+ */
+char *
+xresolvepath ( path )
+ const char *path;
+{
+ char *hardpath;
+ char *owd;
+
+ assert ( isdir ( path ) );
+
+ /* FIXME - If HAVE_READLINK is defined, we should probably walk the path
+ * bit by bit calling xreadlink().
+ */
+
+ owd = xgetwd();
+ if ( CVS_CHDIR ( path ) < 0)
+ error ( 1, errno, "cannot chdir to %s", path );
+ if ( ( hardpath = xgetwd() ) == NULL )
+ error (1, errno, "cannot getwd in %s", path);
+ if ( CVS_CHDIR ( owd ) < 0)
+ error ( 1, errno, "cannot chdir to %s", owd );
+ free (owd);
+ return hardpath;
}
+
/* Return a pointer into PATH's last component. */
-char *
+const char *
last_component (path)
- char *path;
+ const char *path;
{
- char *last = strrchr (path, '/');
+ const char *last = strrchr (path, '/');
if (last && (last != path))
return last + 1;
@@ -990,6 +1035,8 @@ expand_wild (argc, argv, pargc, pargv)
(*pargv)[i] = xstrdup (argv[i]);
}
+
+
#ifdef SERVER_SUPPORT
/* Case-insensitive string compare. I know that some systems
have such a routine, but I'm not sure I see any reasons for
@@ -998,11 +1045,11 @@ expand_wild (argc, argv, pargc, pargv)
not). */
int
cvs_casecmp (str1, str2)
- char *str1;
- char *str2;
+ const char *str1;
+ const char *str2;
{
- char *p;
- char *q;
+ const char *p;
+ const char *q;
int pqdiff;
p = str1;
@@ -1016,107 +1063,4 @@ cvs_casecmp (str1, str2)
}
return pqdiff;
}
-
-/* Case-insensitive file open. As you can see, this is an expensive
- call. We don't regard it as our main strategy for dealing with
- case-insensitivity. Returns errno code or 0 for success. Puts the
- new file in *FP. NAME and MODE are as for fopen. If PATHP is not
- NULL, then put a malloc'd string containing the pathname as found
- into *PATHP. *PATHP is only set if the return value is 0.
-
- Might be cleaner to separate the file finding (which just gives
- *PATHP) from the file opening (which the caller can do). For one
- thing, might make it easier to know whether to put NAME or *PATHP
- into error messages. */
-int
-fopen_case (name, mode, fp, pathp)
- char *name;
- char *mode;
- FILE **fp;
- char **pathp;
-{
- struct dirent *dp;
- DIR *dirp;
- char *dir;
- char *fname;
- char *found_name;
- int retval;
-
- /* Separate NAME into directory DIR and filename within the directory
- FNAME. */
- dir = xstrdup (name);
- fname = strrchr (dir, '/');
- if (fname == NULL)
- error (1, 0, "internal error: relative pathname in fopen_case");
- *fname++ = '\0';
-
- found_name = NULL;
- dirp = CVS_OPENDIR (dir);
- if (dirp == NULL)
- {
- if (existence_error (errno))
- {
- /* This can happen if we are looking in the Attic and the Attic
- directory does not exist. Return the error to the caller;
- they know what to do with it. */
- retval = errno;
- goto out;
- }
- else
- {
- /* Give a fatal error; that way the error message can be
- more specific than if we returned the error to the caller. */
- error (1, errno, "cannot read directory %s", dir);
- }
- }
- errno = 0;
- while ((dp = CVS_READDIR (dirp)) != NULL)
- {
- if (cvs_casecmp (dp->d_name, fname) == 0)
- {
- if (found_name != NULL)
- error (1, 0, "%s is ambiguous; could mean %s or %s",
- fname, dp->d_name, found_name);
- found_name = xstrdup (dp->d_name);
- }
- }
- if (errno != 0)
- error (1, errno, "cannot read directory %s", dir);
- CVS_CLOSEDIR (dirp);
-
- if (found_name == NULL)
- {
- *fp = NULL;
- retval = ENOENT;
- }
- else
- {
- char *p;
-
- /* Copy the found name back into DIR. We are assuming that
- found_name is the same length as fname, which is true as
- long as the above code is just ignoring case and not other
- aspects of filename syntax. */
- p = dir + strlen (dir);
- *p++ = '/';
- strcpy (p, found_name);
- *fp = fopen (dir, mode);
- if (*fp == NULL)
- retval = errno;
- else
- retval = 0;
- }
-
- if (pathp == NULL)
- free (dir);
- else if (retval != 0)
- free (dir);
- else
- *pathp = dir;
- free (found_name);
- out:
- return retval;
-}
#endif /* SERVER_SUPPORT */
-/* vim:tabstop=8:shiftwidth=4
- */
diff --git a/contrib/cvs/src/find_names.c b/contrib/cvs/src/find_names.c
index 751ac67..cff0de1 100644
--- a/contrib/cvs/src/find_names.c
+++ b/contrib/cvs/src/find_names.c
@@ -33,11 +33,10 @@ add_entries_proc (node, closure)
Node *node;
void *closure;
{
- Entnode *entnode;
Node *fnode;
- List *filelist = (List *) closure;
+ List *filelist = closure;
+ Entnode *entnode = node->data;
- entnode = (Entnode *) node->data;
if (entnode->type != ENT_FILE)
return (0);
@@ -127,11 +126,10 @@ add_subdir_proc (p, closure)
Node *p;
void *closure;
{
- List *dirlist = (List *) closure;
- Entnode *entnode;
+ List *dirlist = closure;
+ Entnode *entnode = p->data;
Node *dnode;
- entnode = (Entnode *) p->data;
if (entnode->type != ENT_SUBDIR)
return 0;
@@ -189,7 +187,7 @@ Find_Directories (repository, which, entries)
tmpentries = NULL;
if (tmpentries != NULL)
- sdtp = (struct stickydirtag *) tmpentries->list->data;
+ sdtp = tmpentries->list->data;
/* If we do have an entries list, then if sdtp is NULL, or if
sdtp->subdirs is nonzero, all subdirectory information is
diff --git a/contrib/cvs/src/hardlink.c b/contrib/cvs/src/hardlink.c
index 309d27f..5cd9c37 100644
--- a/contrib/cvs/src/hardlink.c
+++ b/contrib/cvs/src/hardlink.c
@@ -87,7 +87,7 @@ lookup_file_by_inode (filepath)
hp = getnode ();
hp->type = NT_UNKNOWN;
hp->key = inodestr;
- hp->data = (char *) getlist();
+ hp->data = getlist();
hp->delproc = dellist;
(void) addnode (hardlist, hp);
}
@@ -96,14 +96,14 @@ lookup_file_by_inode (filepath)
free (inodestr);
}
- p = findnode ((List *) hp->data, filepath);
+ p = findnode (hp->data, filepath);
if (p == NULL)
{
p = getnode();
p->type = NT_UNKNOWN;
p->key = xstrdup (filepath);
p->data = NULL;
- (void) addnode ((List *) hp->data, p);
+ (void) addnode (hp->data, p);
}
return p;
@@ -143,8 +143,8 @@ update_hardlink_info (file)
}
if (n->data == NULL)
- n->data = (char *) xmalloc (sizeof (struct hardlink_info));
- hlinfo = (struct hardlink_info *) n->data;
+ n->data = xmalloc (sizeof (struct hardlink_info));
+ hlinfo = n->data;
hlinfo->status = T_UPTODATE;
hlinfo->checked_out = 1;
}
@@ -197,10 +197,10 @@ list_linked_files_on_disk (file)
/* Make sure the files linked to this inode are sorted. */
n = findnode (hardlist, inodestr);
- sortlist ((List *) n->data, fsortcmp);
+ sortlist (n->data, fsortcmp);
free (inodestr);
- return (List *) n->data;
+ return n->data;
}
/* Compare the files in the `key' fields of two lists, returning 1 if
@@ -292,7 +292,7 @@ find_checkedout_proc (node, data)
return 0;
}
- hlinfo = (struct hardlink_info *) link->data;
+ hlinfo = link->data;
if (hlinfo->checked_out)
{
/* This file has been checked out recently, so it's safe to
diff --git a/contrib/cvs/src/hash.c b/contrib/cvs/src/hash.c
index 7e562b8..4a97784 100644
--- a/contrib/cvs/src/hash.c
+++ b/contrib/cvs/src/hash.c
@@ -195,7 +195,7 @@ freenode_mem (p)
free (p->key);
/* to be safe, re-initialize these */
- p->key = p->data = (char *) NULL;
+ p->key = p->data = NULL;
p->delproc = (void (*) ()) NULL;
}
@@ -402,6 +402,9 @@ sortlist (list, comp)
Node *head, *remain, *p, **array;
int i, n;
+ if (list == NULL)
+ return;
+
/* save the old first element of the list */
head = list->list;
remain = head->next;
@@ -488,8 +491,10 @@ printnode (node, closure)
return(0);
}
- (void) printf("Node at 0x%p: type = %s, key = 0x%p = \"%s\", data = 0x%p, next = 0x%p, prev = 0x%p\n",
- node, nodetypestring(node->type), node->key, node->key, node->data, node->next, node->prev);
+ (void) printf("Node at %p: type = %s, key = %p = \"%s\", data = %p, next = %p, prev = %p\n",
+ (void *)node, nodetypestring(node->type),
+ (void *)node->key, node->key, node->data,
+ (void *)node->next, (void *)node->prev);
return(0);
}
@@ -509,8 +514,8 @@ printlist (list)
return;
}
- (void) printf("List at 0x%p: list = 0x%p, HASHSIZE = %d, next = 0x%p\n",
- list, list->list, HASHSIZE, list->next);
+ (void) printf("List at %p: list = %p, HASHSIZE = %d, next = %p\n",
+ (void *)list, (void *)list->list, HASHSIZE, (void *)list->next);
(void) walklist(list, printnode, NULL);
diff --git a/contrib/cvs/src/hash.h b/contrib/cvs/src/hash.h
index f98353d..edfee46 100644
--- a/contrib/cvs/src/hash.h
+++ b/contrib/cvs/src/hash.h
@@ -30,7 +30,7 @@ struct node
struct node *hashnext;
struct node *hashprev;
char *key;
- char *data;
+ void *data;
void (*delproc) ();
};
typedef struct node Node;
diff --git a/contrib/cvs/src/history.c b/contrib/cvs/src/history.c
index 076a9b1..8e8d607 100644
--- a/contrib/cvs/src/history.c
+++ b/contrib/cvs/src/history.c
@@ -21,6 +21,7 @@
* F "Release" cmd.
* W "Update" cmd - No User file, Remove from Entries file.
* U "Update" cmd - File was checked out over User file.
+ * P "Update" cmd - User file was patched.
* G "Update" cmd - File was merged successfully.
* C "Update" cmd - File was merged and shows overlaps.
* M "Commit" cmd - "Modified" file.
@@ -34,9 +35,9 @@
*
* CurDir The directory where the action occurred. This should be the
* absolute path of the directory which is at the same level as
- * the "Repository" field (for W,U,G,C & M,A,R).
+ * the "Repository" field (for W,U,P,G,C & M,A,R).
*
- * Repository For record types [W,U,G,C,M,A,R] this field holds the
+ * Repository For record types [W,U,P,G,C,M,A,R] this field holds the
* repository read from the administrative data where the
* command was typed.
* T "A" --> New Tag, "D" --> Delete Tag
@@ -48,11 +49,11 @@
* O,E The Tag or Date, if specified, else "" (null field).
* F "" (null field)
* W The Tag or Date, if specified, else "" (null field).
- * U The Revision checked out over the User file.
+ * U,P The Revision checked out over the User file.
* G,C The Revision(s) involved in merge.
* M,A,R RCS Revision affected.
*
- * argument The module (for [TOEUF]) or file (for [WUGCMAR]) affected.
+ * argument The module (for [TOEF]) or file (for [WUPGCMAR]) affected.
*
*
*** Report categories: "User" and "Since" modifiers apply to all reports.
@@ -60,7 +61,7 @@
*
* Extract list of record types
*
- * -e, -x [TOEFWUGCMAR]
+ * -e, -x [TOEFWUPGCMAR]
*
* Extracted records are simply printed, No analysis is performed.
* All "field" modifiers apply. -e chooses all types.
@@ -93,7 +94,7 @@
* modules are remembered. Only records matching exactly those
* files and repositories are shown. Sorting by "module", then
* filename, is implied. If -l ("last modified") is specified,
- * then "update" records (types WUCG), tag and release records
+ * then "update" records (types WUPCG), tag and release records
* are ignored and the last (by date) "modified" record.
*
* TAG history
@@ -170,7 +171,7 @@
* cvs hi -e -u user
*
*** Dump (eXtract) specified record types
- * cvs hi -x [TOFWUGCMAR]
+ * cvs hi -x [TOEFWUPGCMAR]
*
*
* FUTURE: J[Join], I[Import] (Not currently implemented.)
@@ -178,6 +179,7 @@
*/
#include "cvs.h"
+#include "history.h"
#include "savecwd.h"
static struct hrec
@@ -208,7 +210,6 @@ static void save_file PROTO((char *dir, char *name, char *module));
static void save_module PROTO((char *module));
static void save_user PROTO((char *name));
-#define ALL_REC_TYPES "TOEFWUCGMAR"
#define USER_INCREMENT 2
#define FILE_INCREMENT 128
#define MODULE_INCREMENT 5
@@ -217,6 +218,7 @@ static void save_user PROTO((char *name));
static short report_count;
static short extract;
+static short extract_all;
static short v_checkout;
static short modified;
static short tag_report;
@@ -234,7 +236,7 @@ static short tz_local;
static time_t tz_seconds_east_of_GMT;
static char *tz_name = "+0000";
-char *logHistory = ALL_REC_TYPES;
+char *logHistory = ALL_HISTORY_REC_TYPES;
/* -r, -t, or -b options, malloc'd. These are "" if the option in
question is not specified or is overridden by another option. The
@@ -290,7 +292,7 @@ static const char *const history_usg[] =
" -c Committed (Modified) files\n",
" -o Checked out modules\n",
" -m <module> Look for specified module (repeatable)\n",
- " -x [TOEFWUCGMAR] Extract by record type\n",
+ " -x [" ALL_HISTORY_REC_TYPES "] Extract by record type\n",
" -e Everything (same as -x, but all record types)\n",
" Flags:\n",
" -a All users (Default is self)\n",
@@ -399,9 +401,9 @@ history (argc, argv)
break;
case 'e':
report_count++;
- extract++;
+ extract_all++;
free (rec_types);
- rec_types = xstrdup (ALL_REC_TYPES);
+ rec_types = xstrdup (ALL_HISTORY_REC_TYPES);
break;
case 'l': /* Find Last file record */
last_entry = 1;
@@ -482,7 +484,7 @@ history (argc, argv)
char *cp;
for (cp = optarg; *cp; cp++)
- if (!strchr (ALL_REC_TYPES, *cp))
+ if (!strchr (ALL_HISTORY_REC_TYPES, *cp))
error (1, 0, "%c is not a valid report type", *cp);
}
free (rec_types);
@@ -584,6 +586,8 @@ history (argc, argv)
option_with_arg ("-t", since_tag);
for (mod = user_list; mod < &user_list[user_count]; ++mod)
option_with_arg ("-u", *mod);
+ if (extract_all)
+ send_arg("-e");
if (extract)
option_with_arg ("-x", rec_types);
option_with_arg ("-z", tz_name);
@@ -607,7 +611,7 @@ history (argc, argv)
(void) strcat (rec_types, "T");
}
}
- else if (extract)
+ else if (extract || extract_all)
{
if (user_list)
user_sort++;
@@ -636,7 +640,7 @@ history (argc, argv)
else if (module_report)
{
free (rec_types);
- rec_types = xstrdup (last_entry ? "OMAR" : ALL_REC_TYPES);
+ rec_types = xstrdup (last_entry ? "OMAR" : ALL_HISTORY_REC_TYPES);
module_sort++;
repos_sort++;
file_sort++;
@@ -697,22 +701,25 @@ history (argc, argv)
void
history_write (type, update_dir, revs, name, repository)
int type;
- char *update_dir;
- char *revs;
- char *name;
- char *repository;
+ const char *update_dir;
+ const char *revs;
+ const char *name;
+ const char *repository;
{
char *fname;
char *workdir;
char *username = getcaller ();
int fd;
char *line;
- char *slash = "", *cp, *cp2, *repos;
+ char *slash = "", *cp;
+ const char *cp2, *repos;
int i;
static char *tilde = "";
static char *PrCurDir = NULL;
- if (logoff) /* History is turned off by cmd line switch */
+ if (logoff) /* History is turned off by noexec or
+ * readonlyfs.
+ */
return;
if ( strchr(logHistory, type) == NULL )
return;
@@ -722,6 +729,15 @@ history_write (type, update_dir, revs, name, repository)
CVSROOTADM, CVSROOTADM_HISTORY);
/* turn off history logging if the history file does not exist */
+ /* FIXME: This should check for write permissions instead. This way,
+ * O_CREATE could be added back into the call to open() below and
+ * there would be no race condition involved in log rotation.
+ *
+ * Note that the new method of turning off logging would be either via
+ * the CVSROOT/config file (probably the quicker method, but would need
+ * to be added, or at least checked for, too) or by creating a dummy
+ * history file with 0444 permissions.
+ */
if (!isfile (fname))
{
logoff = 1;
@@ -733,7 +749,7 @@ history_write (type, update_dir, revs, name, repository)
CLIENT_SERVER_STR, fname);
if (noexec)
goto out;
- fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | O_CREAT | OPEN_BINARY, 0666);
+ fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | OPEN_BINARY, 0666);
if (fd < 0)
{
if (! really_quiet)
@@ -1524,6 +1540,7 @@ report_hrecs ()
break;
case 'W':
case 'U':
+ case 'P':
case 'C':
case 'G':
case 'M':
diff --git a/contrib/cvs/src/history.h b/contrib/cvs/src/history.h
new file mode 100644
index 0000000..fd65951
--- /dev/null
+++ b/contrib/cvs/src/history.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2003, Derek Price, Ximbiot <http://ximbiot.com>,
+ * and the Free Software Foundation
+ *
+ * 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 header file for definitions and functions shared by history.c
+ * with other portions of CVS.
+ */
+
+#define ALL_HISTORY_REC_TYPES "TOEFWUPCGMAR"
diff --git a/contrib/cvs/src/ignore.c b/contrib/cvs/src/ignore.c
index 54606a9..26c39e7 100644
--- a/contrib/cvs/src/ignore.c
+++ b/contrib/cvs/src/ignore.c
@@ -165,6 +165,8 @@ ign_add_file (file, hold)
free (line);
}
+
+
/* Parse a line of space-separated wildcards and add them to the list. */
void
ign_add (ign, hold)
@@ -183,6 +185,16 @@ ign_add (ign, hold)
if (isspace ((unsigned char) *ign))
continue;
+ /* If we have used up all the space, add some more. Do this before
+ processing `!', since an "empty" list still contains the `CVS'
+ entry. */
+ if (ign_count >= ign_size)
+ {
+ ign_size += IGN_GROW;
+ ign_list = (char **) xrealloc ((char *) ign_list,
+ (ign_size + 1) * sizeof (char *));
+ }
+
/*
* if we find a single character !, we must re-set the ignore list
* (saving it if necessary). We also catch * as a special case in a
@@ -198,8 +210,10 @@ ign_add (ign, hold)
for (i = 0; i < ign_count; i++)
free (ign_list[i]);
- ign_count = 0;
- ign_list[0] = NULL;
+ ign_count = 1;
+ /* Always ignore the "CVS" directory. */
+ ign_list[0] = xstrdup("CVS");
+ ign_list[1] = NULL;
/* if we are doing a '!', continue; otherwise add the '*' */
if (*ign == '!')
@@ -223,20 +237,14 @@ ign_add (ign, hold)
for (i = 0; i < ign_count; i++)
s_ign_list[i] = ign_list[i];
s_ign_count = ign_count;
- ign_count = 0;
- ign_list[0] = NULL;
+ ign_count = 1;
+ /* Always ignore the "CVS" directory. */
+ ign_list[0] = xstrdup ("CVS");
+ ign_list[1] = NULL;
continue;
}
}
- /* If we have used up all the space, add some more */
- if (ign_count >= ign_size)
- {
- ign_size += IGN_GROW;
- ign_list = (char **) xrealloc ((char *) ign_list,
- (ign_size + 1) * sizeof (char *));
- }
-
/* find the end of this token */
for (mark = ign; *mark && !isspace ((unsigned char) *mark); mark++)
/* do nothing */ ;
@@ -255,12 +263,11 @@ ign_add (ign, hold)
}
}
-/* Set to 1 if filenames should be matched in a case-insensitive
- fashion. Note that, contrary to the name and placement in ignore.c,
- this is no longer just for ignore patterns. */
-int ign_case;
-/* Return 1 if the given filename should be ignored by update or import. */
+
+/* Return true if the given filename should be ignored by update or import,
+ * else return false.
+ */
int
ign_name (name)
char *name;
@@ -268,47 +275,17 @@ ign_name (name)
char **cpp = ign_list;
if (cpp == NULL)
- return (0);
-
- if (ign_case)
- {
- /* We do a case-insensitive match by calling fnmatch on copies of
- the pattern and the name which have been converted to
- lowercase. FIXME: would be much cleaner to just unify this
- with the other case-insensitive fnmatch stuff (FOLD_FN_CHAR
- in lib/fnmatch.c; os2_fnmatch in emx/system.c). */
- char *name_lower;
- char *pat_lower;
- char *p;
-
- name_lower = xstrdup (name);
- for (p = name_lower; *p != '\0'; ++p)
- *p = tolower (*p);
- while (*cpp)
- {
- pat_lower = xstrdup (*cpp++);
- for (p = pat_lower; *p != '\0'; ++p)
- *p = tolower (*p);
- if (CVS_FNMATCH (pat_lower, name_lower, 0) == 0)
- goto matched;
- free (pat_lower);
- }
- free (name_lower);
- return 0;
- matched:
- free (name_lower);
- free (pat_lower);
- return 1;
- }
- else
- {
- while (*cpp)
- if (CVS_FNMATCH (*cpp++, name, 0) == 0)
- return 1;
return 0;
- }
+
+ while (*cpp)
+ if (CVS_FNMATCH (*cpp++, name, 0) == 0)
+ return 1;
+
+ return 0;
}
-
+
+
+
/* FIXME: This list of dirs to ignore stuff seems not to be used.
Really? send_dirent_proc and update_dirent_proc both call
ignore_directory and do_module calls ign_dir_add. No doubt could
@@ -340,7 +317,7 @@ ign_dir_add (name)
int
ignore_directory (name)
- char *name;
+ const char *name;
{
int i;
@@ -356,7 +333,9 @@ ignore_directory (name)
return 0;
}
-
+
+
+
/*
* Process the current directory, looking for files not in ILIST and
* not on the global ignore list for this directory. If we find one,
@@ -369,7 +348,7 @@ void
ignore_files (ilist, entries, update_dir, proc)
List *ilist;
List *entries;
- char *update_dir;
+ const char *update_dir;
Ignore_proc proc;
{
int subdirs;
@@ -377,7 +356,7 @@ ignore_files (ilist, entries, update_dir, proc)
struct dirent *dp;
struct stat sb;
char *file;
- char *xdir;
+ const char *xdir;
List *files;
Node *p;
@@ -386,9 +365,8 @@ ignore_files (ilist, entries, update_dir, proc)
subdirs = 0;
else
{
- struct stickydirtag *sdtp;
+ struct stickydirtag *sdtp = entries->list->data;
- sdtp = (struct stickydirtag *) entries->list->data;
subdirs = sdtp == NULL || sdtp->subdirs;
}
@@ -451,7 +429,7 @@ ignore_files (ilist, entries, update_dir, proc)
#ifdef DT_DIR
dp->d_type != DT_UNKNOWN ||
#endif
- lstat(file, &sb) != -1)
+ CVS_LSTAT (file, &sb) != -1)
{
if (
diff --git a/contrib/cvs/src/import.c b/contrib/cvs/src/import.c
index 6765d8e..1eb02cf 100644
--- a/contrib/cvs/src/import.c
+++ b/contrib/cvs/src/import.c
@@ -20,7 +20,7 @@
#include "savecwd.h"
#include <assert.h>
-static char *get_comment PROTO((char *user));
+static char *get_comment PROTO((const char *user));
static int add_rev PROTO((char *message, RCSNode *rcs, char *vfile,
char *vers));
static int add_tags PROTO((RCSNode *rcs, char *vfile, char *vtag, int targc,
@@ -91,7 +91,7 @@ import (argc, argv)
#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
- command_name);
+ cvs_cmd_name);
break;
case 'd':
#ifdef SERVER_SUPPORT
@@ -157,6 +157,21 @@ import (argc, argv)
use_file_modtime = 1;
#endif
+ /* Don't allow "CVS" as any directory in module path.
+ *
+ * Could abstract this to valid_module_path, but I don't think we'll need
+ * to call it from anywhere else.
+ */
+ if ((cp = strstr(argv[0], "CVS")) && /* path contains "CVS" AND ... */
+ ((cp == argv[0]) || ISDIRSEP(*(cp-1))) && /* /^CVS/ OR m#/CVS# AND ... */
+ ((*(cp+3) == '\0') || ISDIRSEP(*(cp+3))) /* /CVS$/ OR m#CVS/# */
+ )
+ {
+ error (0, 0,
+ "The word `CVS' is reserved by CVS and may not be used");
+ error (1, 0, "as a directory in a path or as a file name.");
+ }
+
for (i = 1; i < argc; i++) /* check the tags for validity */
{
int j;
@@ -168,8 +183,7 @@ import (argc, argv)
}
/* XXX - this should be a module, not just a pathname */
- if (! isabsolute (argv[0])
- && pathname_levels (argv[0]) == 0)
+ if (!isabsolute (argv[0]) && pathname_levels (argv[0]) == 0)
{
if (current_parsed_root == NULL)
{
@@ -379,7 +393,7 @@ import (argc, argv)
li->type = T_TITLE;
li->tag = xstrdup (vbranch);
li->rev_old = li->rev_new = NULL;
- p->data = (char *) li;
+ p->data = li;
(void) addnode (ulist, p);
Update_Logfile (repository, message, logfp, ulist);
dellist (&ulist);
@@ -573,7 +587,8 @@ process_import_file (message, vfile, vtag, targc, targv)
node = findnode_fn (entries, vfile);
if (node != NULL)
{
- Entnode *entdata = (Entnode *) node->data;
+ Entnode *entdata = node->data;
+
if (entdata->type == ENT_FILE)
{
assert (entdata->options[0] == '-'
@@ -653,7 +668,8 @@ update_rcs_file (message, vfile, vtag, targc, targv, inattic)
not NULL? */
expand = vers->srcfile->expand != NULL &&
vers->srcfile->expand[0] == 'b' ? "-kb" : "-ko";
- different = RCS_cmp_file (vers->srcfile, vers->vn_rcs, expand, vfile);
+ different = RCS_cmp_file( vers->srcfile, vers->vn_rcs, (char **)NULL,
+ (char *)NULL, expand, vfile );
if (tocvsPath)
if (unlink_file_dir (tocvsPath) < 0)
error (0, errno, "cannot remove %s", tocvsPath);
@@ -932,7 +948,7 @@ static const struct compair comtable[] =
static char *
get_comment (user)
- char *user;
+ const char *user;
{
char *cp, *suffix;
char *suffix_path;
@@ -988,34 +1004,34 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
add_vbranch, vtag, targc, targv,
desctext, desclen, add_logfp)
/* Log message for the addition. Not used if add_vhead == NULL. */
- char *message;
+ const char *message;
/* Filename of the RCS file to create. */
- char *rcs;
+ const char *rcs;
/* Filename of the file to serve as the contents of the initial
revision. Even if add_vhead is NULL, we use this to determine
the modes to give the new RCS file. */
- char *user;
+ const char *user;
/* Revision number of head that we are adding. Normally 1.1 but
could be another revision as long as ADD_VBRANCH is a branch
from it. If NULL, then just add an empty file without any
revisions (similar to the one created by "rcs -i"). */
- char *add_vhead;
+ const char *add_vhead;
/* Keyword expansion mode, e.g., "b" for binary. NULL means the
default behavior. */
- char *key_opt;
+ const char *key_opt;
/* Vendor branch to import to, or NULL if none. If non-NULL, then
vtag should also be non-NULL. */
- char *add_vbranch;
- char *vtag;
+ const char *add_vbranch;
+ const char *vtag;
int targc;
char *targv[];
/* If non-NULL, description for the file. If NULL, the description
will be empty. */
- char *desctext;
+ const char *desctext;
size_t desclen;
/* Write errors to here as well as via error (), or NULL if we should
@@ -1031,8 +1047,7 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
int i, ierrno, err = 0;
mode_t mode;
char *tocvsPath;
- char *userfile;
- char *local_opt = key_opt;
+ const char *userfile;
char *free_opt = NULL;
mode_t file_type;
@@ -1046,11 +1061,11 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
or the other. Before making a change of this sort, should think
about what is best, document it (in cvs.texinfo and NEWS), &c. */
- if (local_opt == NULL)
+ if (key_opt == NULL)
{
if (wrap_name_has (user, WRAP_RCSOPTION))
{
- local_opt = free_opt = wrap_rcsoption (user, 0);
+ key_opt = free_opt = wrap_rcsoption (user, 0);
}
}
@@ -1087,7 +1102,7 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
if (!preserve_perms || file_type == S_IFREG)
{
fpuser = CVS_FOPEN (userfile,
- ((local_opt != NULL && strcmp (local_opt, "b") == 0)
+ ((key_opt != NULL && strcmp (key_opt, "b") == 0)
? "rb"
: "r")
);
@@ -1157,9 +1172,9 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
goto write_error;
}
- if (local_opt != NULL && strcmp (local_opt, "kv") != 0)
+ if (key_opt != NULL && strcmp (key_opt, "kv") != 0)
{
- if (fprintf (fprcs, "expand @%s@;\012", local_opt) < 0)
+ if (fprintf (fprcs, "expand @%s@;\012", key_opt) < 0)
{
goto write_error;
}
@@ -1463,19 +1478,16 @@ read_error:
*/
int
expand_at_signs (buf, size, fp)
- char *buf;
+ const char *buf;
off_t size;
FILE *fp;
{
- register char *cp, *next;
+ register const char *cp, *next;
cp = buf;
while ((next = memchr (cp, '@', size)) != NULL)
{
- int len;
-
- ++next;
- len = next - cp;
+ size_t len = ++next - cp;
if (fwrite (cp, 1, len, fp) != len)
return EOF;
if (putc ('@', fp) == EOF)
diff --git a/contrib/cvs/src/lock.c b/contrib/cvs/src/lock.c
index 9333d9b..16e99d8 100644
--- a/contrib/cvs/src/lock.c
+++ b/contrib/cvs/src/lock.c
@@ -55,26 +55,28 @@
1. Check for EROFS. Maybe useful, although in the presence of NFS
EROFS does *not* mean that the file system is unchanging.
- 2. Provide a means to put the cvs locks in some directory apart from
- the repository (CVSROOT/locks; a -l option in modules; etc.).
-
- 3. Provide an option to disable locks for operations which only
+ 2. Provide an option to disable locks for operations which only
read (see above for some of the consequences).
- 4. Have a server internally do the locking. Probably a good
+ 3. Have a server internally do the locking. Probably a good
long-term solution, and many people have been working hard on code
changes which would eventually make it possible to have a server
which can handle various connections in one process, but there is
- much, much work still to be done before this is feasible.
-
- 5. Like #4 but use shared memory or something so that the servers
- merely need to all be on the same machine. This is a much smaller
- change to CVS (it functions much like #2; shared memory might be an
- unneeded complication although it presumably would be faster). */
+ much, much work still to be done before this is feasible. */
#include "cvs.h"
#include <assert.h>
+#ifdef HAVE_NANOSLEEP
+# include "xtime.h"
+#else /* HAVE_NANOSLEEP */
+# if !defined HAVE_USLEEP && defined HAVE_SELECT
+ /* use select as a workaround */
+# include "xselect.h"
+# endif /* !defined HAVE_USLEEP && defined HAVE_SELECT */
+#endif /* !HAVE_NANOSLEEP */
+
+
struct lock {
/* This is the directory in which we may have a lock named by the
readlock variable, a lock named by the writelock variable, and/or
@@ -341,7 +343,7 @@ unlock_proc (p, closure)
Node *p;
void *closure;
{
- lock_simple_remove ((struct lock *)p->data);
+ lock_simple_remove (p->data);
return (0);
}
@@ -388,6 +390,8 @@ lock_simple_remove (lock)
}
}
+
+
/*
* Create a lock file for readers
*/
@@ -404,13 +408,13 @@ Reader_Lock (xrepository)
xrepository);
if (noexec)
- return (0);
+ return 0;
/* we only do one directory at a time for read locks! */
if (global_readlock.repository != NULL)
{
error (0, 0, "Reader_Lock called while read locks set - Help!");
- return (1);
+ return 1;
}
if (readlock == NULL)
@@ -439,7 +443,7 @@ Reader_Lock (xrepository)
/* We don't set global_readlock.repository to NULL. I think this
only works because recurse.c will give a fatal error if we return
a nonzero value. */
- return (1);
+ return 1;
}
/* write a read-lock */
@@ -458,9 +462,11 @@ Reader_Lock (xrepository)
/* free the lock dir */
clear_lock (&global_readlock);
- return (err);
+ return err;
}
+
+
/*
* Lock a list of directories for writing
*/
@@ -476,13 +482,13 @@ Writer_Lock (list)
char *wait_repos;
if (noexec)
- return (0);
+ return 0;
/* We only know how to do one list at a time */
if (locklist != (List *) NULL)
{
error (0, 0, "Writer_Lock called while write locks set - Help!");
- return (1);
+ return 1;
}
wait_repos = NULL;
@@ -505,7 +511,7 @@ Writer_Lock (list)
free (wait_repos);
Lock_Cleanup (); /* clean up any locks we set */
error (0, 0, "lock failed - giving up");
- return (1);
+ return 1;
case L_LOCKED: /* Someone already had a lock */
remove_locks (); /* clean up any locks we set */
@@ -519,18 +525,20 @@ Writer_Lock (list)
lock_obtained (wait_repos);
free (wait_repos);
}
- return (0);
+ return 0;
default:
if (wait_repos != NULL)
free (wait_repos);
error (0, 0, "unknown lock status %d in Writer_Lock",
lock_error);
- return (1);
+ return 1;
}
}
}
+
+
/*
* walklist proc for setting write locks
*/
@@ -541,14 +549,16 @@ set_writelock_proc (p, closure)
{
/* if some lock was not OK, just skip this one */
if (lock_error != L_OK)
- return (0);
+ return 0;
/* apply the write lock */
lock_error_repos = p->key;
- lock_error = write_lock ((struct lock *)p->data);
- return (0);
+ lock_error = write_lock (p->data);
+ return 0;
}
+
+
/*
* Create a lock file for writers returns L_OK if lock set ok, L_LOCKED if
* lock held by someone else or L_ERROR if an error occurred
@@ -591,7 +601,7 @@ write_lock (lock)
}
/* indicate we failed due to read locks instead of error */
- return (L_LOCKED);
+ return L_LOCKED;
}
/* write the write-lock file */
@@ -613,15 +623,17 @@ write_lock (lock)
error (0, xerrno, "cannot create write lock in repository `%s'",
lock->repository);
free (tmp);
- return (L_ERROR);
+ return L_ERROR;
}
free (tmp);
- return (L_OK);
+ return L_OK;
}
else
- return (status);
+ return status;
}
+
+
/*
* readers_exist() returns 0 if there are no reader lock files remaining in
* the repository; else 1 is returned, to indicate that the caller should
@@ -631,6 +643,7 @@ static int
readers_exist (repository)
char *repository;
{
+ char *lockdir;
char *line;
DIR *dirp;
struct dirent *dp;
@@ -638,12 +651,15 @@ readers_exist (repository)
int ret;
#ifdef CVS_FUDGELOCKS
time_t now;
- (void) time (&now);
+ (void)time (&now);
#endif
+ lockdir = lock_name (repository, "");
+ lockdir[strlen (lockdir) - 1] = '\0'; /* remove trailing slash */
+
do {
- if ((dirp = CVS_OPENDIR (repository)) == NULL)
- error (1, 0, "cannot open directory %s", repository);
+ if ((dirp = CVS_OPENDIR (lockdir)) == NULL)
+ error (1, 0, "cannot open directory %s", lockdir);
ret = 0;
errno = 0;
@@ -651,13 +667,9 @@ readers_exist (repository)
{
if (CVS_FNMATCH (CVSRFLPAT, dp->d_name, 0) == 0)
{
- /* ignore our own readlock, if any */
- if (readlock && strcmp (readlock, dp->d_name) == 0)
- continue;
-
- line = xmalloc (strlen (repository) + strlen (dp->d_name) + 5);
- (void) sprintf (line, "%s/%s", repository, dp->d_name);
- if ( CVS_STAT (line, &sb) != -1)
+ line = xmalloc (strlen (lockdir) + 1 + strlen (dp->d_name) + 1);
+ (void)sprintf (line, "%s/%s", lockdir, dp->d_name);
+ if (CVS_STAT (line, &sb) != -1)
{
#ifdef CVS_FUDGELOCKS
/*
@@ -677,9 +689,10 @@ readers_exist (repository)
}
else
{
- /* If the file doesn't exist, it just means that it disappeared
- between the time we did the readdir and the time we did
- the stat. */
+ /* If the file doesn't exist, it just means that it
+ * disappeared between the time we did the readdir and the
+ * time we did the stat.
+ */
if (!existence_error (errno))
error (0, errno, "cannot stat %s", line);
}
@@ -695,9 +708,14 @@ readers_exist (repository)
CVS_CLOSEDIR (dirp);
} while (ret < 0);
- return (ret);
+
+ if (lockdir != NULL)
+ free (lockdir);
+ return ret;
}
+
+
/*
* Set the static variable lockers_name appropriately, based on the stat
* structure passed in.
@@ -710,22 +728,29 @@ set_lockers_name (statp)
if (lockers_name != NULL)
free (lockers_name);
- if ((pw = (struct passwd *) getpwuid (statp->st_uid)) !=
- (struct passwd *) NULL)
+ if ((pw = (struct passwd *)getpwuid (statp->st_uid)) !=
+ (struct passwd *)NULL)
{
lockers_name = xstrdup (pw->pw_name);
}
else
{
lockers_name = xmalloc (20);
- (void) sprintf (lockers_name, "uid%lu", (unsigned long) statp->st_uid);
+ (void)sprintf (lockers_name, "uid%lu", (unsigned long) statp->st_uid);
}
}
+
+
/*
- * Persistently tries to make the directory "lckdir",, which serves as a
- * lock. If the create time on the directory is greater than CVSLCKAGE
+ * Persistently tries to make the directory "lckdir", which serves as a
+ * lock.
+ *
+ * #ifdef CVS_FUDGELOCKS
+ * If the create time on the directory is greater than CVSLCKAGE
* seconds old, just try to remove the directory.
+ * #endif
+ *
*/
static int
set_lock (lock, will_wait)
@@ -733,6 +758,7 @@ set_lock (lock, will_wait)
int will_wait;
{
int waited;
+ long us;
struct stat sb;
mode_t omask;
#ifdef CVS_FUDGELOCKS
@@ -749,6 +775,7 @@ set_lock (lock, will_wait)
* directory before they exit.
*/
waited = 0;
+ us = 1;
lock->have_lckdir = 0;
for (;;)
{
@@ -810,6 +837,33 @@ set_lock (lock, will_wait)
/* if he wasn't willing to wait, return an error */
if (!will_wait)
return (L_LOCKED);
+
+ /* if possible, try a very short sleep without a message */
+ if (!waited && us < 1000)
+ {
+ us += us;
+#if defined HAVE_NANOSLEEP
+ {
+ struct timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = us * 1000;
+ (void)nanosleep (&ts, NULL);
+ continue;
+ }
+#elif defined HAVE_USLEEP
+ (void)usleep (us);
+ continue;
+#elif defined HAVE_SELECT
+ {
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = us;
+ (void)select (0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL, &tv);
+ continue;
+ }
+#endif
+ }
+
lock_wait (lock->repository);
waited = 1;
}
@@ -877,10 +931,13 @@ lock_obtained (repos)
cvs_flusherr ();
free (msg);
}
-
+
+
+
static int lock_filesdoneproc PROTO ((void *callerdat, int err,
- char *repository, char *update_dir,
- List *entries));
+ const char *repository,
+ const char *update_dir,
+ List *entries));
/*
* Create a list of repositories to lock
@@ -890,8 +947,8 @@ static int
lock_filesdoneproc (callerdat, err, repository, update_dir, entries)
void *callerdat;
int err;
- char *repository;
- char *update_dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
Node *p;
@@ -917,16 +974,15 @@ lock_tree_for_write (argc, argv, local, which, aflag)
int which;
int aflag;
{
- int err;
/*
* Run the recursion processor to find all the dirs to lock and lock all
* the dirs
*/
lock_tree_list = getlist ();
- err = start_recursion ((FILEPROC) NULL, lock_filesdoneproc,
- (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, argc,
- argv, local, which, aflag, CVS_LOCK_NONE,
- (char *) NULL, 0);
+ start_recursion ((FILEPROC) NULL, lock_filesdoneproc,
+ (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, argc,
+ argv, local, which, aflag, CVS_LOCK_NONE,
+ (char *) NULL, 0, (char *) NULL);
sortlist (lock_tree_list, fsortcmp);
if (Writer_Lock (lock_tree_list) != 0)
error (1, 0, "lock failed - giving up");
diff --git a/contrib/cvs/src/log.c b/contrib/cvs/src/log.c
index ce9ba5c0..1de1b94 100644
--- a/contrib/cvs/src/log.c
+++ b/contrib/cvs/src/log.c
@@ -115,9 +115,10 @@ struct log_data_and_rcs
static int rlog_proc PROTO((int argc, char **argv, char *xwhere,
char *mwhere, char *mfile, int shorten,
int local_specified, char *mname, char *msg));
-static Dtype log_dirproc PROTO ((void *callerdat, char *dir,
- char *repository, char *update_dir,
- List *entries));
+static Dtype log_dirproc PROTO ((void *callerdat, const char *dir,
+ const char *repository,
+ const char *update_dir,
+ List *entries));
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 *));
@@ -224,7 +225,7 @@ cvslog (argc, argv)
int local = 0;
struct option_revlist **prl;
- is_rlog = (strcmp (command_name, "rlog") == 0);
+ is_rlog = (strcmp (cvs_cmd_name, "rlog") == 0);
if (argc == -1)
usage (log_usage);
@@ -486,39 +487,46 @@ rlog_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg)
if (is_rlog)
{
- repository = xmalloc (strlen (current_parsed_root->directory) + strlen (argv[0])
+ repository = xmalloc (strlen (current_parsed_root->directory)
+ + strlen (argv[0])
+ (mfile == NULL ? 0 : strlen (mfile) + 1) + 2);
- (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]);
- where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) + 1)
+ (void)sprintf (repository, "%s/%s",
+ current_parsed_root->directory, argv[0]);
+ where = xmalloc (strlen (argv[0])
+ + (mfile == NULL ? 0 : strlen (mfile) + 1)
+ 1);
(void) strcpy (where, argv[0]);
- /* if mfile isn't null, we need to set up to do only part of the module */
+ /* If mfile isn't null, we need to set up to do only part of theu
+ * module.
+ */
if (mfile != NULL)
{
char *cp;
char *path;
- /* if the portion of the module is a path, put the dir part on repos */
+ /* If the portion of the module is a path, put the dir part on
+ * repos.
+ */
if ((cp = strrchr (mfile, '/')) != NULL)
{
*cp = '\0';
- (void) strcat (repository, "/");
- (void) strcat (repository, mfile);
- (void) strcat (where, "/");
- (void) strcat (where, mfile);
+ (void)strcat (repository, "/");
+ (void)strcat (repository, mfile);
+ (void)strcat (where, "/");
+ (void)strcat (where, mfile);
mfile = cp + 1;
}
/* take care of the rest */
path = xmalloc (strlen (repository) + strlen (mfile) + 5);
- (void) sprintf (path, "%s/%s", repository, mfile);
+ (void)sprintf (path, "%s/%s", repository, mfile);
if (isdir (path))
{
/* directory means repository gets the dir tacked on */
- (void) strcpy (repository, path);
- (void) strcat (where, "/");
- (void) strcat (where, mfile);
+ (void)strcpy (repository, path);
+ (void)strcat (where, "/");
+ (void)strcat (where, mfile);
}
else
{
@@ -531,19 +539,20 @@ rlog_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg)
}
/* cd to the starting repository */
- if ( CVS_CHDIR (repository) < 0)
+ if (CVS_CHDIR (repository) < 0)
{
error (0, errno, "cannot chdir to %s", repository);
free (repository);
- return (1);
+ free (where);
+ return 1;
}
- free (repository);
/* End section which is identical to patch_proc. */
which = W_REPOS | W_ATTIC;
}
else
{
+ repository = NULL;
where = NULL;
which = W_LOCAL | W_REPOS | W_ATTIC;
}
@@ -551,15 +560,19 @@ rlog_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg)
err = start_recursion (log_fileproc, (FILESDONEPROC) NULL, log_dirproc,
(DIRLEAVEPROC) NULL, (void *) &log_data,
argc - 1, argv + 1, local, which, 0, CVS_LOCK_READ,
- where, 1);
+ where, 1, repository);
+
+ if (!(which & W_LOCAL)) free (repository);
+ if (where) free (where);
+
return err;
}
+
/*
* Parse a revision list specification.
*/
-
static struct option_revlist *
log_parse_revlist (argstring)
const char *argstring;
@@ -783,6 +796,8 @@ printlock_proc (lock, foo)
return 0;
}
+
+
/*
* Do an rlog on a file
*/
@@ -796,7 +811,7 @@ log_fileproc (callerdat, finfo)
int selrev = -1;
RCSNode *rcsfile;
char buf[50];
- struct revlist *revlist;
+ struct revlist *revlist = NULL;
struct log_data_and_rcs log_data_and_rcs;
if ((rcsfile = finfo->rcs) == NULL)
@@ -805,22 +820,21 @@ log_fileproc (callerdat, finfo)
p = findnode (finfo->entries, finfo->file);
if (p != NULL)
{
- Entnode *e;
-
- e = (Entnode *) p->data;
+ Entnode *e = p->data;
+
if (e->version[0] == '0' && e->version[1] == '\0')
{
if (!really_quiet)
error (0, 0, "%s has been added, but not committed",
finfo->file);
- return(0);
+ return 0;
}
}
if (!really_quiet)
error (0, 0, "nothing known about %s", finfo->file);
- return (1);
+ return 1;
}
if (log_data->sup_header || !log_data->nameonly)
@@ -833,7 +847,8 @@ log_fileproc (callerdat, finfo)
revisions. */
revlist = log_expand_revlist (rcsfile, log_data->revlist,
log_data->default_branch);
- if (log_data->sup_header || (!log_data->header && !log_data->long_header))
+ if (log_data->sup_header
+ || (!log_data->header && !log_data->long_header))
{
log_data_and_rcs.log_data = log_data;
log_data_and_rcs.revlist = revlist;
@@ -846,11 +861,15 @@ log_fileproc (callerdat, finfo)
start date for each specific revision. */
if (log_data->singledatelist != NULL)
walklist (rcsfile->versions, log_fix_singledate,
- (void *) &log_data_and_rcs);
+ (void *)&log_data_and_rcs);
selrev = walklist (rcsfile->versions, log_count_print,
- (void *) &log_data_and_rcs);
- if (log_data->sup_header && selrev == 0) return 0;
+ (void *)&log_data_and_rcs);
+ if (log_data->sup_header && selrev == 0)
+ {
+ log_free_revlist (revlist);
+ return 0;
+ }
}
}
@@ -859,6 +878,7 @@ log_fileproc (callerdat, finfo)
{
cvs_output (rcsfile->path, 0);
cvs_output ("\n", 1);
+ log_free_revlist (revlist);
return 0;
}
@@ -915,7 +935,7 @@ log_fileproc (callerdat, finfo)
cvs_output ("\n\t", 2);
cp2 = cp;
- while (! isspace ((unsigned char) *cp2) && *cp2 != '\0')
+ while (!isspace ((unsigned char) *cp2) && *cp2 != '\0')
++cp2;
cvs_output (cp, cp2 - cp);
cp = cp2;
@@ -924,7 +944,7 @@ log_fileproc (callerdat, finfo)
}
}
- if (! log_data->notags)
+ if (!log_data->notags)
{
List *syms;
@@ -952,14 +972,14 @@ log_fileproc (callerdat, finfo)
cvs_output ("\n", 1);
- if (! log_data->header || log_data->long_header)
+ if (!log_data->header || log_data->long_header)
{
cvs_output ("description:\n", 0);
if (rcsfile->desc != NULL)
cvs_output (rcsfile->desc, 0);
}
- if (! log_data->header && ! log_data->long_header && rcsfile->head != NULL)
+ if (!log_data->header && ! log_data->long_header && rcsfile->head != NULL)
{
p = findnode (rcsfile->versions, rcsfile->head);
if (p == NULL)
@@ -967,9 +987,8 @@ log_fileproc (callerdat, finfo)
finfo->fullname);
while (p != NULL)
{
- RCSVers *vers;
+ RCSVers *vers = p->data;
- vers = (RCSVers *) p->data;
log_version (log_data, revlist, rcsfile, vers, 1);
if (vers->next == NULL)
p = NULL;
@@ -1009,6 +1028,8 @@ log_fileproc (callerdat, finfo)
return 0;
}
+
+
/*
* Fix up a revision list in order to compare it against versions.
* Expand any symbolic revisions.
@@ -1109,26 +1130,21 @@ log_expand_revlist (rcs, revlist, default_branch)
does. This code is a bit cryptic for my tastes, but
keeping the same implementation as rlog ensures a
certain degree of compatibility. */
- if (r->first == NULL)
+ if (r->first == NULL && nr->last != NULL)
{
- if (nr->last == NULL)
- nr->fields = 0;
+ nr->fields = numdots (nr->last) + 1;
+ if (nr->fields < 2)
+ nr->first = xstrdup (".0");
else
{
- nr->fields = numdots (nr->last) + 1;
- if (nr->fields < 2)
- nr->first = xstrdup (".0");
- else
- {
- char *cp;
+ char *cp;
- nr->first = xstrdup (nr->last);
- cp = strrchr (nr->first, '.');
- strcpy (cp + 1, "0");
- }
+ nr->first = xstrdup (nr->last);
+ cp = strrchr (nr->first, '.');
+ strcpy (cp + 1, "0");
}
}
- else if (r->last == NULL)
+ else if (r->last == NULL && nr->first != NULL)
{
nr->fields = numdots (nr->first) + 1;
nr->last = xstrdup (nr->first);
@@ -1377,6 +1393,8 @@ log_version_requested (log_data, revlist, rcs, vnode)
return 1;
}
+
+
/*
* Output a single symbol. This is called via walklist.
*/
@@ -1393,6 +1411,8 @@ log_symbol (p, closure)
return 0;
}
+
+
/*
* Count the number of entries on a list. This is called via walklist.
*/
@@ -1405,6 +1425,8 @@ log_count (p, closure)
return 1;
}
+
+
/*
* Sort out a single date specification by narrowing down the date
* until we find the specific selected revision.
@@ -1424,7 +1446,7 @@ log_fix_singledate (p, closure)
if (pv == NULL)
error (1, 0, "missing version `%s' in RCS file `%s'",
p->key, data->rcs->path);
- vnode = (RCSVers *) pv->data;
+ vnode = pv->data;
/* We are only interested if this revision passes any other tests.
Temporarily clear log_data->singledatelist to avoid confusing
@@ -1464,6 +1486,8 @@ log_fix_singledate (p, closure)
return 0;
}
+
+
/*
* Count the number of revisions we are going to print.
*/
@@ -1480,7 +1504,7 @@ log_count_print (p, closure)
error (1, 0, "missing version `%s' in RCS file `%s'",
p->key, data->rcs->path);
if (log_version_requested (data->log_data, data->revlist, data->rcs,
- (RCSVers *) pv->data))
+ pv->data))
return 1;
else
return 0;
@@ -1504,7 +1528,7 @@ log_tree (log_data, revlist, rcs, ver)
if (p == NULL)
error (1, 0, "missing version `%s' in RCS file `%s'",
ver, rcs->path);
- vnode = (RCSVers *) p->data;
+ vnode = p->data;
if (vnode->next != NULL)
log_tree (log_data, revlist, rcs, vnode->next);
if (vnode->branches != NULL)
@@ -1540,7 +1564,7 @@ log_abranch (log_data, revlist, rcs, ver)
if (p == NULL)
error (1, 0, "missing version `%s' in RCS file `%s'",
ver, rcs->path);
- vnode = (RCSVers *) p->data;
+ vnode = p->data;
if (vnode->next != NULL)
log_abranch (log_data, revlist, rcs, vnode->next);
log_version (log_data, revlist, rcs, vnode, 0);
@@ -1611,7 +1635,7 @@ log_version (log_data, revlist, rcs, ver, trunk)
if (nextp == NULL)
error (1, 0, "missing version `%s' in `%s'", ver->next,
rcs->path);
- nextver = (RCSVers *) nextp->data;
+ nextver = nextp->data;
pdel = findnode (nextver->other, ";add");
padd = findnode (nextver->other, ";delete");
}
@@ -1640,14 +1664,14 @@ log_version (log_data, revlist, rcs, ver, trunk)
would be the p == NULL case would mean an RCS file which was
missing the "log" keyword (which is illegal according to
rcsfile.5). */
- if (p == NULL || p->data == NULL || p->data[0] == '\0')
+ if (p == NULL || p->data == NULL || *(char *)p->data == '\0')
cvs_output ("*** empty log message ***\n", 0);
else
{
/* FIXME: Technically, the log message could contain a null
byte. */
cvs_output (p->data, 0);
- if (p->data[strlen (p->data) - 1] != '\n')
+ if (((char *)p->data)[strlen (p->data) - 1] != '\n')
cvs_output ("\n", 1);
}
}
@@ -1685,9 +1709,9 @@ log_branch (p, closure)
static Dtype
log_dirproc (callerdat, dir, repository, update_dir, entries)
void *callerdat;
- char *dir;
- char *repository;
- char *update_dir;
+ const char *dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
if (!isdir (dir))
diff --git a/contrib/cvs/src/login.c b/contrib/cvs/src/login.c
index 4d395dd..49622e8 100644
--- a/contrib/cvs/src/login.c
+++ b/contrib/cvs/src/login.c
@@ -12,12 +12,6 @@
#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */
-#ifdef HAVE_GETPASSPHRASE
-#define GETPASS getpassphrase
-#else
-#define GETPASS getpass
-#endif
-
/* There seems to be very little agreement on which system header
getpass is declared in. With a lot of fancy autoconfiscation,
we could perhaps detect this, but for now we'll just rely on
@@ -25,9 +19,6 @@
declaration won't work (some Crays declare the 2#$@% thing as
varadic, believe it or not). On Cray, getpass will be declared
in either stdlib.h or unistd.h. */
-#ifndef _CRAY
-extern char *GETPASS ();
-#endif
#ifndef CVS_PASSWORD_FILE
#define CVS_PASSWORD_FILE ".cvspass"
@@ -229,8 +220,10 @@ password_entry_parseline (cvsroot_canonical, warn, linenumber, linebuf)
*
* Mode Action
* password_entry_lookup Return the password
- * password_entry_delete Delete the entry from the file, if it exists
- * password_entry_add Replace the line with the new one, else append it
+ * password_entry_delete Delete the entry from the file, if it
+ * exists.
+ * password_entry_add Replace the line with the new one, else
+ * append it.
*
* Because the user might be accessing multiple repositories, with
* different passwords for each one, the format of ~/.cvspass is:
@@ -291,7 +284,7 @@ password_entry_operation (operation, root, newpassword)
char *cvsroot_canonical = NULL;
char *password = NULL;
int line_length;
- long line;
+ long line = -1;
char *linebuf = NULL;
size_t linebuf_len;
char *p;
@@ -299,7 +292,8 @@ password_entry_operation (operation, root, newpassword)
if (root->method != pserver_method)
{
- error (0, 0, "internal error: can only call password_entry_operation with pserver method");
+ error (0, 0, "\
+internal error: can only call password_entry_operation with pserver method");
error (1, 0, "CVSROOT: %s", root->original);
}
@@ -323,7 +317,8 @@ password_entry_operation (operation, root, newpassword)
while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
{
line++;
- password = password_entry_parseline(cvsroot_canonical, 1, line, linebuf);
+ password = password_entry_parseline (cvsroot_canonical, 1, line,
+ linebuf);
if (password != NULL)
/* this is it! break out and deal with linebuf */
break;
@@ -373,7 +368,8 @@ process:
* add
*/
if (!noexec && password != NULL && (operation == password_entry_delete
- || (operation == password_entry_add && strcmp (password, newpassword))))
+ || (operation == password_entry_add
+ && strcmp (password, newpassword))))
{
long found_at = line;
char *tmp_name;
@@ -394,7 +390,8 @@ process:
line++;
if (line < found_at
|| (line != found_at
- && !password_entry_parseline(cvsroot_canonical, 0, line, linebuf)))
+ && !password_entry_parseline (cvsroot_canonical, 0, line,
+ linebuf)))
{
if (fprintf (tmp_fp, "%s", linebuf) == EOF)
{
@@ -541,7 +538,7 @@ login (argc, argv)
else
{
char *tmp;
- tmp = GETPASS ("CVS password: ");
+ tmp = getpass ("CVS password: ");
/* Must deal with a NULL return value here. I haven't managed to
* disconnect the CVS process from the tty and force a NULL return
* in sanity.sh, but the Linux version of getpass is documented
@@ -560,7 +557,8 @@ login (argc, argv)
connect_to_pserver (current_parsed_root, NULL, NULL, 1, 0);
- password_entry_operation (password_entry_add, current_parsed_root, typed_password);
+ password_entry_operation (password_entry_add, current_parsed_root,
+ typed_password);
memset (typed_password, 0, strlen (typed_password));
free (typed_password);
@@ -572,6 +570,8 @@ login (argc, argv)
return 0;
}
+
+
/* Returns the _scrambled_ password. The server must descramble
before hashing and comparing. If password file not found, or
password not found in the file, just return NULL. */
@@ -579,7 +579,7 @@ char *
get_cvs_password ()
{
if (current_parsed_root->password)
- return (scramble(current_parsed_root->password));
+ return scramble (current_parsed_root->password);
/* If someone (i.e., login()) is calling connect_to_pserver() out of
context, then assume they have supplied the correct, scrambled
@@ -607,9 +607,12 @@ get_cvs_password ()
error (1, 0, "CVSROOT: %s", current_parsed_root->original);
}
- return password_entry_operation (password_entry_lookup, current_parsed_root, NULL);
+ return password_entry_operation (password_entry_lookup,
+ current_parsed_root, NULL);
}
+
+
static const char *const logout_usage[] =
{
"Usage: %s %s\n",
diff --git a/contrib/cvs/src/logmsg.c b/contrib/cvs/src/logmsg.c
index 5296e24..52a025a 100644
--- a/contrib/cvs/src/logmsg.c
+++ b/contrib/cvs/src/logmsg.c
@@ -13,14 +13,16 @@
static int find_type PROTO((Node * p, void *closure));
static int fmt_proc PROTO((Node * p, void *closure));
-static int logfile_write PROTO((char *repository, char *filter,
- char *message, FILE * logfp, List * changes));
-static int rcsinfo_proc PROTO((char *repository, char *template));
+static int logfile_write PROTO((const char *repository, const char *filter,
+ const char *message, FILE * logfp,
+ List * changes));
+static int rcsinfo_proc PROTO((const char *repository, const char *template));
static int title_proc PROTO((Node * p, void *closure));
-static int update_logfile_proc PROTO((char *repository, char *filter));
+static int update_logfile_proc PROTO((const char *repository,
+ const char *filter));
static void setup_tmpfile PROTO((FILE * xfp, char *xprefix, List * changes));
-static int editinfo_proc PROTO((char *repository, char *template));
-static int verifymsg_proc PROTO((char *repository, char *script));
+static int editinfo_proc PROTO((const char *repository, const char *template));
+static int verifymsg_proc PROTO((const char *repository, const char *script));
static FILE *fp;
static char *str_list;
@@ -104,9 +106,8 @@ find_type (p, closure)
Node *p;
void *closure;
{
- struct logfile_info *li;
+ struct logfile_info *li = p->data;
- li = (struct logfile_info *) p->data;
if (li->type == type)
return (1);
else
@@ -125,7 +126,7 @@ fmt_proc (p, closure)
{
struct logfile_info *li;
- li = (struct logfile_info *) p->data;
+ li = p->data;
if (li->type == type)
{
if (li->tag == NULL
@@ -182,9 +183,9 @@ fmt_proc (p, closure)
*/
void
do_editor (dir, messagep, repository, changes)
- char *dir;
+ const char *dir;
char **messagep;
- char *repository;
+ const char *repository;
List *changes;
{
static int reuse_log_message = 0;
@@ -413,7 +414,7 @@ do_editor (dir, messagep, repository, changes)
void
do_verify (messagep, repository)
char **messagep;
- char *repository;
+ const char *repository;
{
FILE *fp;
char *fname;
@@ -429,14 +430,14 @@ do_verify (messagep, repository)
/* FIXME? Do we really want to skip this on noexec? What do we do
for the other administrative files? */
- if (noexec)
+ if (noexec || repository == NULL)
return;
/* Get the name of the verification script to run */
- if (repository != NULL)
- (void) Parse_Info (CVSROOTADM_VERIFYMSG, repository,
- verifymsg_proc, 0);
+ if (Parse_Info (CVSROOTADM_VERIFYMSG, repository, verifymsg_proc, 0) > 0)
+ error (1, 0, "Message verification failed");
+
if (!verifymsg_script)
return;
@@ -550,6 +551,8 @@ do_verify (messagep, repository)
if (unlink_file (fname) < 0)
error (0, errno, "cannot remove %s", fname);
free (fname);
+ free( verifymsg_script );
+ verifymsg_script = NULL;
}
/*
@@ -560,8 +563,8 @@ do_verify (messagep, repository)
/* ARGSUSED */
static int
rcsinfo_proc (repository, template)
- char *repository;
- char *template;
+ const char *repository;
+ const char *template;
{
static char *last_template;
FILE *tfp;
@@ -602,13 +605,13 @@ rcsinfo_proc (repository, template)
* specified program as standard input.
*/
static FILE *logfp;
-static char *message;
+static const char *message;
static List *changes;
void
Update_Logfile (repository, xmessage, xlogfp, xchanges)
- char *repository;
- char *xmessage;
+ const char *repository;
+ const char *xmessage;
FILE *xlogfp;
List *xchanges;
{
@@ -625,17 +628,21 @@ Update_Logfile (repository, xmessage, xlogfp, xchanges)
(void) Parse_Info (CVSROOTADM_LOGINFO, repository, update_logfile_proc, 1);
}
+
+
/*
* callback proc to actually do the logfile write from Update_Logfile
*/
static int
update_logfile_proc (repository, filter)
- char *repository;
- char *filter;
+ const char *repository;
+ const char *filter;
{
- return (logfile_write (repository, filter, message, logfp, changes));
+ return logfile_write (repository, filter, message, logfp, changes);
}
+
+
/*
* concatenate each filename/version onto str_list
*/
@@ -644,10 +651,9 @@ title_proc (p, closure)
Node *p;
void *closure;
{
- struct logfile_info *li;
char *c;
+ struct logfile_info *li = p->data;
- li = (struct logfile_info *) p->data;
if (li->type == type)
{
/* Until we decide on the correct logging solution when we add
@@ -727,9 +733,9 @@ title_proc (p, closure)
*/
static int
logfile_write (repository, filter, message, logfp, changes)
- char *repository;
- char *filter;
- char *message;
+ const char *repository;
+ const char *filter;
+ const char *message;
FILE *logfp;
List *changes;
{
@@ -796,7 +802,7 @@ logfile_write (repository, filter, message, logfp, changes)
if (fmt_percent)
{
int len;
- char *srepos;
+ const char *srepos;
char *fmt_begin, *fmt_end; /* beginning and end of the
format string specified in
filter. */
@@ -927,7 +933,7 @@ logfile_write (repository, filter, message, logfp, changes)
}
setup_tmpfile (pipefp, "", changes);
- (void) fprintf (pipefp, "Log Message:\n%s\n", message);
+ (void) fprintf (pipefp, "Log Message:\n%s\n", (message) ? message : "");
if (logfp != (FILE *) 0)
{
(void) fprintf (pipefp, "Status:\n");
@@ -951,8 +957,8 @@ logfile_write (repository, filter, message, logfp, changes)
/* ARGSUSED */
static int
editinfo_proc(repository, editor)
- char *repository;
- char *editor;
+ const char *repository;
+ const char *editor;
{
/* nothing to do if the last match is the same as this one */
if (editinfo_editor && strcmp (editinfo_editor, editor) == 0)
@@ -969,8 +975,8 @@ editinfo_proc(repository, editor)
*/
static int
verifymsg_proc (repository, script)
- char *repository;
- char *script;
+ const char *repository;
+ const char *script;
{
if (verifymsg_script && strcmp (verifymsg_script, script) == 0)
return (0);
diff --git a/contrib/cvs/src/main.c b/contrib/cvs/src/main.c
index e925142..2bd7d88 100644
--- a/contrib/cvs/src/main.c
+++ b/contrib/cvs/src/main.c
@@ -21,9 +21,9 @@
extern int gethostname ();
#endif
-char *program_name;
-char *program_path;
-char *command_name;
+const char *program_name;
+const char *program_path;
+const char *cvs_cmd_name;
/* I'd dynamically allocate this, but it seems like gethostname
requires a fixed size array. If I'm remembering the RFCs right,
@@ -247,7 +247,6 @@ static const char *const opt_usage[] =
" -q Cause CVS to be somewhat quiet.\n",
" -r Make checked-out files read-only.\n",
" -w Make checked-out files read-write (default).\n",
- " -l Turn history logging off.\n",
" -n Do not execute anything that will change the disk.\n",
" -t Show trace of program execution -- try with -n.\n",
" -v CVS version and copyright.\n",
@@ -407,7 +406,7 @@ main (argc, argv)
int help = 0; /* Has the user asked for help? This
lets us support the `cvs -H cmd'
convention to give help for cmd. */
- static const char short_options[] = "+Qqrwtnlvb:T:e:d:Hfz:s:xa";
+ static const char short_options[] = "+Qqrwtnvb:T:e:d:Hfz:s:xa";
static struct option long_options[] =
{
{"help", 0, NULL, 'H'},
@@ -537,7 +536,6 @@ main (argc, argv)
break;
case 'n':
noexec = 1;
- case 'l': /* Fall through */
logoff = 1;
break;
case 'v':
@@ -545,7 +543,7 @@ main (argc, argv)
version (0, (char **) NULL);
(void) fputs ("\n", stdout);
(void) fputs ("\
-Copyright (c) 1989-2002 Brian Berliner, david d `zoo' zuhn, \n\
+Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
Jeff Polk, and other authors\n", stdout);
(void) fputs ("\n", stdout);
(void) fputs ("CVS may be copied only under the terms of the GNU General Public License,\n", stdout);
@@ -590,14 +588,19 @@ Copyright (c) 1989-2002 Brian Berliner, david d `zoo' zuhn, \n\
break;
case 'z':
#ifdef CLIENT_SUPPORT
- gzip_level = atoi (optarg);
- if (gzip_level < 0 || gzip_level > 9)
+ 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
+#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. */
+ * level, so that users can have it in their .cvsrc and not
+ * cause any trouble.
+ *
+ * We still parse the argument to -z for correctness since
+ * one user complained of being bitten by a run of
+ * `cvs -z -n up' which read -n as the argument to -z without
+ * complaining. */
break;
case 's':
variable_set (optarg);
@@ -634,24 +637,24 @@ Copyright (c) 1989-2002 Brian Berliner, david d `zoo' zuhn, \n\
/* Look up the command name. */
- command_name = argv[0];
+ cvs_cmd_name = argv[0];
for (cm = cmds; cm->fullname; cm++)
{
- if (cm->nick1 && !strcmp (command_name, cm->nick1))
+ if (cm->nick1 && !strcmp (cvs_cmd_name, cm->nick1))
break;
- if (cm->nick2 && !strcmp (command_name, cm->nick2))
+ if (cm->nick2 && !strcmp (cvs_cmd_name, cm->nick2))
break;
- if (!strcmp (command_name, cm->fullname))
+ if (!strcmp (cvs_cmd_name, cm->fullname))
break;
}
if (!cm->fullname)
{
- fprintf (stderr, "Unknown command: `%s'\n\n", command_name);
+ fprintf (stderr, "Unknown command: `%s'\n\n", cvs_cmd_name);
usage (cmd_usage);
}
else
- command_name = cm->fullname; /* Global pointer for later use */
+ cvs_cmd_name = cm->fullname; /* Global pointer for later use */
if (help)
{
@@ -685,18 +688,18 @@ Copyright (c) 1989-2002 Brian Berliner, david d `zoo' zuhn, \n\
running as Kerberos server as root. Do the authentication as
the very first thing, to minimize the amount of time we are
running as root. */
- if (strcmp (command_name, "kserver") == 0)
+ if (strcmp (cvs_cmd_name, "kserver") == 0)
{
kserver_authenticate_connection ();
/* Pretend we were invoked as a plain server. */
- command_name = "server";
+ cvs_cmd_name = "server";
}
# endif /* HAVE_KERBEROS */
# if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
- if (strcmp (command_name, "pserver") == 0)
+ if (strcmp (cvs_cmd_name, "pserver") == 0)
{
/* The reason that --allow-root is not a command option
is mainly the comment in server() about how argc,argv
@@ -710,11 +713,11 @@ Copyright (c) 1989-2002 Brian Berliner, david d `zoo' zuhn, \n\
pserver_authenticate_connection ();
/* Pretend we were invoked as a plain server. */
- command_name = "server";
+ cvs_cmd_name = "server";
}
# endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */
- server_active = strcmp (command_name, "server") == 0;
+ server_active = strcmp (cvs_cmd_name, "server") == 0;
#endif /* SERVER_SUPPORT */
@@ -781,7 +784,7 @@ Copyright (c) 1989-2002 Brian Berliner, david d `zoo' zuhn, \n\
#endif /* KLUDGE_FOR_WNT_TESTSUITE */
if (use_cvsrc)
- read_cvsrc (&argc, &argv, command_name);
+ read_cvsrc (&argc, &argv, cvs_cmd_name);
#ifdef SERVER_SUPPORT
/* Fiddling with CVSROOT doesn't make sense if we're running
@@ -922,7 +925,7 @@ Copyright (c) 1989-2002 Brian Berliner, david d `zoo' zuhn, \n\
{
save_errno = errno;
/* If this is "cvs init", the root need not exist yet. */
- if (strcmp (command_name, "init") != 0)
+ if (strcmp (cvs_cmd_name, "init") != 0)
{
error (1, save_errno, "%s", path);
}
@@ -1020,7 +1023,11 @@ Copyright (c) 1989-2002 Brian Berliner, david d `zoo' zuhn, \n\
Lock_Cleanup ();
- free (program_path);
+ /* It's okay to cast out the const below since we know we allocated this in
+ * this function. The const was to keep other functions from messing with
+ * this.
+ */
+ free ((char *)program_path);
if (CVSroot_cmdline != NULL)
free (CVSroot_cmdline);
if (free_CVSroot)
@@ -1154,7 +1161,7 @@ void
usage (cpp)
register const char *const *cpp;
{
- (void) fprintf (stderr, *cpp++, program_name, command_name);
+ (void) fprintf (stderr, *cpp++, program_name, cvs_cmd_name);
for (; *cpp; cpp++)
(void) fprintf (stderr, *cpp);
error_exit ();
diff --git a/contrib/cvs/src/mkmodules.c b/contrib/cvs/src/mkmodules.c
index df6fea1..4ed3291 100644
--- a/contrib/cvs/src/mkmodules.c
+++ b/contrib/cvs/src/mkmodules.c
@@ -6,8 +6,9 @@
* specified in the README file that comes with the CVS kit. */
#include "cvs.h"
-#include "savecwd.h"
#include "getline.h"
+#include "history.h"
+#include "savecwd.h"
#ifndef DBLKSIZ
#define DBLKSIZ 4096 /* since GNU ndbm doesn't define it */
@@ -197,7 +198,7 @@ static const char *const checkoutlist_contents[] = {
"#\n",
"# File format:\n",
"#\n",
- "# [<whitespace>]<filename><whitespace><error message><end-of-line>\n",
+ "# [<whitespace>]<filename>[<whitespace><error message>]<end-of-line>\n",
"#\n",
"# comment lines begin with '#'\n",
NULL
@@ -296,9 +297,9 @@ static const char *const config_contents[] = {
"# command.\n",
"#TopLevelAdmin=no\n",
"\n",
- "# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the\n",
+ "# Set `LogHistory' to `all' or `" ALL_HISTORY_REC_TYPES "' to log all transactions to the\n",
"# history file, or a subset as needed (ie `TMAR' logs all write operations)\n",
- "#LogHistory=TOFEWGCMAR\n",
+ "#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",
@@ -460,7 +461,7 @@ mkmodules (dir)
{
/*
* File format:
- * [<whitespace>]<filename><whitespace><error message><end-of-line>
+ * [<whitespace>]<filename>[<whitespace><error message>]<end-of-line>
*
* comment lines begin with '#'
*/
@@ -491,12 +492,13 @@ mkmodules (dir)
}
else
{
+ /* Skip leading white space before the error message. */
for (cp++;
- cp < last && *last && isspace ((unsigned char) *last);
+ cp < last && *cp && isspace ((unsigned char) *cp);
cp++)
;
if (cp < last && *cp)
- error (0, 0, cp, fname);
+ error (0, 0, "%s", cp);
}
if (unlink_file (temp) < 0
&& !existence_error (errno))
@@ -848,7 +850,7 @@ init (argc, argv)
/* Name of ,v file for this administrative file. */
char *info_v;
/* Exit status. */
- int err;
+ int err = 0;
const struct admin_file *fileptr;
@@ -980,5 +982,5 @@ init (argc, argv)
mkmodules (adm);
free (adm);
- return 0;
+ return err;
}
diff --git a/contrib/cvs/src/modules.c b/contrib/cvs/src/modules.c
index b2ded8d..a784a86 100644
--- a/contrib/cvs/src/modules.c
+++ b/contrib/cvs/src/modules.c
@@ -3,7 +3,8 @@
* 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.
+ * as specified in the README file that comes with the CVS source
+ * distribution.
*
* Modules
*
@@ -30,7 +31,7 @@
/* Options in modules file. Note that it is OK to use GNU getopt features;
we already are arranging to make sure we are using the getopt distributed
with CVS. */
-#define CVSMODULE_OPTS "+ad:i:lo:e:s:t:u:"
+#define CVSMODULE_OPTS "+ad:lo:e:s:t:"
/* Special delimiter. */
#define CVSMODULE_SPEC '&'
@@ -91,14 +92,17 @@ close_module (db)
dbm_close (db);
}
+
+
/*
* This is the recursive function that processes a module name.
* It calls back the passed routine for each directory of a module
* It runs the post checkout or post tag proc from the modules file
*/
-int
-do_module (db, mname, m_type, msg, callback_proc, where, shorten,
- local_specified, run_module_prog, build_dirs, extra_arg)
+static int
+my_module (db, mname, m_type, msg, callback_proc, where, shorten,
+ local_specified, run_module_prog, build_dirs, extra_arg,
+ stack)
DBM *db;
char *mname;
enum mtype m_type;
@@ -110,12 +114,11 @@ do_module (db, mname, m_type, msg, callback_proc, where, shorten,
int run_module_prog;
int build_dirs;
char *extra_arg;
+ List *stack;
{
- char *checkin_prog = NULL;
char *checkout_prog = NULL;
char *export_prog = NULL;
char *tag_prog = NULL;
- char *update_prog = NULL;
struct saved_cwd cwd;
int cwd_saved = 0;
char *line;
@@ -150,7 +153,7 @@ do_module (db, mname, m_type, msg, callback_proc, where, shorten,
+ strlen (msg)
+ (where ? strlen (where) : 0)
+ (extra_arg ? strlen (extra_arg) : 0));
- sprintf (buf, "%s-> do_module (%s, %s, %s, %s)\n",
+ sprintf (buf, "%s-> my_module (%s, %s, %s, %s)\n",
CLIENT_SERVER_STR,
mname, msg, where ? where : "",
extra_arg ? extra_arg : "");
@@ -170,6 +173,13 @@ do_module (db, mname, m_type, msg, callback_proc, where, shorten,
if (isabsolute (mname))
error (1, 0, "Absolute module reference invalid: `%s'", mname);
+ /* Similarly for directories that attempt to step above the root of the
+ * repository.
+ */
+ if (pathname_levels (mname) > 0)
+ error (1, 0, "up-level in module reference (`..') invalid: `%s'.",
+ mname);
+
/* if this is a directory to ignore, add it to that list */
if (mname[0] == '!' && mname[1] != '\0')
{
@@ -238,7 +248,8 @@ do_module (db, mname, m_type, msg, callback_proc, where, shorten,
*acp = '/';
}
else
- (void) sprintf (attic_file, "%s/%s/%s%s", current_parsed_root->directory,
+ (void) sprintf (attic_file, "%s/%s/%s%s",
+ current_parsed_root->directory,
CVSATTIC, mname, RCSEXT);
if (isdir (file))
@@ -440,12 +451,6 @@ do_module (db, mname, m_type, msg, callback_proc, where, shorten,
mwhere = xstrdup (optarg);
nonalias_opt = 1;
break;
- case 'i':
- if (checkin_prog)
- free (checkin_prog);
- checkin_prog = xstrdup (optarg);
- nonalias_opt = 1;
- break;
case 'l':
local_specified = 1;
nonalias_opt = 1;
@@ -468,12 +473,6 @@ do_module (db, mname, m_type, msg, callback_proc, where, shorten,
tag_prog = xstrdup (optarg);
nonalias_opt = 1;
break;
- case 'u':
- if (update_prog)
- free (update_prog);
- update_prog = xstrdup (optarg);
- nonalias_opt = 1;
- break;
case '?':
error (0, 0,
"modules file has invalid option for key %s value %s",
@@ -510,14 +509,33 @@ do_module (db, mname, m_type, msg, callback_proc, where, shorten,
for (i = 0; i < modargc; i++)
{
- if (strcmp (mname, modargv[i]) == 0)
+ /*
+ * Recursion check: if an alias module calls itself or a module
+ * which causes the first to be called again, print an error
+ * message and stop recursing.
+ *
+ * Algorithm:
+ *
+ * 1. Check that MNAME isn't in the stack.
+ * 2. Push MNAME onto the stack.
+ * 3. Call do_module().
+ * 4. Pop MNAME from the stack.
+ */
+ if (stack && findnode (stack, mname))
error (0, 0,
"module `%s' in modules file contains infinite loop",
mname);
else
- err += do_module (db, modargv[i], m_type, msg, callback_proc,
- where, shorten, local_specified,
- run_module_prog, build_dirs, extra_arg);
+ {
+ if (!stack) stack = getlist();
+ push_string (stack, mname);
+ err += my_module (db, modargv[i], m_type, msg, callback_proc,
+ where, shorten, local_specified,
+ run_module_prog, build_dirs, extra_arg,
+ stack);
+ pop_string (stack);
+ if (isempty (stack)) dellist (&stack);
+ }
}
goto do_module_return;
}
@@ -552,7 +570,7 @@ module `%s' is a request for a file in a module which is not a directory",
/* XXX - think about making null repositories at each dir here
instead of just at the bottom */
make_directories (dir);
- if ( CVS_CHDIR (dir) < 0)
+ if (CVS_CHDIR (dir) < 0)
{
error (0, errno, "cannot chdir to %s", dir);
spec_opt = NULL;
@@ -654,9 +672,10 @@ module `%s' is a request for a file in a module which is not a directory",
error (0, 0, "Mal-formed %c option for module %s - ignored",
CVSMODULE_SPEC, mname);
else
- err += do_module (db, spec_opt, m_type, msg, callback_proc,
- (char *) NULL, 0, local_specified,
- run_module_prog, build_dirs, extra_arg);
+ err += my_module (db, spec_opt, m_type, msg, callback_proc,
+ (char *) NULL, 0, local_specified,
+ run_module_prog, build_dirs, extra_arg,
+ stack);
spec_opt = next_opt;
}
@@ -668,40 +687,6 @@ module `%s' is a request for a file in a module which is not a directory",
}
#endif
- /* run/write out the checkin/update prog files if necessary */
- if (err == 0 && !noexec && m_type == CHECKOUT && run_module_prog)
- {
-#ifdef SERVER_SUPPORT
- if (server_active) {
- if (checkin_prog != NULL)
- server_prog (where ? where : mwhere ? mwhere : mname, checkin_prog, PROG_CHECKIN);
- if (update_prog != NULL)
- server_prog (where ? where : mwhere ? mwhere : mname, update_prog, PROG_UPDATE);
- }
- else
- {
-#endif
- FILE *fp;
-
- if (checkin_prog != NULL)
- {
- fp = open_file (CVSADM_CIPROG, "w+");
- (void) fprintf (fp, "%s\n", checkin_prog);
- if (fclose (fp) == EOF)
- error (1, errno, "cannot close %s", CVSADM_CIPROG);
- }
- if (update_prog != NULL)
- {
- fp = open_file (CVSADM_UPROG, "w+");
- (void) fprintf (fp, "%s\n", update_prog);
- if (fclose (fp) == EOF)
- error (1, errno, "cannot close %s", CVSADM_UPROG);
- }
-#ifdef SERVER_SUPPORT
- }
-#endif
- }
-
/* cd back to where we started */
if (restore_cwd (&cwd, NULL))
error_exit ();
@@ -750,7 +735,7 @@ module `%s' is a request for a file in a module which is not a directory",
{
cvs_output (program_name, 0);
cvs_output (" ", 1);
- cvs_output (command_name, 0);
+ cvs_output (cvs_cmd_name, 0);
cvs_output (": Executing '", 0);
run_print (stdout);
cvs_output ("'\n", 0);
@@ -769,16 +754,12 @@ module `%s' is a request for a file in a module which is not a directory",
free_names (&xmodargc, xmodargv);
if (mwhere)
free (mwhere);
- if (checkin_prog)
- free (checkin_prog);
if (checkout_prog)
free (checkout_prog);
if (export_prog)
free (export_prog);
if (tag_prog)
free (tag_prog);
- if (update_prog)
- free (update_prog);
if (cwd_saved)
free_cwd (&cwd);
if (value != NULL)
@@ -789,6 +770,33 @@ module `%s' is a request for a file in a module which is not a directory",
return (err);
}
+
+
+/* External face of do_module so that we can have an internal version which
+ * accepts a stack argument to track alias recursion.
+ */
+int
+do_module (db, mname, m_type, msg, callback_proc, where, shorten,
+ local_specified, run_module_prog, build_dirs, extra_arg)
+ DBM *db;
+ char *mname;
+ enum mtype m_type;
+ char *msg;
+ CALLBACKPROC callback_proc;
+ char *where;
+ int shorten;
+ int local_specified;
+ int run_module_prog;
+ int build_dirs;
+ char *extra_arg;
+{
+ return my_module (db, mname, m_type, msg, callback_proc, where, shorten,
+ local_specified, run_module_prog, build_dirs, extra_arg,
+ NULL);
+}
+
+
+
/* - Read all the records from the modules database into an array.
- Sort the array depending on what format is desired.
- Print the array in the format desired.
@@ -799,7 +807,7 @@ module `%s' is a request for a file in a module which is not a directory",
files and the comment field: (Including aliases)
modulename -s switches, one per line, even if
- -i it has many switches.
+ it has many switches.
Directories and files involved, formatted
to cover multiple lines if necessary.
# Comment, also formatted to cover multiple
diff --git a/contrib/cvs/src/myndbm.c b/contrib/cvs/src/myndbm.c
index aa71ca8..a5afcce 100644
--- a/contrib/cvs/src/myndbm.c
+++ b/contrib/cvs/src/myndbm.c
@@ -19,7 +19,7 @@
#ifdef MY_NDBM
# ifndef O_ACCMODE
-# define O_ACCMODE O_RDONLY|O_WRONLY|O_RDWR
+# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
# endif /* defined O_ACCMODE */
static void mydbm_load_file PROTO ((FILE *, List *, char *));
@@ -181,12 +181,12 @@ mydbm_store (db, key, value, flags)
node->type = NDBMNODE;
node->key = xmalloc (key.dsize + 1);
- strncpy (node->key, key.dptr, key.dsize);
- node->key[key.dsize] = '\0';
+ *node->key = '\0';
+ strncat (node->key, key.dptr, key.dsize);
node->data = xmalloc (value.dsize + 1);
- strncpy (node->data, value.dptr, value.dsize);
- node->data[value.dsize] = '\0';
+ *(char *)node->data = '\0';
+ strncat (node->data, value.dptr, value.dsize);
db->modified = 1;
if (addnode (db->dbm_list, node) == -1)
diff --git a/contrib/cvs/src/no_diff.c b/contrib/cvs/src/no_diff.c
index dfca372..ebddcd3 100644
--- a/contrib/cvs/src/no_diff.c
+++ b/contrib/cvs/src/no_diff.c
@@ -8,7 +8,7 @@
* No Difference
*
* The user file looks modified judging from its time stamp; however it needn't
- * be. No_difference() finds out whether it is or not. If it is not, it
+ * be. No_Difference() finds out whether it is or not. If it is not, it
* updates the administration.
*
* returns 0 if no differences are found and non-zero otherwise
@@ -49,8 +49,9 @@ No_Difference (finfo, vers)
options = xstrdup ("");
tocvsPath = wrap_tocvs_process_file (finfo->file);
- retcode = RCS_cmp_file (vers->srcfile, vers->vn_user, options,
- tocvsPath == NULL ? finfo->file : tocvsPath);
+ retcode = RCS_cmp_file( vers->srcfile, vers->vn_user, (char **)NULL,
+ (char *)NULL, options,
+ tocvsPath == NULL ? finfo->file : tocvsPath );
if (retcode == 0)
{
/* no difference was found, so fix the entries file */
@@ -70,7 +71,7 @@ No_Difference (finfo, vers)
/* update the entdata pointer in the vers_ts structure */
p = findnode (finfo->entries, finfo->file);
- vers->entdata = (Entnode *) p->data;
+ vers->entdata = p->data;
ret = 0;
}
diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c
index 9771692..27f7d79 100644
--- a/contrib/cvs/src/parseinfo.c
+++ b/contrib/cvs/src/parseinfo.c
@@ -14,15 +14,16 @@ extern char *logHistory;
/*
* Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for
- * the first line in the file that matches the REPOSITORY, or if ALL != 0, any lines
- * matching "ALL", or if no lines match, the last line matching "DEFAULT".
+ * the first line in the file that matches the REPOSITORY, or if ALL != 0, any
+ * lines matching "ALL", or if no lines match, the last line matching
+ * "DEFAULT".
*
* Return 0 for success, -1 if there was not an INFOFILE, and >0 for failure.
*/
int
Parse_Info (infofile, repository, callproc, all)
- char *infofile;
- char *repository;
+ const char *infofile;
+ const char *repository;
CALLPROC callproc;
int all;
{
@@ -32,9 +33,11 @@ Parse_Info (infofile, repository, callproc, all)
char *line = NULL;
size_t line_allocated = 0;
char *default_value = NULL;
- char *expanded_value= NULL;
+ int default_line = 0;
+ char *expanded_value;
int callback_done, line_number;
- char *cp, *exp, *value, *srepos, bad;
+ char *cp, *exp, *value;
+ const char *srepos;
const char *regex_err;
if (current_parsed_root == NULL)
@@ -114,10 +117,6 @@ Parse_Info (infofile, repository, callproc, all)
if ((cp = strrchr (value, '\n')) != NULL)
*cp = '\0';
- if (expanded_value != NULL)
- free (expanded_value);
- expanded_value = expand_path (value, infofile, line_number);
-
/*
* At this point, exp points to the regular expression, and value
* points to the value to call the callback routine with. Evaluate
@@ -128,12 +127,14 @@ Parse_Info (infofile, repository, callproc, all)
/* save the default value so we have it later if we need it */
if (strcmp (exp, "DEFAULT") == 0)
{
- /* Is it OK to silently ignore all but the last DEFAULT
- expression? */
- if (default_value != NULL && default_value != &bad)
+ if (default_value != NULL)
+ {
+ error (0, 0, "Multiple `DEFAULT' lines (%d and %d) in %s file",
+ default_line, line_number, infofile);
free (default_value);
- default_value = (expanded_value != NULL ?
- xstrdup (expanded_value) : &bad);
+ }
+ default_value = xstrdup(value);
+ default_line = line_number;
continue;
}
@@ -147,8 +148,12 @@ Parse_Info (infofile, repository, callproc, all)
if (!all)
error(0, 0, "Keyword `ALL' is ignored at line %d in %s file",
line_number, infofile);
- else if (expanded_value != NULL)
+ else if ((expanded_value = expand_path (value, infofile,
+ line_number)) != NULL)
+ {
err += callproc (repository, expanded_value);
+ free (expanded_value);
+ }
else
err++;
continue;
@@ -169,8 +174,11 @@ Parse_Info (infofile, repository, callproc, all)
continue; /* no match */
/* it did, so do the callback and note that we did one */
- if (expanded_value != NULL)
+ if ((expanded_value = expand_path (value, infofile, line_number)) != NULL)
+ {
err += callproc (repository, expanded_value);
+ free (expanded_value);
+ }
else
err++;
callback_done = 1;
@@ -183,17 +191,18 @@ Parse_Info (infofile, repository, callproc, all)
/* if we fell through and didn't callback at all, do the default */
if (callback_done == 0 && default_value != NULL)
{
- if (default_value != &bad)
- err += callproc (repository, default_value);
+ if ((expanded_value = expand_path (default_value, infofile, default_line)) != NULL)
+ {
+ err += callproc (repository, expanded_value);
+ free (expanded_value);
+ }
else
err++;
}
/* free up space if necessary */
- if (default_value != NULL && default_value != &bad)
+ if (default_value != NULL)
free (default_value);
- if (expanded_value != NULL)
- free (expanded_value);
free (infopath);
if (line != NULL)
free (line);
@@ -209,8 +218,9 @@ Parse_Info (infofile, repository, callproc, all)
KEYWORD=VALUE. There is currently no way to have a multi-line
VALUE (would be nice if there was, probably).
- CVSROOT is the $CVSROOT directory (current_parsed_root->directory might not be
- set yet).
+ CVSROOT is the $CVSROOT directory
+ (current_parsed_root->directory might not be set yet, so this
+ function takes the cvsroot as a function argument).
Returns 0 for success, negative value for failure. Call
error(0, ...) on errors in addition to the return value. */
@@ -285,7 +295,7 @@ parse_config (cvsroot)
for making sure the syntax is consistent. Any good examples
to follow there (Apache?)? */
- /* Strip the training newline. There will be one unless we
+ /* Strip the trailing newline. There will be one unless we
read a partial line without a newline, and then got end of
file (or error?). */
diff --git a/contrib/cvs/src/patch.c b/contrib/cvs/src/patch.c
index e6a25f5..cba6a8a 100644
--- a/contrib/cvs/src/patch.c
+++ b/contrib/cvs/src/patch.c
@@ -17,8 +17,8 @@
#include "getline.h"
static RETSIGTYPE patch_cleanup PROTO((void));
-static Dtype patch_dirproc PROTO ((void *callerdat, char *dir,
- char *repos, char *update_dir,
+static Dtype patch_dirproc PROTO ((void *callerdat, const char *dir,
+ const char *repos, const char *update_dir,
List *entries));
static int patch_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static int patch_proc PROTO((int argc, char **argv, char *xwhere,
@@ -58,6 +58,8 @@ static const char *const patch_usage[] =
NULL
};
+
+
int
patch (argc, argv)
int argc;
@@ -86,7 +88,7 @@ patch (argc, argv)
#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
- command_name);
+ cvs_cmd_name);
break;
case 'f':
force_tag_match = 0;
@@ -232,34 +234,36 @@ patch (argc, argv)
/* clean up if we get a signal */
#ifdef SIGABRT
- (void) SIG_register (SIGABRT, patch_cleanup);
+ (void)SIG_register (SIGABRT, patch_cleanup);
#endif
#ifdef SIGHUP
- (void) SIG_register (SIGHUP, patch_cleanup);
+ (void)SIG_register (SIGHUP, patch_cleanup);
#endif
#ifdef SIGINT
- (void) SIG_register (SIGINT, patch_cleanup);
+ (void)SIG_register (SIGINT, patch_cleanup);
#endif
#ifdef SIGQUIT
- (void) SIG_register (SIGQUIT, patch_cleanup);
+ (void)SIG_register (SIGQUIT, patch_cleanup);
#endif
#ifdef SIGPIPE
- (void) SIG_register (SIGPIPE, patch_cleanup);
+ (void)SIG_register (SIGPIPE, patch_cleanup);
#endif
#ifdef SIGTERM
- (void) SIG_register (SIGTERM, patch_cleanup);
+ (void)SIG_register (SIGTERM, patch_cleanup);
#endif
db = open_module ();
for (i = 0; i < argc; i++)
err += do_module (db, argv[i], PATCH, "Patching", patch_proc,
- (char *) NULL, 0, 0, 0, 0, (char *) NULL);
+ (char *)NULL, 0, local, 0, 0, (char *)NULL);
close_module (db);
free (options);
patch_cleanup ();
- return (err);
+ return err;
}
+
+
/*
* callback proc for doing the real work of patching
*/
@@ -283,12 +287,14 @@ patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
char *repository;
char *where;
- repository = xmalloc (strlen (current_parsed_root->directory) + strlen (argv[0])
+ repository = xmalloc (strlen (current_parsed_root->directory)
+ + strlen (argv[0])
+ (mfile == NULL ? 0 : strlen (mfile) + 1) + 2);
- (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]);
+ (void)sprintf (repository, "%s/%s",
+ current_parsed_root->directory, argv[0]);
where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) + 1)
+ 1);
- (void) strcpy (where, argv[0]);
+ (void)strcpy (where, argv[0]);
/* if mfile isn't null, we need to set up to do only part of the module */
if (mfile != NULL)
@@ -300,22 +306,22 @@ patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
if ((cp = strrchr (mfile, '/')) != NULL)
{
*cp = '\0';
- (void) strcat (repository, "/");
- (void) strcat (repository, mfile);
- (void) strcat (where, "/");
- (void) strcat (where, mfile);
+ (void)strcat (repository, "/");
+ (void)strcat (repository, mfile);
+ (void)strcat (where, "/");
+ (void)strcat (where, mfile);
mfile = cp + 1;
}
/* take care of the rest */
path = xmalloc (strlen (repository) + strlen (mfile) + 2);
- (void) sprintf (path, "%s/%s", repository, mfile);
+ (void)sprintf (path, "%s/%s", repository, mfile);
if (isdir (path))
{
/* directory means repository gets the dir tacked on */
- (void) strcpy (repository, path);
- (void) strcat (where, "/");
- (void) strcat (where, mfile);
+ (void)strcpy (repository, path);
+ (void)strcat (where, "/");
+ (void)strcat (where, mfile);
}
else
{
@@ -332,9 +338,8 @@ patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
{
error (0, errno, "cannot chdir to %s", repository);
free (repository);
- return (1);
+ return 1;
}
- free (repository);
if (force_tag_match)
which = W_REPOS | W_ATTIC;
@@ -343,25 +348,30 @@ patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
if (rev1 != NULL && !rev1_validated)
{
- tag_check_valid (rev1, argc - 1, argv + 1, local_specified, 0, NULL);
+ tag_check_valid (rev1, argc - 1, argv + 1, local_specified, 0,
+ repository);
rev1_validated = 1;
}
if (rev2 != NULL && !rev2_validated)
{
- tag_check_valid (rev2, argc - 1, argv + 1, local_specified, 0, NULL);
+ tag_check_valid (rev2, argc - 1, argv + 1, local_specified, 0,
+ repository);
rev2_validated = 1;
}
/* start the recursion processor */
- err = start_recursion (patch_fileproc, (FILESDONEPROC) NULL, patch_dirproc,
- (DIRLEAVEPROC) NULL, NULL,
+ err = start_recursion (patch_fileproc, (FILESDONEPROC)NULL, patch_dirproc,
+ (DIRLEAVEPROC)NULL, NULL,
argc - 1, argv + 1, local_specified,
- which, 0, CVS_LOCK_READ, where, 1);
+ which, 0, CVS_LOCK_READ, where, 1, repository);
+ free (repository);
free (where);
- return (err);
+ return err;
}
+
+
/*
* Called to examine a particular RCS file, as appropriate with the options
* that were set above.
@@ -394,6 +404,7 @@ patch_fileproc (callerdat, finfo)
line1_chars_allocated = 0;
line2 = NULL;
line2_chars_allocated = 0;
+ vers_tag = vers_head = NULL;
/* find the parsed rcs file */
if ((rcsfile = finfo->rcs) == NULL)
@@ -449,53 +460,38 @@ patch_fileproc (callerdat, finfo)
vers_tag = NULL;
}
- if (vers_tag == NULL && vers_head == NULL)
+ if ((vers_tag == NULL && vers_head == NULL) ||
+ (vers_tag != NULL && vers_head != NULL &&
+ strcmp (vers_head, vers_tag) == 0))
{
- /* Nothing known about specified revs. */
+ /* Nothing known about specified revs or
+ * not changed between releases.
+ */
ret = 0;
goto out2;
}
- if (vers_tag && vers_head && strcmp (vers_head, vers_tag) == 0)
- {
- /* Not changed between releases. */
- ret = 0;
- goto out2;
- }
-
- if (patch_short)
+ if( patch_short && ( vers_tag == NULL || vers_head == NULL ) )
{
+ /* For adds & removes with a short patch requested, we can print our
+ * error message now and get out.
+ */
cvs_output ("File ", 0);
cvs_output (finfo->fullname, 0);
if (vers_tag == NULL)
{
- cvs_output (" is new; current revision ", 0);
+ cvs_output( " is new; ", 0 );
+ cvs_output( rev2 ? rev2 : date2 ? date2 : "current", 0 );
+ cvs_output( " revision ", 0 );
cvs_output (vers_head, 0);
cvs_output ("\n", 1);
}
- else if (vers_head == NULL)
- {
- cvs_output (" is removed; not included in ", 0);
- if (rev2 != NULL)
- {
- cvs_output ("release tag ", 0);
- cvs_output (rev2, 0);
- }
- else if (date2 != NULL)
- {
- cvs_output ("release date ", 0);
- cvs_output (date2, 0);
- }
- else
- cvs_output ("current release", 0);
- cvs_output ("\n", 1);
- }
else
{
- cvs_output (" changed from revision ", 0);
- cvs_output (vers_tag, 0);
- cvs_output (" to ", 0);
- cvs_output (vers_head, 0);
+ cvs_output( " is removed; ", 0 );
+ cvs_output( rev1 ? rev1 : date1, 0 );
+ cvs_output( " revision ", 0 );
+ cvs_output( vers_tag, 0 );
cvs_output ("\n", 1);
}
ret = 0;
@@ -541,9 +537,9 @@ patch_fileproc (callerdat, finfo)
if (vers_tag != NULL)
{
- retcode = RCS_checkout (rcsfile, (char *) NULL, vers_tag,
+ retcode = RCS_checkout (rcsfile, (char *)NULL, vers_tag,
rev1, options, tmpfile1,
- (RCSCHECKOUTPROC) NULL, (void *) NULL);
+ (RCSCHECKOUTPROC)NULL, (void *)NULL);
if (retcode != 0)
{
error (0, 0,
@@ -565,9 +561,9 @@ patch_fileproc (callerdat, finfo)
}
if (vers_head != NULL)
{
- retcode = RCS_checkout (rcsfile, (char *) NULL, vers_head,
+ retcode = RCS_checkout (rcsfile, (char *)NULL, vers_head,
rev2, options, tmpfile2,
- (RCSCHECKOUTPROC) NULL, (void *) NULL);
+ (RCSCHECKOUTPROC)NULL, (void *)NULL);
if (retcode != 0)
{
error (0, 0,
@@ -576,13 +572,14 @@ patch_fileproc (callerdat, finfo)
goto out;
}
if ((t.actime = t.modtime = RCS_getrevtime (rcsfile, vers_head,
- (char *) 0, 0)) != -1)
+ (char *)0, 0)) != -1)
/* I believe this timestamp only affects the dates in our diffs,
and therefore should be on the server, not the client. */
- (void) utime (tmpfile2, &t);
+ (void)utime (tmpfile2, &t);
}
- switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, unidiff ? "-u" : "-c", tmpfile3))
+ switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, unidiff ? "-u" : "-c",
+ tmpfile3))
{
case -1: /* fork/wait failure */
error (1, errno, "fork for diff failed on %s", rcs);
@@ -593,14 +590,29 @@ patch_fileproc (callerdat, finfo)
/*
* The two revisions are really different, so read the first two
* lines of the diff output file, and munge them to include more
- * reasonable file names that "patch" will understand.
+ * reasonable file names that "patch" will understand, unless the
+ * user wanted a short patch. In that case, just output the short
+ * message.
*/
+ if( patch_short )
+ {
+ cvs_output ("File ", 0);
+ cvs_output (finfo->fullname, 0);
+ cvs_output (" changed from revision ", 0);
+ cvs_output (vers_tag, 0);
+ cvs_output (" to ", 0);
+ cvs_output (vers_head, 0);
+ cvs_output ("\n", 1);
+ ret = 0;
+ goto out;
+ }
/* Output an "Index:" line for patch to use */
cvs_output ("Index: ", 0);
cvs_output (finfo->fullname, 0);
cvs_output ("\n", 1);
+ /* Now the munging. */
fp = open_file (tmpfile3, "r");
if (getline (&line1, &line1_chars_allocated, fp) < 0 ||
getline (&line2, &line2_chars_allocated, fp) < 0)
@@ -648,8 +660,10 @@ failed to read diff file header %s for %s: end of file", tmpfile3, rcs);
assert (current_parsed_root != NULL);
assert (current_parsed_root->directory != NULL);
{
- strippath = xmalloc (strlen (current_parsed_root->directory) + 2);
- (void) sprintf (strippath, "%s/", current_parsed_root->directory);
+ strippath = xmalloc (strlen (current_parsed_root->directory)
+ + 2);
+ (void)sprintf (strippath, "%s/",
+ current_parsed_root->directory);
}
/*else
strippath = xstrdup (REPOS_STRIP); */
@@ -661,7 +675,7 @@ failed to read diff file header %s for %s: end of file", tmpfile3, rcs);
file1 = xmalloc (strlen (finfo->fullname)
+ strlen (vers_tag)
+ 10);
- (void) sprintf (file1, "%s:%s", finfo->fullname, vers_tag);
+ (void)sprintf (file1, "%s:%s", finfo->fullname, vers_tag);
}
else
{
@@ -670,8 +684,8 @@ failed to read diff file header %s for %s: end of file", tmpfile3, rcs);
file2 = xmalloc (strlen (finfo->fullname)
+ (vers_head != NULL ? strlen (vers_head) : 10)
+ 10);
- (void) sprintf (file2, "%s:%s", finfo->fullname,
- vers_head ? vers_head : "removed");
+ (void)sprintf (file2, "%s:%s", finfo->fullname,
+ vers_head ? vers_head : "removed");
/* Note that the string "diff" is specified by POSIX (for -c)
and is part of the diff output format, not the name of a
@@ -745,9 +759,11 @@ failed to read diff file header %s for %s: end of file", tmpfile3, rcs);
free (vers_head);
if (rcs != NULL)
free (rcs);
- return (ret);
+ return ret;
}
+
+
/*
* Print a warm fuzzy message
*/
@@ -755,9 +771,9 @@ failed to read diff file header %s for %s: end of file", tmpfile3, rcs);
static Dtype
patch_dirproc (callerdat, dir, repos, update_dir, entries)
void *callerdat;
- char *dir;
- char *repos;
- char *update_dir;
+ const char *dir;
+ const char *repos;
+ const char *update_dir;
List *entries;
{
if (!quiet)
diff --git a/contrib/cvs/src/rcs.c b/contrib/cvs/src/rcs.c
index 2b2725d..607a879 100644
--- a/contrib/cvs/src/rcs.c
+++ b/contrib/cvs/src/rcs.c
@@ -62,7 +62,8 @@ struct rcsbuffer
};
static RCSNode *RCS_parsercsfile_i PROTO((FILE * fp, const char *rcsfile));
-static char *RCS_getdatebranch PROTO((RCSNode * rcs, char *date, char *branch));
+static char *RCS_getdatebranch PROTO((RCSNode * rcs, const char *date,
+ const char *branch));
static void rcsbuf_open PROTO ((struct rcsbuffer *, FILE *fp,
const char *filename, unsigned long pos));
static void rcsbuf_close PROTO ((struct rcsbuffer *));
@@ -125,13 +126,13 @@ static void putdeltatext PROTO ((FILE *, Deltatext *));
static FILE *rcs_internal_lockfile PROTO ((char *));
static void rcs_internal_unlockfile PROTO ((FILE *, char *));
-static char *rcs_lockfilename PROTO ((char *));
+static char *rcs_lockfilename PROTO ((const char *));
/* The RCS file reading functions are called a lot, and they do some
string comparisons. This macro speeds things up a bit by skipping
the function call when the first characters are different. It
evaluates its arguments multiple times. */
-#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp ((a), (b)) == 0)
+#define STREQ(a, b) (*(char *)(a) == *(char *)(b) && strcmp ((a), (b)) == 0)
/*
* We don't want to use isspace() from the C library because:
@@ -165,6 +166,81 @@ static const char spacetab[] = {
static char *rcs_lockfile;
static int rcs_lockfd = -1;
+
+
+/*
+ * char *
+ * locate_rcs ( const char* file, const char *repository , int *inattic )
+ *
+ * Find an RCS file in the repository, case insensitively when the cased name
+ * doesn't exist, we are running as the server, and a client has asked us to
+ * ignore case.
+ *
+ * Most parts of CVS will want to rely instead on RCS_parse which calls this
+ * function and is called by recurse.c which then puts the result in useful
+ * places like the rcs field of struct file_info.
+ *
+ * INPUTS
+ *
+ * repository the repository (including the directory)
+ * file the filename within that directory (without RCSEXT).
+ * inattic NULL or a pointer to the output boolean
+ *
+ * OUTPUTS
+ *
+ * inattic If this input was non-null, the destination will be
+ * set to true if the file was found in the attic or
+ * false if not. If no RCS file is found, this value
+ * is undefined.
+ *
+ * RETURNS
+ *
+ * a newly-malloc'd array containing the absolute pathname of the RCS
+ * file that was found or NULL when none was found.
+ *
+ * ERRORS
+ *
+ * errno can be set by the return value of the final call to
+ * locate_file_in_dir(). This should resolve to the system's existence error
+ * value (sometime ENOENT) if the Attic directory did not exist and ENOENT if
+ * the Attic was found but no matching files were found in the Attic or its
+ * parent.
+ */
+static char *
+locate_rcs (repository, file, inattic)
+ const char *repository;
+ const char *file;
+ int *inattic;
+{
+ char *retval;
+
+ /* First, try to find the file as cased. */
+ retval = xmalloc (strlen (repository)
+ + sizeof (CVSATTIC)
+ + strlen (file)
+ + sizeof (RCSEXT)
+ + 3);
+ sprintf (retval, "%s/%s%s", repository, file, RCSEXT);
+ if (isreadable (retval))
+ {
+ if (inattic)
+ *inattic = 0;
+ return retval;
+ }
+ sprintf (retval, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
+ if (isreadable (retval))
+ {
+ if (inattic)
+ *inattic = 1;
+ return retval;
+ }
+ free (retval);
+
+ return NULL;
+}
+
+
+
/* A few generic thoughts on error handling, in particular the
printing of unexpected characters that we find in the RCS file
(that is, why we use '\x%x' rather than %c or some such).
@@ -195,110 +271,36 @@ RCS_parse (file, repos)
{
RCSNode *rcs;
FILE *fp;
- RCSNode *retval;
+ RCSNode *retval = NULL;
char *rcsfile;
+ int inattic;
/* We're creating a new RCSNode, so there is no hope of finding it
in the cache. */
rcsbuf_cache_close ();
- rcsfile = xmalloc (strlen (repos) + strlen (file)
- + sizeof (RCSEXT) + sizeof (CVSATTIC) + 10);
- (void) sprintf (rcsfile, "%s/%s%s", repos, file, RCSEXT);
- if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL)
- {
- rcs = RCS_parsercsfile_i(fp, rcsfile);
- if (rcs != NULL)
- rcs->flags |= VALID;
-
- retval = rcs;
- goto out;
- }
- else if (! existence_error (errno))
+ if ((rcsfile = locate_rcs (repos, file, &inattic)) == NULL)
{
- error (0, errno, "cannot open %s", rcsfile);
- retval = NULL;
- goto out;
+ /* Handle the error cases */
}
-
- (void) sprintf (rcsfile, "%s/%s/%s%s", repos, CVSATTIC, file, RCSEXT);
- if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL)
+ else if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL)
{
rcs = RCS_parsercsfile_i(fp, rcsfile);
if (rcs != NULL)
- {
- rcs->flags |= INATTIC;
+ {
rcs->flags |= VALID;
+ if ( inattic )
+ rcs->flags |= INATTIC;
}
+ free ( rcsfile );
retval = rcs;
- goto out;
}
else if (! existence_error (errno))
{
+ free ( rcsfile );
error (0, errno, "cannot open %s", rcsfile);
- retval = NULL;
- goto out;
}
-#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE)
- else if (ign_case)
- {
- int status;
- char *found_path;
-
- /* The client might be asking for a file which we do have
- (which the client doesn't know about), but for which the
- filename case differs. We only consider this case if the
- regular CVS_FOPENs fail, because fopen_case is such an
- expensive call. */
- (void) sprintf (rcsfile, "%s/%s%s", repos, file, RCSEXT);
- status = fopen_case (rcsfile, "rb", &fp, &found_path);
- if (status == 0)
- {
- rcs = RCS_parsercsfile_i (fp, rcsfile);
- if (rcs != NULL)
- rcs->flags |= VALID;
-
- free (rcs->path);
- rcs->path = found_path;
- retval = rcs;
- goto out;
- }
- else if (! existence_error (status))
- {
- error (0, status, "cannot open %s", rcsfile);
- retval = NULL;
- goto out;
- }
-
- (void) sprintf (rcsfile, "%s/%s/%s%s", repos, CVSATTIC, file, RCSEXT);
- status = fopen_case (rcsfile, "rb", &fp, &found_path);
- if (status == 0)
- {
- rcs = RCS_parsercsfile_i (fp, rcsfile);
- if (rcs != NULL)
- {
- rcs->flags |= INATTIC;
- rcs->flags |= VALID;
- }
-
- free (rcs->path);
- rcs->path = found_path;
- retval = rcs;
- goto out;
- }
- else if (! existence_error (status))
- {
- error (0, status, "cannot open %s", rcsfile);
- retval = NULL;
- goto out;
- }
- }
-#endif
- retval = NULL;
-
- out:
- free (rcsfile);
return retval;
}
@@ -308,7 +310,7 @@ RCS_parse (file, repos)
*/
RCSNode *
RCS_parsercsfile (rcsfile)
- char *rcsfile;
+ const char *rcsfile;
{
FILE *fp;
RCSNode *rcs;
@@ -330,6 +332,7 @@ RCS_parsercsfile (rcsfile)
}
+
/*
*/
static RCSNode *
@@ -343,7 +346,7 @@ RCS_parsercsfile_i (fp, rcsfile)
/* make a node */
rdata = (RCSNode *) xmalloc (sizeof (RCSNode));
- memset ((char *) rdata, 0, sizeof (RCSNode));
+ memset ((char *)rdata, 0, sizeof (RCSNode));
rdata->refcount = 1;
rdata->path = xstrdup (rcsfile);
@@ -361,7 +364,7 @@ RCS_parsercsfile_i (fp, rcsfile)
goto l_error;
if (STREQ (RCSHEAD, key) && value != NULL)
- rdata->head = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *) NULL);
+ rdata->head = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *)NULL);
if (! rcsbuf_getkey (&rcsbuf, &key, &value))
goto l_error;
@@ -372,7 +375,7 @@ RCS_parsercsfile_i (fp, rcsfile)
{
char *cp;
- rdata->branch = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *) NULL);
+ rdata->branch = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *)NULL);
if ((numdots (rdata->branch) & 1) != 0)
{
/* turn it into a branch if it's a revision */
@@ -390,12 +393,12 @@ RCS_parsercsfile_i (fp, rcsfile)
if (STREQ (RCSEXPAND, key))
{
rdata->expand = rcsbuf_valcopy (&rcsbuf, value, 0,
- (size_t *) NULL);
+ (size_t *)NULL);
break;
}
for (cp = key;
- (isdigit ((unsigned char) *cp) || *cp == '.') && *cp != '\0';
+ (isdigit ((unsigned char)*cp) || *cp == '.') && *cp != '\0';
cp++)
/* do nothing */ ;
if (*cp == '\0')
@@ -420,10 +423,11 @@ l_error:
rcsbuf_close (&rcsbuf);
freercsnode (&rdata);
fclose (fp);
- return (NULL);
+ return NULL;
}
+
/* Do the real work of parsing an RCS file.
On error, die with a fatal error; if it returns at all it was successful.
@@ -576,7 +580,7 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
q = getnode ();
q->type = RCSVERS;
q->delproc = rcsvers_delproc;
- q->data = (char *) vnode;
+ q->data = vnode;
q->key = vnode->version;
/* add the nodes to the list */
@@ -628,7 +632,7 @@ RCS_setattic (rcs, toattic)
int toattic;
{
char *newpath;
- char *p;
+ const char *p;
char *q;
/* Some systems aren't going to let us rename an open file. */
@@ -737,7 +741,7 @@ RCS_fully_parse (rcs)
/* Rather than try to keep track of how much information we
have read, just read to the end of the file. */
- if (! rcsbuf_getrevnum (&rcsbuf, &key))
+ if (!rcsbuf_getrevnum (&rcsbuf, &key))
break;
vers = findnode (rcs->versions, key);
@@ -746,11 +750,11 @@ RCS_fully_parse (rcs)
"mismatch in rcs file %s between deltas and deltatexts (%s)",
rcs->path, key);
- vnode = (RCSVers *) vers->data;
+ vnode = vers->data;
while (rcsbuf_getkey (&rcsbuf, &key, &value))
{
- if (! STREQ (key, "text"))
+ if (!STREQ (key, "text"))
{
Node *kv;
@@ -760,7 +764,7 @@ RCS_fully_parse (rcs)
kv->type = rcsbuf_valcmp (&rcsbuf) ? RCSCMPFLD : RCSFIELD;
kv->key = xstrdup (key);
kv->data = rcsbuf_valcopy (&rcsbuf, value, kv->type == RCSFIELD,
- (size_t *) NULL);
+ (size_t *)NULL);
if (addnode (vnode->other, kv) != 0)
{
error (0, 0,
@@ -773,7 +777,7 @@ warning: duplicate key `%s' in version `%s' of RCS file `%s'",
continue;
}
- if (! STREQ (vnode->version, rcs->head))
+ if (!STREQ (vnode->version, rcs->head))
{
unsigned long add, del;
char buf[50];
@@ -872,6 +876,8 @@ warning: duplicate key `%s' in version `%s' of RCS file `%s'",
rcsbuf_cache (rcs, &rcsbuf);
}
+
+
/*
* freercsnode - free up the info for an RCSNode
*/
@@ -965,7 +971,7 @@ static void
rcsvers_delproc (p)
Node *p;
{
- free_rcsvers_contents ((RCSVers *) p->data);
+ free_rcsvers_contents (p->data);
}
/* These functions retrieve keys and values from an RCS file using a
@@ -2183,8 +2189,8 @@ do_branches (list, val)
char *
RCS_getversion (rcs, tag, date, force_tag_match, simple_tag)
RCSNode *rcs;
- char *tag;
- char *date;
+ const char *tag;
+ const char *date;
int force_tag_match;
int *simple_tag;
{
@@ -2217,14 +2223,16 @@ RCS_getversion (rcs, tag, date, force_tag_match, simple_tag)
return (rev);
}
else if (tag)
- return (RCS_gettag (rcs, tag, force_tag_match, simple_tag));
+ return RCS_gettag (rcs, tag, force_tag_match, simple_tag);
else if (date)
- return (RCS_getdate (rcs, date, force_tag_match));
+ return RCS_getdate (rcs, date, force_tag_match);
else
- return (RCS_head (rcs));
+ return RCS_head (rcs);
}
+
+
/*
* Get existing revision number corresponding to tag or revision.
* Similar to RCS_gettag but less interpretation imposed.
@@ -2330,12 +2338,11 @@ RCS_tag2rev (rcs, tag)
char *
RCS_gettag (rcs, symtag, force_tag_match, simple_tag)
RCSNode *rcs;
- char *symtag;
+ const char *symtag;
int force_tag_match;
int *simple_tag;
{
- char *tag = symtag;
- int tag_allocated = 0;
+ char *tag;
if (simple_tag != NULL)
*simple_tag = 0;
@@ -2347,28 +2354,27 @@ RCS_gettag (rcs, symtag, force_tag_match, simple_tag)
if (rcs->flags & PARTIAL)
RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL);
- /* If tag is "HEAD", special case to get head RCS revision */
- if (tag && STREQ (tag, TAG_HEAD))
+ /* If symtag is "HEAD", special case to get head RCS revision */
+ if (symtag && STREQ (symtag, TAG_HEAD))
#if 0 /* This #if 0 is only in the Cygnus code. Why? Death support? */
if (force_tag_match && (rcs->flags & VALID) && (rcs->flags & INATTIC))
return ((char *) NULL); /* head request for removed file */
else
#endif
- return (RCS_head (rcs));
+ return RCS_head (rcs);
- if (!isdigit ((unsigned char) tag[0]))
+ if (!isdigit ((unsigned char) symtag[0]))
{
char *version;
/* If we got a symbolic tag, resolve it to a numeric */
- version = translate_symtag (rcs, tag);
+ version = translate_symtag (rcs, symtag);
if (version != NULL)
{
int dots;
char *magic, *branch, *cp;
tag = version;
- tag_allocated = 1;
/*
* If this is a magic revision, we turn it into either its
@@ -2396,9 +2402,9 @@ RCS_gettag (rcs, symtag, force_tag_match, simple_tag)
if (branch != NULL)
{
free (tag);
- return (branch);
+ return branch;
}
- return (tag);
+ return tag;
}
free (magic);
}
@@ -2407,11 +2413,15 @@ RCS_gettag (rcs, symtag, force_tag_match, simple_tag)
{
/* The tag wasn't there, so return the head or NULL */
if (force_tag_match)
- return (NULL);
+ return NULL;
else
- return (RCS_head (rcs));
+ return RCS_head (rcs);
}
}
+ else
+ tag = xstrdup (symtag);
+
+ /* tag is always allocated and numeric now. */
/*
* numeric tag processing:
@@ -2429,8 +2439,7 @@ RCS_gettag (rcs, symtag, force_tag_match, simple_tag)
/* we have a branch tag, so we need to walk the branch */
branch = RCS_getbranch (rcs, tag, force_tag_match);
- if (tag_allocated)
- free (tag);
+ free (tag);
return branch;
}
else
@@ -2450,19 +2459,16 @@ RCS_gettag (rcs, symtag, force_tag_match, simple_tag)
without calling co? */
if (simple_tag != NULL)
*simple_tag = 1;
- if (! tag_allocated)
- tag = xstrdup (tag);
- return (tag);
+ return tag;
}
else
{
/* The revision wasn't there, so return the head or NULL */
- if (tag_allocated)
- free (tag);
+ free (tag);
if (force_tag_match)
- return (NULL);
+ return NULL;
else
- return (RCS_head (rcs));
+ return RCS_head (rcs);
}
}
}
@@ -2675,7 +2681,7 @@ RCS_whatbranch (rcs, rev)
char *
RCS_getbranch (rcs, tag, force_tag_match)
RCSNode *rcs;
- char *tag;
+ const char *tag;
int force_tag_match;
{
Node *p, *head;
@@ -2712,7 +2718,7 @@ RCS_getbranch (rcs, tag, force_tag_match)
else
return (RCS_head (rcs));
}
- vn = (RCSVers *) p->data;
+ vn = p->data;
cp = vn->next;
}
free (xtag);
@@ -2745,7 +2751,7 @@ RCS_getbranch (rcs, tag, force_tag_match)
}
/* find the first element of the branch we are looking for */
- vn = (RCSVers *) p->data;
+ vn = p->data;
if (vn->branches == NULL)
return (NULL);
xtag = xmalloc (strlen (tag) + 1 + 1); /* 1 for the extra '.' */
@@ -2779,7 +2785,7 @@ RCS_getbranch (rcs, tag, force_tag_match)
else
return (RCS_head (rcs));
}
- vn = (RCSVers *) p->data;
+ vn = p->data;
nextvers = vn->next;
} while (nextvers != NULL);
@@ -2870,7 +2876,7 @@ RCS_getbranchpoint (rcs, target)
error (0, 0, "%s: can't find branch point %s", rcs->path, target);
return NULL;
}
- rev = (RCSVers *) vp->data;
+ rev = vp->data;
*bp++ = '.';
while (*bp && *bp != '.')
@@ -2929,7 +2935,7 @@ RCS_head (rcs)
char *
RCS_getdate (rcs, date, force_tag_match)
RCSNode *rcs;
- char *date;
+ const char *date;
int force_tag_match;
{
char *cur_rev = NULL;
@@ -2963,7 +2969,7 @@ RCS_getdate (rcs, date, force_tag_match)
while (p != NULL)
{
/* if the date of this one is before date, take it */
- vers = (RCSVers *) p->data;
+ vers = p->data;
if (RCS_datecmp (vers->date, date) <= 0)
{
cur_rev = vers->version;
@@ -2999,8 +3005,10 @@ RCS_getdate (rcs, date, force_tag_match)
p = findnode (rcs->versions, "1.1.1.1");
if (p)
{
- vers = (RCSVers *) p->data;
- if (RCS_datecmp (vers->date, date) != 0)
+ char *date_1_1 = vers->date;
+
+ vers = p->data;
+ if (RCS_datecmp (vers->date, date_1_1) != 0)
return xstrdup ("1.1");
}
}
@@ -3018,11 +3026,13 @@ RCS_getdate (rcs, date, force_tag_match)
if (!force_tag_match ||
(vers != NULL && RCS_datecmp (vers->date, date) <= 0))
- return (xstrdup (vers->version));
+ return xstrdup (vers->version);
else
- return (NULL);
+ return NULL;
}
+
+
/*
* Look up the last element on a branch that was put in before the specified
* date (return the rev or NULL)
@@ -3030,8 +3040,8 @@ RCS_getdate (rcs, date, force_tag_match)
static char *
RCS_getdatebranch (rcs, date, branch)
RCSNode *rcs;
- char *date;
- char *branch;
+ const char *date;
+ const char *branch;
{
char *cur_rev = NULL;
char *cp;
@@ -3058,7 +3068,7 @@ RCS_getdatebranch (rcs, date, branch)
free (xrev);
if (p == NULL)
return (NULL);
- vers = (RCSVers *) p->data;
+ vers = p->data;
/* Tentatively use this revision, if it is early enough. */
if (RCS_datecmp (vers->date, date) <= 0)
@@ -3091,7 +3101,7 @@ RCS_getdatebranch (rcs, date, branch)
/* walk the next pointers until you find the end, or the date is too late */
while (p != NULL)
{
- vers = (RCSVers *) p->data;
+ vers = p->data;
if (RCS_datecmp (vers->date, date) <= 0)
cur_rev = vers->version;
else
@@ -3108,19 +3118,23 @@ RCS_getdatebranch (rcs, date, branch)
return xstrdup (cur_rev);
}
+
+
/*
* Compare two dates in RCS format. Beware the change in format on January 1,
* 2000, when years go from 2-digit to full format.
*/
int
RCS_datecmp (date1, date2)
- char *date1, *date2;
+ const char *date1, *date2;
{
int length_diff = strlen (date1) - strlen (date2);
- return (length_diff ? length_diff : strcmp (date1, date2));
+ return length_diff ? length_diff : strcmp (date1, date2);
}
+
+
/* Look up revision REV in RCS and return the date specified for the
revision minus FUDGE seconds (FUDGE will generally be one, so that the
logically previous revision will be found later, or zero, if we want
@@ -3135,7 +3149,7 @@ RCS_datecmp (date1, date2)
time_t
RCS_getrevtime (rcs, rev, date, fudge)
RCSNode *rcs;
- char *rev;
+ const char *rev;
char *date;
int fudge;
{
@@ -3155,26 +3169,29 @@ RCS_getrevtime (rcs, rev, date, fudge)
p = findnode (rcs->versions, rev);
if (p == NULL)
return (-1);
- vers = (RCSVers *) p->data;
+ vers = p->data;
/* split up the date */
- ftm = &xtm;
- (void) sscanf (vers->date, SDATEFORM, &ftm->tm_year, &ftm->tm_mon,
- &ftm->tm_mday, &ftm->tm_hour, &ftm->tm_min,
- &ftm->tm_sec);
+ if (sscanf (vers->date, SDATEFORM, &xtm.tm_year, &xtm.tm_mon,
+ &xtm.tm_mday, &xtm.tm_hour, &xtm.tm_min, &xtm.tm_sec) != 6)
+ error (1, 0, "%s: invalid date for revision %s (%s)", rcs->path,
+ rev, vers->date);
/* If the year is from 1900 to 1999, RCS files contain only two
digits, and sscanf gives us a year from 0-99. If the year is
2000+, RCS files contain all four digits and we subtract 1900,
because the tm_year field should contain years since 1900. */
- if (ftm->tm_year > 1900)
- ftm->tm_year -= 1900;
+ if (xtm.tm_year >= 100 && xtm.tm_year < 2000)
+ error (0, 0, "%s: non-standard date format for revision %s (%s)",
+ rcs->path, rev, vers->date);
+ if (xtm.tm_year >= 1900)
+ xtm.tm_year -= 1900;
/* put the date in a form getdate can grok */
- (void) sprintf (tdate, "%d/%d/%d GMT %d:%d:%d", ftm->tm_mon,
- ftm->tm_mday, ftm->tm_year + 1900, ftm->tm_hour,
- ftm->tm_min, ftm->tm_sec);
+ (void) sprintf (tdate, "%d/%d/%d GMT %d:%d:%d", xtm.tm_mon,
+ xtm.tm_mday, xtm.tm_year + 1900, xtm.tm_hour,
+ xtm.tm_min, xtm.tm_sec);
/* turn it into seconds since the epoch */
revdate = get_date (tdate, (struct timeb *) NULL);
@@ -3191,7 +3208,7 @@ RCS_getrevtime (rcs, rev, date, fudge)
ftm->tm_min, ftm->tm_sec);
}
}
- return (revdate);
+ return revdate;
}
List *
@@ -3426,7 +3443,7 @@ RCS_isdead (rcs, tag)
if (p == NULL)
return (0);
- version = (RCSVers *) p->data;
+ version = p->data;
return (version->dead);
}
@@ -3449,7 +3466,7 @@ RCS_getexpand (rcs)
void
RCS_setexpand (rcs, expand)
RCSNode *rcs;
- char *expand;
+ const char *expand;
{
/* Since RCS_parsercsfile_i now reads expand, don't need to worry
about RCS_reparsercsfile. */
@@ -3722,7 +3739,7 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
case KEYWORD_HEADER:
case KEYWORD_ID:
{
- char *path;
+ const char *path;
int free_path;
char *date;
@@ -3746,7 +3763,10 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
locker != NULL ? " " : "",
locker != NULL ? locker : "");
if (free_path)
- free (path);
+ /* If free_path is set then we know we allocated path
+ * and we can discard the const.
+ */
+ free ((char *)path);
free (date);
free_value = 1;
}
@@ -4023,6 +4043,8 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
}
}
+
+
/* Check out a revision from an RCS file.
If PFN is not NULL, then ignore WORKFILE and SOUT. Call PFN zero
@@ -4062,14 +4084,14 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
int
RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
- RCSNode *rcs;
- char *workfile;
- char *rev;
- char *nametag;
- char *options;
- char *sout;
- RCSCHECKOUTPROC pfn;
- void *callerdat;
+ RCSNode *rcs;
+ const char *workfile;
+ const char *rev;
+ const char *nametag;
+ const char *options;
+ const char *sout;
+ RCSCHECKOUTPROC pfn;
+ void *callerdat;
{
int free_rev = 0;
enum kflag expand;
@@ -4096,7 +4118,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
if (trace)
{
- (void) fprintf (stderr, "%s-> checkout (%s, %s, %s, %s)\n",
+ (void) fprintf (stderr, "%s-> RCS_checkout (%s, %s, %s, %s, %s)\n",
#ifdef SERVER_SUPPORT
server_active ? "S" : " ",
#else
@@ -4104,6 +4126,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
#endif
rcs->path,
rev != NULL ? rev : "",
+ nametag != NULL ? nametag : "",
options != NULL ? options : "",
(pfn != NULL ? "(function)"
: (workfile != NULL
@@ -4158,7 +4181,10 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
{
error (0, 0, "internal error: cannot find head text");
if (free_rev)
- free (rev);
+ /* It's okay to discard the const when free_rev is set, because
+ * we know we allocated it in this function.
+ */
+ free ((char *)rev);
return 1;
}
@@ -4244,7 +4270,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
if (vp == NULL)
error (1, 0, "internal error: no revision information for %s",
rev == NULL ? rcs->head : rev);
- vers = (RCSVers *) vp->data;
+ vers = vp->data;
/* First we look for symlinks, which are simplest to handle. */
info = findnode (vers->other_delta, "symlink");
@@ -4269,11 +4295,14 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
error (1, errno, "cannot remove %s", dest);
if (symlink (info->data, dest) < 0)
error (1, errno, "cannot create symbolic link from %s to %s",
- dest, info->data);
+ dest, (char *)info->data);
if (free_value)
free (value);
if (free_rev)
- free (rev);
+ /* It's okay to discard the const when free_rev is set, because
+ * we know we allocated it in this function.
+ */
+ free ((char *)rev);
return 0;
}
@@ -4314,8 +4343,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
if (uptodate_link != NULL)
{
- struct hardlink_info *hlinfo =
- (struct hardlink_info *) uptodate_link->data;
+ struct hardlink_info *hlinfo = uptodate_link->data;
if (link (uptodate_link->key, workfile) < 0)
error (1, errno, "cannot link %s to %s",
@@ -4324,7 +4352,10 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
if (free_value)
free (value);
if (free_rev)
- free (rev);
+ /* It's okay to discard the const when free_rev is set,
+ * because we know we allocated it in this function.
+ */
+ free ((char *)rev);
return 0;
}
}
@@ -4357,7 +4388,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
if (sscanf (info->data, "%15s %lu",
devtype, &devnum_long) < 2)
error (1, 0, "%s:%s has bad `special' newphrase %s",
- workfile, vers->version, info->data);
+ workfile, vers->version, (char *)info->data);
devnum = devnum_long;
if (STREQ (devtype, "character"))
special_file = S_IFCHR;
@@ -4365,10 +4396,10 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
special_file = S_IFBLK;
else
error (0, 0, "%s is a special file of unsupported type `%s'",
- workfile, info->data);
+ workfile, (char *)info->data);
}
}
-#endif
+#endif /* PRESERVE_PERMISSIONS_SUPPORT */
if (expand != KFLAG_O && expand != KFLAG_B)
{
@@ -4383,7 +4414,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
rev == NULL ? rcs->head : rev);
}
- expand_keywords (rcs, (RCSVers *) vp->data, nametag, log, loglen,
+ expand_keywords (rcs, vp->data, nametag, log, loglen,
expand, value, len, &newvalue, &len);
if (newvalue != value)
@@ -4396,7 +4427,10 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
}
if (free_rev)
- free (rev);
+ /* It's okay to discard the const when free_rev is set, because
+ * we know we allocated it in this function.
+ */
+ free ((char *)rev);
if (log != NULL)
{
@@ -4666,7 +4700,7 @@ RCS_findlock_or_tip (rcs)
lock->key);
return NULL;
}
- return (RCSVers *) p->data;
+ return p->data;
}
/* No existing lock. The RCS rule is that this is an error unless
@@ -4681,7 +4715,7 @@ RCS_findlock_or_tip (rcs)
that in other ways if at all anyway (e.g. rcslock.pl). */
p = findnode (rcs->versions, RCS_getbranch (rcs, rcs->branch, 0));
- return (RCSVers *) p->data;
+ return p->data;
}
/* Revision number string, R, must contain a `.'.
@@ -4812,7 +4846,7 @@ RCS_addbranch (rcs, branch)
return NULL;
}
free (branchpoint);
- branchnode = (RCSVers *) nodep->data;
+ branchnode = nodep->data;
/* If BRANCH was a full branch number, make sure it is higher than MAX. */
if ((numdots (branch) & 1) == 1)
@@ -4912,24 +4946,24 @@ RCS_addbranch (rcs, branch)
or zero for success. */
int
-RCS_checkin (rcs, workfile, message, rev, flags)
+RCS_checkin (rcs, workfile_in, message, rev, flags)
RCSNode *rcs;
- char *workfile;
- char *message;
- char *rev;
+ const char *workfile_in;
+ const char *message;
+ const char *rev;
int flags;
{
RCSVers *delta, *commitpt;
Deltatext *dtext;
Node *nodep;
- char *tmpfile, *changefile, *chtext;
+ char *tmpfile, *changefile;
char *diffopts;
size_t bufsize;
- int buflen, chtextlen;
- int status, checkin_quiet, allocated_workfile;
+ int status, checkin_quiet;
struct tm *ftm;
time_t modtime;
int adding_branch = 0;
+ char *workfile = xstrdup (workfile_in);
#ifdef PRESERVE_PERMISSIONS_SUPPORT
struct stat sb;
#endif
@@ -4941,7 +4975,6 @@ RCS_checkin (rcs, workfile, message, rev, flags)
/* Get basename of working file. Is there a library function to
do this? I couldn't find one. -twp */
- allocated_workfile = 0;
if (workfile == NULL)
{
char *p;
@@ -4950,7 +4983,6 @@ RCS_checkin (rcs, workfile, message, rev, flags)
p = workfile + (strlen (workfile) - extlen);
assert (strncmp (p, RCSEXT, extlen) == 0);
*p = '\0';
- allocated_workfile = 1;
}
/* If the filename is a symbolic link, follow it and replace it
@@ -5107,7 +5139,7 @@ workfile);
nodep = getnode();
nodep->type = RCSVERS;
nodep->delproc = rcsvers_delproc;
- nodep->data = (char *) delta;
+ nodep->data = delta;
nodep->key = delta->version;
(void) addnode (rcs->versions, nodep);
@@ -5287,7 +5319,7 @@ workfile);
}
nodep = findnode (rcs->versions, tip);
- commitpt = (RCSVers *) nodep->data;
+ commitpt = nodep->data;
free (branch);
free (newrev);
@@ -5316,7 +5348,7 @@ workfile);
{
error (0, 0, "%s: revision %s locked by %s",
rcs->path,
- nodep->key, nodep->data);
+ nodep->key, (char *)nodep->data);
status = 1;
goto checkin_done;
}
@@ -5346,9 +5378,7 @@ workfile);
"could not check out revision %s of `%s'",
commitpt->version, rcs->path);
- bufsize = buflen = 0;
- chtext = NULL;
- chtextlen = 0;
+ bufsize = 0;
changefile = cvs_temp_name();
/* Diff options should include --binary if the RCS file has -kb set
@@ -5482,7 +5512,7 @@ workfile);
nodep = getnode();
nodep->type = RCSVERS;
nodep->delproc = rcsvers_delproc;
- nodep->data = (char *) delta;
+ nodep->data = delta;
nodep->key = delta->version;
(void) addnode (rcs->versions, nodep);
@@ -5515,8 +5545,7 @@ workfile);
cvs_output ("done\n", 5);
checkin_done:
- if (allocated_workfile)
- free (workfile);
+ free (workfile);
if (commitpt != NULL && commitpt->text != NULL)
{
@@ -5531,8 +5560,9 @@ workfile);
return status;
}
-/* This structure is passed between RCS_cmp_file and cmp_file_buffer. */
+
+/* This structure is passed between RCS_cmp_file and cmp_file_buffer. */
struct cmp_file_data
{
const char *filename;
@@ -5540,22 +5570,21 @@ struct cmp_file_data
int different;
};
-/* Compare the contents of revision REV of RCS file RCS with the
- contents of the file FILENAME. OPTIONS is a string for the keyword
+/* Compare the contents of revision REV1 of RCS file RCS with the
+ contents of REV2 if given, otherwise, compare with the contents of
+ the file FILENAME. OPTIONS is a string for the keyword
expansion options. Return 0 if the contents of the revision are
the same as the contents of the file, 1 if they are different. */
-
int
-RCS_cmp_file (rcs, rev, options, filename)
+RCS_cmp_file (rcs, rev1, rev1_cache, rev2, options, filename)
RCSNode *rcs;
- char *rev;
- char *options;
+ const char *rev1;
+ char **rev1_cache;
+ const char *rev2;
+ const char *options;
const char *filename;
{
int binary;
- FILE *fp;
- struct cmp_file_data data;
- int retcode;
if (options != NULL && options[0] != '\0')
binary = STREQ (options, "-kb");
@@ -5583,6 +5612,7 @@ RCS_cmp_file (rcs, rev, options, filename)
if (preserve_perms)
{
char *tmp;
+ int retcode;
tmp = cvs_temp_name();
retcode = RCS_checkout(rcs, NULL, rev, NULL, options, tmp, NULL, NULL);
@@ -5598,39 +5628,67 @@ RCS_cmp_file (rcs, rev, options, filename)
else
#endif
{
- fp = CVS_FOPEN (filename, binary ? FOPEN_BINARY_READ : "r");
+ FILE *fp;
+ struct cmp_file_data data;
+ const char *use_file1;
+ char *tmpfile = NULL;
+
+ if (rev2 != NULL)
+ {
+ /* Open & cache rev1 */
+ tmpfile = cvs_temp_name();
+ if (RCS_checkout (rcs, NULL, rev1, NULL, options, tmpfile,
+ (RCSCHECKOUTPROC)0, NULL))
+ error (1, errno,
+ "cannot check out revision %s of %s",
+ rev1, rcs->path);
+ use_file1 = tmpfile;
+ if (rev1_cache != NULL)
+ *rev1_cache = tmpfile;
+ }
+ else
+ use_file1 = filename;
+
+ fp = CVS_FOPEN (use_file1, binary ? FOPEN_BINARY_READ : "r");
if (fp == NULL)
/* FIXME-update-dir: should include update_dir in message. */
- error (1, errno, "cannot open file %s for comparing", filename);
+ error (1, errno, "cannot open file %s for comparing", use_file1);
- data.filename = filename;
+ data.filename = use_file1;
data.fp = fp;
data.different = 0;
- retcode = RCS_checkout (rcs, (char *) NULL, rev, (char *) NULL,
- options, RUN_TTY, cmp_file_buffer,
- (void *) &data);
+ if (RCS_checkout (rcs, (char *)NULL, rev2 ? rev2 : rev1,
+ (char *)NULL, options, RUN_TTY, cmp_file_buffer,
+ (void *)&data ))
+ error (1, errno,
+ "cannot check out revision %s of %s",
+ rev2 ? rev2 : rev1, rcs->path);
/* If we have not yet found a difference, make sure that we are at
the end of the file. */
- if (! data.different)
+ if (!data.different)
{
if (getc (fp) != EOF)
data.different = 1;
}
fclose (fp);
+ if (rev1_cache == NULL && tmpfile)
+ {
+ if (CVS_UNLINK (tmpfile ) < 0)
+ error (0, errno, "cannot remove %s", tmpfile);
+ free (tmpfile);
+ }
- if (retcode != 0)
- return 1;
-
return data.different;
}
}
+
+
/* This is a subroutine of RCS_cmp_file. It is passed to
RCS_checkout. */
-
#define CMP_BUF_SIZE (8 * 1024)
static void
@@ -5639,7 +5697,7 @@ cmp_file_buffer (callerdat, buffer, len)
const char *buffer;
size_t len;
{
- struct cmp_file_data *data = (struct cmp_file_data *) callerdat;
+ struct cmp_file_data *data = (struct cmp_file_data *)callerdat;
char *filebuf;
/* If we've already found a difference, we don't need to check
@@ -5678,6 +5736,8 @@ cmp_file_buffer (callerdat, buffer, len)
free (filebuf);
}
+
+
/* For RCS file RCS, make symbolic tag TAG point to revision REV.
This validates that TAG is OK for a user to use. Return value is
-1 for error (and errno is set to indicate the error), positive for
@@ -5806,7 +5866,7 @@ RCS_setbranch (rcs, rev)
int
RCS_lock (rcs, rev, lock_quiet)
RCSNode *rcs;
- char *rev;
+ const char *rev;
int lock_quiet;
{
List *locks;
@@ -5870,7 +5930,7 @@ RCS_lock (rcs, rev, lock_quiet)
}
delnode (p);
#else
- error (1, 0, "Revision %s is already locked by %s", xrev, p->data);
+ error (1, 0, "Revision %s is already locked by %s", xrev, (char *)p->data);
#endif
}
@@ -5986,7 +6046,7 @@ RCS_unlock (rcs, rev, unlock_quiet)
char *repos, *workfile;
if (!unlock_quiet)
error (0, 0, "\
-%s: revision %s locked by %s; breaking lock", rcs->path, xrev, lock->data);
+%s: revision %s locked by %s; breaking lock", rcs->path, xrev, (char *)lock->data);
repos = xstrdup (rcs->path);
workfile = strrchr (repos, '/');
*workfile++ = '\0';
@@ -6291,10 +6351,10 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
{
/* Walk deltas from BRANCHPOINT on, looking for REV1. */
nodep = findnode (rcs->versions, branchpoint);
- revp = (RCSVers *) nodep->data;
+ revp = nodep->data;
while (revp->next != NULL && ! STREQ (revp->next, rev1))
{
- revp = (RCSVers *) nodep->data;
+ revp = nodep->data;
nodep = findnode (rcs->versions, revp->next);
}
if (revp->next == NULL)
@@ -6338,7 +6398,7 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
while (!found && next != NULL)
{
nodep = findnode (rcs->versions, next);
- revp = (RCSVers *) nodep->data;
+ revp = nodep->data;
if (rev2 != NULL)
found = STREQ (revp->version, rev2);
@@ -6442,7 +6502,7 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
char *diffbuf;
size_t bufsize, len;
-#if defined (__CYGWIN32__) || defined (_WIN32)
+#if defined (WOE32) && !defined (__CYGWIN32__)
/* FIXME: This is an awful kludge, but at least until I have
time to work on it a little more and test it, I'd rather
give a fatal error than corrupt the file. I think that we
@@ -6455,7 +6515,7 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
error (1, 0,
"admin -o not implemented yet for binary on this system");
}
-#endif
+#endif /* WOE32 */
afterfile = cvs_temp_name();
status = RCS_checkout (rcs, NULL, after, NULL, "-ko", afterfile,
@@ -6510,7 +6570,7 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
/* Save the new change text in after's delta node. */
nodep = findnode (rcs->versions, after);
- revp = (RCSVers *) nodep->data;
+ revp = nodep->data;
assert (revp->text == NULL);
@@ -6538,7 +6598,7 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
next = revp->next)
{
nodep = findnode (rcs->versions, next);
- revp = (RCSVers *) nodep->data;
+ revp = nodep->data;
revp->outdated = 1;
}
@@ -6562,7 +6622,7 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
else if (STREQ (rev1, branchpoint))
{
nodep = findnode (rcs->versions, before);
- revp = (RCSVers *) nodep->data;
+ revp = nodep->data;
nodep = revp->branches->list->next;
while (nodep != revp->branches->list &&
! STREQ (nodep->key, rev1))
@@ -6579,7 +6639,7 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
else
{
nodep = findnode (rcs->versions, before);
- beforep = (RCSVers *) nodep->data;
+ beforep = nodep->data;
free (beforep->next);
beforep->next = xstrdup (after);
}
@@ -7136,7 +7196,7 @@ RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen)
RCSNode *rcs;
FILE *fp;
struct rcsbuffer *rcsbuf;
- char *version;
+ const char *version;
enum rcs_delta_op op;
char **text;
size_t *len;
@@ -7214,7 +7274,7 @@ RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen)
/* Stash the previous version. */
prev_vers = vers;
- vers = (RCSVers *) node->data;
+ vers = node->data;
next = vers->next;
/* Compare key and trunkversion now, because key points to
@@ -7783,7 +7843,7 @@ putlock_proc (symnode, fp)
Node *symnode;
void *fp;
{
- return fprintf ((FILE *) fp, "\n\t%s:%s", symnode->data, symnode->key);
+ return fprintf ((FILE *) fp, "\n\t%s:%s", (char *)symnode->data, symnode->key);
}
static int
@@ -7979,7 +8039,7 @@ RCS_putdtree (rcs, rev, fp)
rcs->path);
}
- versp = (RCSVers *) p->data;
+ versp = p->data;
/* Print the delta node and recurse on its `next' node. This prints
the trunk. If there are any branches printed on this revision,
@@ -8096,7 +8156,7 @@ RCS_copydeltas (rcs, fin, rcsbufin, fout, newdtext, insertpt)
}
np = findnode (rcs->versions, dtext->version);
- dadmin = (RCSVers *) np->data;
+ dadmin = np->data;
/* If this revision has been outdated, just skip it. */
if (dadmin->outdated)
@@ -8208,9 +8268,7 @@ count_delta_actions (np, ignore)
Node *np;
void *ignore;
{
- RCSVers *dadmin;
-
- dadmin = (RCSVers *) np->data;
+ RCSVers *dadmin = np->data;
if (dadmin->outdated)
return 1;
@@ -8404,10 +8462,10 @@ rcs_internal_unlockfile (fp, rcsfile)
static char *
rcs_lockfilename (rcsfile)
- char *rcsfile;
+ const char *rcsfile;
{
char *lockfile, *lockp;
- char *rcsbase, *rcsp, *rcsend;
+ const char *rcsbase, *rcsp, *rcsend;
int rcslen;
/* Create the lockfile name. */
@@ -8515,8 +8573,8 @@ RCS_abandon (rcs)
*/
char *
make_file_label (path, rev, rcs)
- char *path;
- char *rev;
+ const char *path;
+ const char *rev;
RCSNode *rcs;
{
char datebuf[MAXDATELEN + 1];
@@ -8539,15 +8597,17 @@ make_file_label (path, rev, rcs)
else
{
struct stat sb;
- struct tm *wm = NULL;
+ struct tm *wm;
if (strcmp(DEVNULL, path))
{
- char *file = last_component (path);
+ const char *file = last_component (path);
if (CVS_STAT (file, &sb) < 0)
- error (0, 1, "could not get info for `%s'", path);
- else
- wm = gmtime (&sb.st_mtime);
+ /* Assume that if the stat fails,then the later read for the
+ * diff will too.
+ */
+ error (1, errno, "could not get info for `%s'", path);
+ wm = gmtime (&sb.st_mtime);
}
else
{
@@ -8555,11 +8615,8 @@ make_file_label (path, rev, rcs)
wm = gmtime(&t);
}
- if (wm)
- {
- (void) tm_to_internet (datebuf, wm);
- (void) sprintf (label, "-L%s\t%s", path, datebuf);
- }
+ (void) tm_to_internet (datebuf, wm);
+ (void) sprintf (label, "-L%s\t%s", path, datebuf);
}
return label;
}
diff --git a/contrib/cvs/src/rcs.h b/contrib/cvs/src/rcs.h
index 55eed95..4a6d2a5 100644
--- a/contrib/cvs/src/rcs.h
+++ b/contrib/cvs/src/rcs.h
@@ -186,47 +186,51 @@ enum rcs_delta_op {RCS_ANNOTATE, RCS_FETCH};
* exported interfaces
*/
RCSNode *RCS_parse PROTO((const char *file, const char *repos));
-RCSNode *RCS_parsercsfile PROTO((char *rcsfile));
+RCSNode *RCS_parsercsfile PROTO((const char *rcsfile));
void RCS_fully_parse PROTO((RCSNode *));
void RCS_reparsercsfile PROTO((RCSNode *, FILE **, struct rcsbuffer *));
extern int RCS_setattic PROTO ((RCSNode *, int));
char *RCS_check_kflag PROTO((const char *arg));
-char *RCS_getdate PROTO((RCSNode * rcs, char *date, int force_tag_match));
-char *RCS_gettag PROTO((RCSNode * rcs, char *symtag, int force_tag_match,
- int *simple_tag));
+char *RCS_getdate PROTO((RCSNode * rcs, const char *date,
+ int force_tag_match));
+char *RCS_gettag PROTO((RCSNode * rcs, const char *symtag, int force_tag_match,
+ int *simple_tag));
int RCS_exist_rev PROTO((RCSNode *rcs, char *rev));
int RCS_exist_tag PROTO((RCSNode *rcs, char *tag));
char *RCS_tag2rev PROTO((RCSNode *rcs, char *tag));
-char *RCS_getversion PROTO((RCSNode * rcs, char *tag, char *date,
- int force_tag_match, int *simple_tag));
+char *RCS_getversion PROTO((RCSNode * rcs, const char *tag, const char *date,
+ int force_tag_match, int *simple_tag));
char *RCS_magicrev PROTO((RCSNode *rcs, char *rev));
int RCS_isbranch PROTO((RCSNode *rcs, const char *rev));
int RCS_nodeisbranch PROTO((RCSNode *rcs, const char *tag));
char *RCS_whatbranch PROTO((RCSNode *rcs, const char *tag));
char *RCS_head PROTO((RCSNode * rcs));
-int RCS_datecmp PROTO((char *date1, char *date2));
-time_t RCS_getrevtime PROTO((RCSNode * rcs, char *rev, char *date, int fudge));
+int RCS_datecmp PROTO((const char *date1, const char *date2));
+time_t RCS_getrevtime PROTO((RCSNode * rcs, const char *rev, char *date,
+ int fudge));
List *RCS_symbols PROTO((RCSNode *rcs));
void RCS_check_tag PROTO((const char *tag));
int RCS_valid_rev PROTO ((char *rev));
List *RCS_getlocks PROTO((RCSNode *rcs));
void freercsnode PROTO((RCSNode ** rnodep));
-char *RCS_getbranch PROTO((RCSNode * rcs, char *tag, int force_tag_match));
+char *RCS_getbranch PROTO((RCSNode * rcs, const char *tag,
+ int force_tag_match));
char *RCS_branch_head PROTO ((RCSNode *rcs, char *rev));
int RCS_isdead PROTO((RCSNode *, const char *));
char *RCS_getexpand PROTO ((RCSNode *));
-void RCS_setexpand PROTO ((RCSNode *, char *));
-int RCS_checkout PROTO ((RCSNode *, char *, char *, char *, char *, char *,
- RCSCHECKOUTPROC, void *));
-int RCS_checkin PROTO ((RCSNode *rcs, char *workfile, char *message,
- char *rev, int flags));
-int RCS_cmp_file PROTO ((RCSNode *, char *, char *, const char *));
+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));
+int RCS_cmp_file PROTO((RCSNode *, const char *, char **, const char *,
+ const char *, const char *));
int RCS_settag PROTO ((RCSNode *, const char *, const char *));
int RCS_deltag PROTO ((RCSNode *, const char *));
int RCS_setbranch PROTO((RCSNode *, const char *));
-int RCS_lock PROTO ((RCSNode *, char *, int));
+int RCS_lock PROTO ((RCSNode *, const char *, int));
int RCS_unlock PROTO ((RCSNode *, char *, int));
int RCS_delete_revs PROTO ((RCSNode *, char *, char *, int));
void RCS_addaccess PROTO ((RCSNode *, char *));
@@ -237,14 +241,15 @@ void RCS_rewrite PROTO ((RCSNode *, Deltatext *, char *));
void RCS_abandon PROTO ((RCSNode *));
int rcs_change_text PROTO ((const char *, char *, size_t, const char *,
size_t, char **, size_t *));
-void RCS_deltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, char *,
+void RCS_deltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, const char *,
enum rcs_delta_op, char **, size_t *,
char **, size_t *));
-char *make_file_label PROTO ((char *, char *, RCSNode *));
+char *make_file_label PROTO ((const char *, const char *, RCSNode *));
extern int preserve_perms;
/* From import.c. */
-extern int add_rcs_file PROTO ((char *, char *, char *, char *, char *,
- char *, char *, int, char **,
- char *, size_t, FILE *));
+extern int add_rcs_file PROTO ((const char *, const char *, const char *,
+ const char *, const char *, const char *,
+ const char *, int, char **, const char *,
+ size_t, FILE *));
diff --git a/contrib/cvs/src/rcscmds.c b/contrib/cvs/src/rcscmds.c
index 178913e..52e3a9a 100644
--- a/contrib/cvs/src/rcscmds.c
+++ b/contrib/cvs/src/rcscmds.c
@@ -51,7 +51,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 ((char *, char *, char *, char *));
+static void RCS_output_diff_options PROTO ((const char *, const char *,
+ const char *, const char *));
/* Stuff to deal with passing arguments the way libdiff.a wants to deal
@@ -74,7 +75,7 @@ static int call_diff_argc_allocated;
static void call_diff_add_arg PROTO ((const char *));
static void call_diff_setup PROTO ((const char *prog));
-static int call_diff PROTO ((char *out));
+static int call_diff PROTO ((const char *out));
static int call_diff3 PROTO ((char *out));
static void call_diff_write_output PROTO((const char *, size_t));
@@ -204,9 +205,11 @@ static struct diff_callbacks call_diff_file_callbacks =
call_diff_error
};
+
+
static int
call_diff (out)
- char *out;
+ const char *out;
{
if (out == RUN_TTY)
return diff_run (call_diff_argc, call_diff_argv, NULL,
@@ -216,6 +219,8 @@ call_diff (out)
&call_diff_file_callbacks);
}
+
+
static int
call_diff3 (out)
char *out;
@@ -235,11 +240,11 @@ call_diff3 (out)
int
RCS_merge(rcs, path, workfile, options, rev1, rev2)
RCSNode *rcs;
- char *path;
- char *workfile;
- char *options;
- char *rev1;
- char *rev2;
+ const char *path;
+ const char *workfile;
+ const char *options;
+ const char *rev1;
+ const char *rev2;
{
char *xrev1, *xrev2;
char *tmp1, *tmp2;
@@ -308,6 +313,7 @@ RCS_merge(rcs, path, workfile, options, rev1, rev2)
call_diff_arg ("-L");
call_diff_arg (xrev2);
+ call_diff_arg ("--");
call_diff_arg (workfile);
call_diff_arg (tmp1);
call_diff_arg (tmp2);
@@ -376,23 +382,23 @@ 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, rev2, label1, label2, workfile)
+RCS_exec_rcsdiff(rcsfile, opts, options, rev1, rev1_cache, rev2,
+ label1, label2, workfile )
RCSNode *rcsfile;
- char *opts;
- char *options;
- char *rev1;
- char *rev2;
- char *label1;
- char *label2;
- char *workfile;
+ const char *opts;
+ const char *options;
+ const char *rev1;
+ const char *rev1_cache;
+ const char *rev2;
+ const char *label1;
+ const char *label2;
+ const char *workfile;
{
- char *tmpfile1;
- char *tmpfile2;
- char *use_file2;
+ char *tmpfile1 = NULL;
+ char *tmpfile2 = NULL;
+ const char *use_file1, *use_file2;
int status, retval;
- tmpfile1 = cvs_temp_name ();
- tmpfile2 = NULL;
cvs_output ("\
===================================================================\n\
@@ -409,19 +415,27 @@ RCS file: ", 0);
cvs_output ("retrieving revision ", 0);
cvs_output (rev1, 0);
cvs_output ("\n", 1);
- status = RCS_checkout (rcsfile, NULL, rev1, NULL, options, tmpfile1,
- (RCSCHECKOUTPROC)0, NULL);
- if (status > 0)
- {
- retval = status;
- goto error_return;
- }
- else if (status < 0)
+
+ if (rev1_cache != NULL)
+ use_file1 = rev1_cache;
+ else
{
- error (0, errno,
- "cannot check out revision %s of %s", rev1, rcsfile->path);
- retval = 1;
- goto error_return;
+ tmpfile1 = cvs_temp_name();
+ status = RCS_checkout (rcsfile, NULL, rev1, NULL, options, tmpfile1,
+ (RCSCHECKOUTPROC)0, NULL);
+ if (status > 0)
+ {
+ retval = status;
+ goto error_return;
+ }
+ else if (status < 0)
+ {
+ error( 0, errno,
+ "cannot check out revision %s of %s", rev1, rcsfile->path );
+ retval = 1;
+ goto error_return;
+ }
+ use_file1 = tmpfile1;
}
if (rev2 == NULL)
@@ -452,7 +466,7 @@ RCS file: ", 0);
}
RCS_output_diff_options (opts, rev1, rev2, workfile);
- status = diff_exec (tmpfile1, use_file2, label1, label2, opts, RUN_TTY);
+ status = diff_exec( use_file1, use_file2, label1, label2, opts, RUN_TTY );
if (status >= 0)
{
retval = status;
@@ -461,40 +475,41 @@ RCS file: ", 0);
else if (status < 0)
{
error (0, errno,
- "cannot diff %s and %s", tmpfile1, use_file2);
+ "cannot diff %s and %s", use_file1, use_file2);
retval = 1;
goto error_return;
}
error_return:
{
- int save_noexec = noexec;
- noexec = 0;
- if (unlink_file (tmpfile1) < 0)
+ /* Call CVS_UNLINK() below rather than unlink_file to avoid the check
+ * for noexec.
+ */
+ if( tmpfile1 != NULL )
{
- if (!existence_error (errno))
- error (0, errno, "cannot remove temp file %s", tmpfile1);
+ if( CVS_UNLINK( tmpfile1 ) < 0 )
+ {
+ if( !existence_error( errno ) )
+ error( 0, errno, "cannot remove temp file %s", tmpfile1 );
+ }
+ free( tmpfile1 );
}
- noexec = save_noexec;
- }
- free (tmpfile1);
- if (tmpfile2 != NULL)
- {
- int save_noexec = noexec;
- noexec = 0;
- if (unlink_file (tmpfile2) < 0)
+ if( tmpfile2 != NULL )
{
- if (!existence_error (errno))
- error (0, errno, "cannot remove temp file %s", tmpfile2);
+ if( CVS_UNLINK( tmpfile2 ) < 0 )
+ {
+ if( !existence_error( errno ) )
+ error( 0, errno, "cannot remove temp file %s", tmpfile2 );
+ }
+ free (tmpfile2);
}
- noexec = save_noexec;
- free (tmpfile2);
}
return retval;
}
+
/* Show differences between two files. This is the start of a diff library.
Some issues:
@@ -531,12 +546,12 @@ RCS file: ", 0);
int
diff_exec (file1, file2, label1, label2, options, out)
- char *file1;
- char *file2;
- char *label1;
- char *label2;
- char *options;
- char *out;
+ const char *file1;
+ const char *file2;
+ const char *label1;
+ const char *label2;
+ const char *options;
+ const char *out;
{
char *args;
@@ -597,10 +612,10 @@ diff_exec (file1, file2, label1, label2, options, out)
static void
RCS_output_diff_options (opts, rev1, rev2, workfile)
- char *opts;
- char *rev1;
- char *rev2;
- char *workfile;
+ const char *opts;
+ const char *rev1;
+ const char *rev2;
+ const char *workfile;
{
char *tmp;
diff --git a/contrib/cvs/src/recurse.c b/contrib/cvs/src/recurse.c
index d5eeabf..b807e2d 100644
--- a/contrib/cvs/src/recurse.c
+++ b/contrib/cvs/src/recurse.c
@@ -12,6 +12,7 @@
#include "savecwd.h"
#include "fileattr.h"
#include "edit.h"
+#include <assert.h>
static int do_dir_proc PROTO((Node * p, void *closure));
static int do_file_proc PROTO((Node * p, void *closure));
@@ -35,6 +36,7 @@ struct recursion_frame {
int aflag;
int locktype;
int dosrcs;
+ char *repository; /* Keep track of repository for rtag */
};
static int do_recursion PROTO ((struct recursion_frame *frame));
@@ -67,7 +69,7 @@ struct frame_and_entries {
int
start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
argc, argv, local, which, aflag, locktype,
- update_preload, dosrcs)
+ update_preload, dosrcs, repository_in)
FILEPROC fileproc;
FILESDONEPROC filesdoneproc;
DIRENTPROC direntproc;
@@ -105,6 +107,15 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
int locktype;
char *update_preload;
int dosrcs;
+ /* Keep track of the repository string. This is only for the remote mode,
+ * specifically, r* commands (rtag, rdiff, co, ...) where xgetwd() was
+ * used to locate the repository. Things would break when xgetwd() was
+ * used with a symlinked repository because xgetwd() would return the true
+ * path and in some cases this would cause the path to be printed as other
+ * than the user specified in error messages and in other cases some of
+ * CVS's security assertions would fail.
+ */
+ char *repository_in;
{
int i, err = 0;
#ifdef CLIENT_SUPPORT
@@ -123,6 +134,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
frame.aflag = aflag;
frame.locktype = locktype;
frame.dosrcs = dosrcs;
+ frame.repository = repository_in;
expand_wild (argc, argv, &argc, &argv);
@@ -261,7 +273,10 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
/* Now break out argv[i] into directory part (DIR) and file part (COMP).
DIR and COMP will each point to a newly malloc'd string. */
dir = xstrdup (argv[i]);
- comp = last_component (dir);
+ /* Its okay to discard the const below - we know we just allocated
+ * dir ourselves.
+ */
+ comp = (char *)last_component (dir);
if (comp == dir)
{
/* no dir component. What we have is an implied "./" */
@@ -502,7 +517,7 @@ do_recursion (frame)
{
int err = 0;
int dodoneproc = 1;
- char *srepository;
+ char *srepository = NULL;
List *entries = NULL;
int locktype;
int process_this_directory = 1;
@@ -613,17 +628,19 @@ do_recursion (frame)
if (frame->which & W_LOCAL)
{
if (isdir (CVSADM))
+ {
repository = Name_Repository ((char *) NULL, update_dir);
+ srepository = repository; /* remember what to free */
+ }
else
repository = NULL;
}
else
{
- repository = xgetwd ();
- if (repository == NULL)
- error (1, errno, "could not get working directory");
+ repository = frame->repository;
+ assert (repository != NULL);
+ assert (strstr (repository, "/./") == NULL);
}
- srepository = repository; /* remember what to free */
fileattr_startdir (repository);
@@ -662,7 +679,10 @@ do_recursion (frame)
repository at this point. Name_Repository will give a
reasonable error message. */
if (repository == NULL)
- repository = Name_Repository ((char *) NULL, update_dir);
+ {
+ Name_Repository ((char *) NULL, update_dir);
+ assert (!"Not reached. Please report this problem to <bug-cvs@gnu.org>");
+ }
/* find the files and fill in entries if appropriate */
if (process_this_directory)
@@ -736,7 +756,10 @@ do_recursion (frame)
err += walklist (filelist, do_file_proc, &frfile);
/* unlock it */
- if (locktype != CVS_LOCK_NONE)
+ if (/* We only lock the repository above when repository is set */
+ repository
+ /* and when asked for a read or write lock. */
+ && locktype != CVS_LOCK_NONE)
Lock_Cleanup ();
/* clean up */
@@ -778,12 +801,14 @@ do_recursion (frame)
if (srepository)
{
free (srepository);
- repository = (char *) NULL;
}
+ repository = (char *) NULL;
- return (err);
+ return err;
}
+
+
/*
* Process each of the files in the list with the callback proc
*/
@@ -795,18 +820,19 @@ do_file_proc (p, closure)
struct frame_and_file *frfile = (struct frame_and_file *)closure;
struct file_info *finfo = frfile->finfo;
int ret;
+ char *tmp;
finfo->file = p->key;
- finfo->fullname = xmalloc (strlen (finfo->file)
+ tmp = xmalloc (strlen (finfo->file)
+ strlen (finfo->update_dir)
+ 2);
- finfo->fullname[0] = '\0';
+ tmp[0] = '\0';
if (finfo->update_dir[0] != '\0')
{
- strcat (finfo->fullname, finfo->update_dir);
- strcat (finfo->fullname, "/");
+ strcat (tmp, finfo->update_dir);
+ strcat (tmp, "/");
}
- strcat (finfo->fullname, finfo->file);
+ strcat (tmp, finfo->file);
if (frfile->frame->dosrcs && repository)
{
@@ -821,27 +847,30 @@ do_file_proc (p, closure)
if (finfo->rcs == NULL
&& !(frfile->frame->which & W_LOCAL))
{
- error (0, 0, "could not read RCS file for %s", finfo->fullname);
- free (finfo->fullname);
+ error (0, 0, "could not read RCS file for %s", tmp);
+ free (tmp);
cvs_flushout ();
return 0;
}
}
else
finfo->rcs = (RCSNode *) NULL;
+ finfo->fullname = tmp;
ret = frfile->frame->fileproc (frfile->frame->callerdat, finfo);
freercsnode(&finfo->rcs);
- free (finfo->fullname);
+ free (tmp);
/* Allow the user to monitor progress with tail -f. Doing this once
per file should be no big deal, but we don't want the performance
hit of flushing on every line like previous versions of CVS. */
cvs_flushout ();
- return (ret);
+ return ret;
}
+
+
/*
* Process each of the directories in the list (recursing as we go)
*/
@@ -1076,7 +1105,7 @@ but CVS uses %s for its own purposes; skipping %s directory",
dirlist = NULL;
/* cd to the sub-directory */
- if ( CVS_CHDIR (dir) < 0)
+ if (CVS_CHDIR (dir) < 0)
error (1, errno, "could not chdir to %s", dir);
/* honor the global SKIP_DIRS (a.k.a. local) */
@@ -1093,7 +1122,30 @@ but CVS uses %s for its own purposes; skipping %s directory",
/* make the recursive call */
xframe = *frame;
xframe.flags = dir_return;
+ /* Keep track of repository, really just for r* commands (rtag, rdiff,
+ * co, ...) to tag_check_valid, since all the other commands use
+ * CVS/Repository to figure it out per directory.
+ */
+ if (repository)
+ {
+ if (strcmp (dir, ".") == 0)
+ xframe.repository = xstrdup (repository);
+ else
+ {
+ xframe.repository = xmalloc (strlen (repository)
+ + strlen (dir)
+ + 2);
+ sprintf (xframe.repository, "%s/%s", repository, dir);
+ }
+ }
+ else
+ xframe.repository = NULL;
err += do_recursion (&xframe);
+ if (xframe.repository)
+ {
+ free (xframe.repository);
+ xframe.repository = NULL;
+ }
/* put the `.' back if necessary */
if (stripped_dot)
@@ -1115,7 +1167,7 @@ but CVS uses %s for its own purposes; skipping %s directory",
free (update_dir);
update_dir = saved_update_dir;
- return (err);
+ return err;
}
/*
@@ -1157,9 +1209,9 @@ addfile (listp, dir, file)
}
n->type = DIRS;
- fl = (List *) n->data;
+ fl = n->data;
addlist (&fl, file);
- n->data = (char *) fl;
+ n->data = fl;
return;
}
@@ -1182,7 +1234,7 @@ unroll_files_proc (p, closure)
return (0);
/* otherwise, call dorecusion for this list of files. */
- filelist = (List *) p->data;
+ filelist = p->data;
p->data = NULL;
save_dirlist = dirlist;
dirlist = NULL;
diff --git a/contrib/cvs/src/release.c b/contrib/cvs/src/release.c
index f87583d..2d8c72c 100644
--- a/contrib/cvs/src/release.c
+++ b/contrib/cvs/src/release.c
@@ -94,7 +94,7 @@ release (argc, argv)
case 'q':
error (1, 0,
"-q or -Q must be specified before \"%s\"",
- command_name);
+ cvs_cmd_name);
break;
case 'd':
delete_flag++;
@@ -116,12 +116,17 @@ release (argc, argv)
* up to the user to take note of them, at least currently
* (ignore-193 in testsuite)).
*/
- /* Construct the update command. */
+ /* Construct the update command. Be sure to add authentication and
+ encryption if we are using them currently, else our child process may
+ not be able to communicate with the server. */
update_cmd = xmalloc (strlen (program_path)
- + strlen (current_parsed_root->original)
- + 20);
- sprintf (update_cmd, "%s -n -q -d %s update",
- program_path, current_parsed_root->original);
+ + strlen (current_parsed_root->original)
+ + 1 + 3 + 3 + 16 + 1);
+ sprintf (update_cmd, "%s %s%s-n -q -d %s update",
+ program_path,
+ cvsauthenticate ? "-a " : "",
+ cvsencrypt ? "-x " : "",
+ current_parsed_root->original);
#ifdef CLIENT_SUPPORT
/* Start the server; we'll close it after looping. */
@@ -216,7 +221,7 @@ release (argc, argv)
if (c) /* "No" */
{
(void) fprintf (stderr, "** `%s' aborted by user choice.\n",
- command_name);
+ cvs_cmd_name);
free (repository);
if (restore_cwd (&cwd, NULL))
error_exit ();
@@ -224,6 +229,17 @@ release (argc, argv)
}
}
+ /* Note: client.c doesn't like to have other code
+ changing the current directory on it. So a fair amount
+ of effort is needed to make sure it doesn't get confused
+ about the directory and (for example) overwrite
+ CVS/Entries file in the wrong directory. See release-17
+ through release-23. */
+
+ free (repository);
+ if (restore_cwd (&cwd, NULL))
+ exit (EXIT_FAILURE);
+
if (1
#ifdef CLIENT_SUPPORT
&& !(current_parsed_root->isremote
@@ -232,13 +248,14 @@ release (argc, argv)
#endif
)
{
- /* We are chdir'ed into the directory in question.
- So don't pass args to unedit. */
- int argc = 1;
+ int argc = 2;
char *argv[3];
argv[0] = "dummy";
- argv[1] = NULL;
+ argv[1] = thisarg;
+ argv[2] = NULL;
err += unedit (argc, argv);
+ if (restore_cwd (&cwd, NULL))
+ exit (EXIT_FAILURE);
}
#ifdef CLIENT_SUPPORT
@@ -255,11 +272,6 @@ release (argc, argv)
history_write ('F', thisarg, "", thisarg, ""); /* F == Free */
}
- free (repository);
-
- if (restore_cwd (&cwd, NULL))
- error_exit ();
-
if (delete_flag)
{
/* FIXME? Shouldn't this just delete the CVS-controlled
@@ -272,7 +284,17 @@ release (argc, argv)
#ifdef CLIENT_SUPPORT
if (current_parsed_root->isremote)
- err += get_server_responses ();
+ {
+ /* FIXME:
+ * Is there a good reason why get_server_responses() isn't
+ * responsible for restoring its initial directory itself when
+ * finished?
+ */
+ err += get_server_responses ();
+
+ if (restore_cwd (&cwd, NULL))
+ exit (EXIT_FAILURE);
+ }
#endif /* CLIENT_SUPPORT */
}
diff --git a/contrib/cvs/src/remove.c b/contrib/cvs/src/remove.c
index 01cdfb4..2a3545a 100644
--- a/contrib/cvs/src/remove.c
+++ b/contrib/cvs/src/remove.c
@@ -22,8 +22,8 @@ static int remove_force_fileproc PROTO ((void *callerdat,
struct file_info *finfo));
#endif
static int remove_fileproc PROTO ((void *callerdat, struct file_info *finfo));
-static Dtype remove_dirproc PROTO ((void *callerdat, char *dir,
- char *repos, char *update_dir,
+static Dtype remove_dirproc PROTO ((void *callerdat, const char *dir,
+ const char *repos, const char *update_dir,
List *entries));
static int force;
@@ -90,7 +90,8 @@ cvsremove (argc, argv)
start_recursion (remove_force_fileproc, (FILESDONEPROC) NULL,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL,
(void *) NULL, argc, argv, local, W_LOCAL,
- 0, CVS_LOCK_NONE, (char *) NULL, 0);
+ 0, CVS_LOCK_NONE, (char *) NULL, 0,
+ (char *) NULL);
}
/* else FIXME should probably act as if the file doesn't exist
in doing the following checks. */
@@ -114,7 +115,8 @@ cvsremove (argc, argv)
err = start_recursion (remove_fileproc, (FILESDONEPROC) NULL,
remove_dirproc, (DIRLEAVEPROC) NULL, NULL,
argc, argv,
- local, W_LOCAL, 0, CVS_LOCK_READ, (char *) NULL, 1);
+ local, W_LOCAL, 0, CVS_LOCK_READ, (char *) NULL, 1,
+ (char *) NULL);
if (removed_files && !really_quiet)
error (0, 0, "use '%s commit' to remove %s permanently", program_name,
@@ -276,9 +278,9 @@ cannot remove file `%s' which has a sticky date of `%s'",
static Dtype
remove_dirproc (callerdat, dir, repos, update_dir, entries)
void *callerdat;
- char *dir;
- char *repos;
- char *update_dir;
+ const char *dir;
+ const char *repos;
+ const char *update_dir;
List *entries;
{
if (!quiet)
diff --git a/contrib/cvs/src/repos.c b/contrib/cvs/src/repos.c
index 8cdcb45..2c7a3bc 100644
--- a/contrib/cvs/src/repos.c
+++ b/contrib/cvs/src/repos.c
@@ -21,11 +21,11 @@
char *
Name_Repository (dir, update_dir)
- char *dir;
- char *update_dir;
+ const char *dir;
+ const char *update_dir;
{
FILE *fpin;
- char *xupdate_dir;
+ const char *xupdate_dir;
char *repos = NULL;
size_t repos_allocated = 0;
char *tmp;
@@ -123,8 +123,9 @@ Name_Repository (dir, update_dir)
error (0, 0, "`..'-relative repositories are not supported.");
error (1, 0, "illegal source repository");
}
- newrepos = xmalloc (strlen (current_parsed_root->directory) + strlen (repos) + 2);
- (void) sprintf (newrepos, "%s/%s", current_parsed_root->directory, repos);
+ newrepos = xmalloc (strlen (current_parsed_root->directory)
+ + strlen (repos) + 2);
+ sprintf (newrepos, "%s/%s", current_parsed_root->directory, repos);
free (repos);
repos = newrepos;
}
@@ -134,29 +135,33 @@ Name_Repository (dir, update_dir)
return repos;
}
+
+
/*
* Return a pointer to the repository name relative to CVSROOT from a
* possibly fully qualified repository
*/
-char *
+const char *
Short_Repository (repository)
- char *repository;
+ const char *repository;
{
if (repository == NULL)
- return (NULL);
+ return NULL;
/* If repository matches CVSroot at the beginning, strip off CVSroot */
/* And skip leading '/' in rep, in case CVSroot ended with '/'. */
if (strncmp (current_parsed_root->directory, repository,
strlen (current_parsed_root->directory)) == 0)
{
- char *rep = repository + strlen (current_parsed_root->directory);
+ const char *rep = repository + strlen (current_parsed_root->directory);
return (*rep == '/') ? rep+1 : rep;
}
else
- return (repository);
+ return repository;
}
+
+
/* Sanitize the repository name (in place) by removing trailing
* slashes and a trailing "." if present. It should be safe for
* callers to use strcat and friends to create repository names.
@@ -179,12 +184,7 @@ Short_Repository (repository)
* back further someday, so that the trailing "/." doesn't get into
* repository in the first place, but we haven't taken things that
* far yet.'' --Jim Kingdon (recurse.c, 07-Sep-97)
- *
- * Ahh, all too true. The major consideration is RELATIVE_REPOS. If
- * the "/." doesn't end up in the repository while RELATIVE_REPOS is
- * defined, there will be nothing in the CVS/Repository file. I
- * haven't verified that the remote protocol will handle that
- * correctly yet, so I've not made that change. */
+ */
void
Sanitize_Repository_Name (repository)
diff --git a/contrib/cvs/src/root.c b/contrib/cvs/src/root.c
index 8308e97..05aa0bd 100644
--- a/contrib/cvs/src/root.c
+++ b/contrib/cvs/src/root.c
@@ -16,8 +16,9 @@
/* Printable names for things in the current_parsed_root->method enum variable.
Watch out if the enum is changed in cvs.h! */
-char *method_names[] = {
- "undefined", "local", "server (rsh)", "pserver", "kserver", "gserver", "ext", "fork"
+const char method_names[][16] = {
+ "undefined", "local", "server (rsh)", "pserver",
+ "kserver", "gserver", "ext", "fork"
};
#ifndef DEBUG
@@ -34,6 +35,7 @@ Name_Root (dir, update_dir)
char *tmp;
char *cvsadm;
char *cp;
+ int len;
if (update_dir && *update_dir)
xupdate_dir = update_dir;
@@ -73,18 +75,20 @@ Name_Root (dir, update_dir)
*/
fpin = open_file (tmp, "r");
- if (getline (&root, &root_allocated, fpin) < 0)
+ if ((len = getline (&root, &root_allocated, fpin)) < 0)
{
+ int saved_errno = errno;
/* FIXME: should be checking for end of file separately; errno
is not set in that case. */
error (0, 0, "in directory %s:", xupdate_dir);
- error (0, errno, "cannot read %s", CVSADM_ROOT);
+ error (0, saved_errno, "cannot read %s", CVSADM_ROOT);
error (0, 0, "please correct this problem");
ret = NULL;
goto out;
}
- (void) fclose (fpin);
- if ((cp = strrchr (root, '\n')) != NULL)
+ fclose (fpin);
+ cp = root + (len - 1);
+ if (*cp == '\n')
*cp = '\0'; /* strip the newline */
/*
@@ -131,6 +135,8 @@ Name_Root (dir, update_dir)
return (ret);
}
+
+
/*
* Write the CVS/Root file so that the environment variable CVSROOT
* and/or the -d option to cvs will be validated or not necessary for
@@ -138,8 +144,8 @@ Name_Root (dir, update_dir)
*/
void
Create_Root (dir, rootdir)
- char *dir;
- char *rootdir;
+ const char *dir;
+ const char *rootdir;
{
FILE *fout;
char *tmp;
@@ -287,12 +293,14 @@ new_cvsroot_t ()
newroot->original = NULL;
newroot->method = null_method;
+#ifdef CLIENT_SUPPORT
newroot->username = NULL;
newroot->password = NULL;
newroot->hostname = NULL;
newroot->port = 0;
newroot->directory = NULL;
-#ifdef CLIENT_SUPPORT
+ newroot->proxy_hostname = NULL;
+ newroot->proxy_port = 0;
newroot->isremote = 0;
#endif /* CLIENT_SUPPORT */
@@ -308,6 +316,9 @@ free_cvsroot_t (root)
{
if (root->original != NULL)
free (root->original);
+ if (root->directory != NULL)
+ free (root->directory);
+#ifdef CLIENT_SUPPORT
if (root->username != NULL)
free (root->username);
if (root->password != NULL)
@@ -318,8 +329,9 @@ free_cvsroot_t (root)
}
if (root->hostname != NULL)
free (root->hostname);
- if (root->directory != NULL)
- free (root->directory);
+ if (root->proxy_hostname != NULL)
+ free (root->proxy_hostname);
+#endif /* CLIENT_SUPPORT */
free (root);
}
@@ -350,7 +362,7 @@ free_cvsroot_t (root)
*/
cvsroot_t *
parse_cvsroot (root_in)
- char *root_in;
+ const char *root_in;
{
cvsroot_t *newroot; /* the new root to be returned */
char *cvsroot_save; /* what we allocated so we can dispose
@@ -360,7 +372,9 @@ parse_cvsroot (root_in)
* [[user][:password]@]host[:[port]]
*/
char *cvsroot_copy, *p, *q; /* temporary pointers for parsing */
+#ifdef CLIENT_SUPPORT
int check_hostname, no_port, no_password;
+#endif /* CLIENT_SUPPORT */
/* allocate some space */
newroot = new_cvsroot_t();
@@ -392,6 +406,25 @@ parse_cvsroot (root_in)
*p = '\0';
cvsroot_copy = ++p;
+#ifdef CLIENT_SUPPORT
+ /* Look for method options, for instance, proxy, proxyport.
+ * We don't handle these, but we like to try and warn the user that
+ * they are being ignored.
+ */
+ if (p = strchr (method, ';'))
+ {
+ *p++ = '\0';
+ if (!really_quiet)
+ {
+ error (0, 0,
+"WARNING: Ignoring method options found in CVSROOT: `%s'.",
+ p);
+ error (0, 0,
+"Use CVS version 1.12.7 or later to handle method options.");
+ }
+ }
+#endif /* CLIENT_SUPPORT */
+
/* Now we have an access method -- see if it's valid. */
if (strcmp (method, "local") == 0)
@@ -440,13 +473,18 @@ parse_cvsroot (root_in)
if ((p = strchr (cvsroot_copy, '/')) == NULL)
{
error (0, 0, "CVSROOT requires a path spec:");
- error (0, 0, ":(gserver|kserver|pserver):[[user][:password]@]host[:[port]]/path");
+ error (0, 0,
+":(gserver|kserver|pserver):[[user][:password]@]host[:[port]]/path");
error (0, 0, "[:(ext|server):][[user]@]host[:]/path");
goto error_exit;
}
firstslash = p; /* == NULL if '/' not in string */
*p = '\0';
+ /* Don't parse username, password, hostname, or port without client
+ * support.
+ */
+#ifdef CLIENT_SUPPORT
/* Check to see if there is a username[:password] in the string. */
if ((p = strchr (cvsroot_copy, '@')) != NULL)
{
@@ -488,15 +526,18 @@ parse_cvsroot (root_in)
{
if (!isdigit(*q++))
{
- error (0, 0, "CVSROOT may only specify a positive, non-zero, integer port (not `%s').",
+ error (0, 0,
+"CVSROOT may only specify a positive, non-zero, integer port (not `%s').",
p);
- error (0, 0, "Perhaps you entered a relative pathname?");
+ error (0, 0,
+ "Perhaps you entered a relative pathname?");
goto error_exit;
}
}
if ((newroot->port = atoi (p)) <= 0)
{
- error (0, 0, "CVSROOT may only specify a positive, non-zero, integer port (not `%s').",
+ error (0, 0,
+"CVSROOT may only specify a positive, non-zero, integer port (not `%s').",
p);
error (0, 0, "Perhaps you entered a relative pathname?");
goto error_exit;
@@ -514,9 +555,17 @@ parse_cvsroot (root_in)
/* restore the '/' */
cvsroot_copy = firstslash;
*cvsroot_copy = '/';
+#endif /* CLIENT_SUPPORT */
}
- /* parse the path for all methods */
+ /*
+ * Parse the path for all methods.
+ */
+ /* Here & local_cvsroot() should be the only places this needs to be
+ * called on a CVSROOT now. cvsroot->original is saved for error messages
+ * and, otherwise, we want no trailing slashes.
+ */
+ Sanitize_Repository_Name( cvsroot_copy );
newroot->directory = xstrdup(cvsroot_copy);
/*
@@ -541,6 +590,7 @@ parse_cvsroot (root_in)
}
#endif
+#ifdef CLIENT_SUPPORT
if (newroot->username && ! newroot->hostname)
{
error (0, 0, "Missing hostname in CVSROOT.");
@@ -548,17 +598,22 @@ parse_cvsroot (root_in)
}
check_hostname = 0;
- no_password = 0;
+ no_password = 1;
no_port = 0;
+#endif /* CLIENT_SUPPORT */
switch (newroot->method)
{
case local_method:
+#ifdef CLIENT_SUPPORT
if (newroot->username || newroot->hostname)
{
error (0, 0, "Can't specify hostname and username in CVSROOT");
error (0, 0, "when using local access method.");
goto error_exit;
}
+ no_port = 1;
+ /* no_password already set */
+#endif /* CLIENT_SUPPORT */
/* cvs.texinfo has always told people that CVSROOT must be an
absolute pathname. Furthermore, attempts to use a relative
pathname produced various errors (I couldn't get it to work),
@@ -571,9 +626,8 @@ parse_cvsroot (root_in)
error (0, 0, "when using local access method.");
goto error_exit;
}
- no_port = 1;
- no_password = 1;
break;
+#ifdef CLIENT_SUPPORT
case fork_method:
/* We want :fork: to behave the same as other remote access
methods. Therefore, don't check to see that the repository
@@ -584,6 +638,7 @@ parse_cvsroot (root_in)
error (0, 0, "when using fork access method.");
goto error_exit;
}
+ newroot->hostname = xstrdup("server"); /* for error messages */
if (!isabsolute (newroot->directory))
{
error (0, 0, "CVSROOT must be an absolute pathname (not `%s')",
@@ -592,39 +647,44 @@ parse_cvsroot (root_in)
goto error_exit;
}
no_port = 1;
- no_password = 1;
+ /* no_password already set */
break;
case kserver_method:
-#ifndef HAVE_KERBEROS
+# ifndef HAVE_KERBEROS
error (0, 0, "CVSROOT is set for a kerberos access method but your");
error (0, 0, "CVS executable doesn't support it.");
goto error_exit;
-#else
+# else
check_hostname = 1;
+ /* no_password already set */
break;
-#endif
+# endif
case gserver_method:
-#ifndef HAVE_GSSAPI
+# ifndef HAVE_GSSAPI
error (0, 0, "CVSROOT is set for a GSSAPI access method but your");
error (0, 0, "CVS executable doesn't support it.");
goto error_exit;
-#else
+# else
check_hostname = 1;
+ /* no_password already set */
break;
-#endif
+# endif
case server_method:
case ext_method:
no_port = 1;
- no_password = 1;
+ /* no_password already set */
check_hostname = 1;
break;
case pserver_method:
+ no_password = 0;
check_hostname = 1;
break;
+#endif /* CLIENT_SUPPORT */
default:
error (1, 0, "Invalid method found in parse_cvsroot");
}
+#ifdef CLIENT_SUPPORT
if (no_password && newroot->password)
{
error (0, 0, "CVSROOT password specification is only valid for");
@@ -644,6 +704,7 @@ parse_cvsroot (root_in)
error (0, 0, "and pserver connection methods.");
goto error_exit;
}
+#endif /* CLIENT_SUPPORT */
if (*newroot->directory == '\0')
{
@@ -718,14 +779,18 @@ normalize_cvsroot (root)
* repository DIR. */
cvsroot_t *
local_cvsroot (dir)
- char *dir;
+ const char *dir;
{
cvsroot_t *newroot = new_cvsroot_t();
newroot->original = xstrdup(dir);
newroot->method = local_method;
newroot->directory = xstrdup(dir);
-
+ /* Here and parse_cvsroot() should be the only places this needs to be
+ * called on a CVSROOT now. cvsroot->original is saved for error messages
+ * and, otherwise, we want no trailing slashes.
+ */
+ Sanitize_Repository_Name( newroot->directory );
return newroot;
}
@@ -741,7 +806,7 @@ local_cvsroot (dir)
#include <stdio.h>
char *program_name = "testing";
-char *command_name = "parse_cvsroot"; /* XXX is this used??? */
+char *cvs_cmd_name = "parse_cvsroot"; /* XXX is this used??? */
/* Toy versions of various functions when debugging under unix. Yes,
these make various bad assumptions, but they're pretty easy to
@@ -790,5 +855,3 @@ main (argc, argv)
/* NOTREACHED */
}
#endif
-/* vim:tabstop=8:shiftwidth=4
- */
diff --git a/contrib/cvs/src/root.h b/contrib/cvs/src/root.h
index afe79b6..b812eef 100644
--- a/contrib/cvs/src/root.h
+++ b/contrib/cvs/src/root.h
@@ -20,18 +20,23 @@ typedef enum {
ext_method,
fork_method
} CVSmethod;
-extern char *method_names[]; /* change this in root.c if you change
- the enum above */
+extern const char method_names[][16]; /* change this in root.c if you change
+ the enum above */
typedef struct cvsroot_s {
- char *original; /* the complete source CVSroot string */
- CVSmethod method; /* one of the enum values above */
- char *username; /* the username or NULL if method == local */
- char *password; /* the username or NULL if method == local */
- char *hostname; /* the hostname or NULL if method == local */
- int port; /* the port or zero if method == local */
- char *directory; /* the directory name */
+ char *original; /* The complete source CVSroot string. */
+ CVSmethod method; /* One of the enum values above. */
+ char *directory; /* The directory name. */
#ifdef CLIENT_SUPPORT
- unsigned char isremote; /* nonzero if we are doing remote access */
+ char *username; /* The username or NULL if method == local. */
+ char *password; /* The password or NULL if method == local. */
+ char *hostname; /* The hostname or NULL if method == local. */
+ int port; /* The port or zero if method == local. */
+ char *proxy_hostname; /* The hostname of the proxy server, or NULL
+ * when method == local or no proxy will be
+ * 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;
diff --git a/contrib/cvs/src/run.c b/contrib/cvs/src/run.c
index 2d020eb..b03d683 100644
--- a/contrib/cvs/src/run.c
+++ b/contrib/cvs/src/run.c
@@ -91,6 +91,8 @@ run_add_arg (s)
run_argv[run_argc] = (char *) 0; /* not post-incremented on purpose! */
}
+
+
int
run_exec (stin, stout, sterr, flags)
const char *stin;
@@ -129,10 +131,10 @@ run_exec (stin, stout, sterr, flags)
cvs_outerr (")\n", 0);
}
if (noexec && (flags & RUN_REALLY) == 0)
- return (0);
+ return 0;
/* make sure that we are null terminated, since we didn't calloc */
- run_add_arg ((char *) 0);
+ run_add_arg ((char *)0);
/* setup default file descriptor numbers */
shin = 0;
@@ -170,8 +172,8 @@ run_exec (stin, stout, sterr, flags)
}
/* Make sure we don't flush this twice, once in the subprocess. */
- fflush (stdout);
- fflush (stderr);
+ cvs_flushout();
+ cvs_flusherr();
/* The output files, if any, are now created. Do the fork and dups.
@@ -251,7 +253,7 @@ run_exec (stin, stout, sterr, flags)
#ifdef BSD_SIGNALS
if (flags & RUN_SIGIGNORE)
{
- memset ((char *) &vec, 0, sizeof (vec));
+ memset ((char *)&vec, 0, sizeof (vec));
vec.sv_handler = SIG_IGN;
(void) sigvec (SIGINT, &vec, &ivec);
(void) sigvec (SIGQUIT, &vec, &qvec);
@@ -300,17 +302,17 @@ run_exec (stin, stout, sterr, flags)
#ifdef POSIX_SIGNALS
if (flags & RUN_SIGIGNORE)
{
- (void) sigaction (SIGINT, &iact, (struct sigaction *) NULL);
- (void) sigaction (SIGQUIT, &qact, (struct sigaction *) NULL);
+ (void) sigaction (SIGINT, &iact, (struct sigaction *)NULL);
+ (void) sigaction (SIGQUIT, &qact, (struct sigaction *)NULL);
}
else
- (void) sigprocmask (SIG_SETMASK, &sigset_omask, (sigset_t *) NULL);
+ (void) sigprocmask (SIG_SETMASK, &sigset_omask, (sigset_t *)NULL);
#else
#ifdef BSD_SIGNALS
if (flags & RUN_SIGIGNORE)
{
- (void) sigvec (SIGINT, &ivec, (struct sigvec *) NULL);
- (void) sigvec (SIGQUIT, &qvec, (struct sigvec *) NULL);
+ (void) sigvec (SIGINT, &ivec, (struct sigvec *)NULL);
+ (void) sigvec (SIGQUIT, &qvec, (struct sigvec *)NULL);
}
else
(void) sigsetmask (mask);
@@ -344,9 +346,11 @@ run_exec (stin, stout, sterr, flags)
out0:
if (rerrno)
errno = rerrno;
- return (rc);
+ return rc;
}
+
+
void
run_print (fp)
FILE *fp;
@@ -398,7 +402,7 @@ run_popen (cmd, mode)
int
piped_child (command, tofdp, fromfdp)
- char **command;
+ const char **command;
int *tofdp;
int *fromfdp;
{
@@ -436,7 +440,8 @@ piped_child (command, tofdp, fromfdp)
if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0)
error (1, errno, "cannot dup2 pipe");
- execvp (command[0], command);
+ /* Okay to cast out const below - execvp don't return anyhow. */
+ execvp ((char *)command[0], (char **)command);
error (1, errno, "cannot exec %s", command[0]);
}
if (close (to_child_pipe[0]) < 0)
@@ -455,7 +460,7 @@ close_on_exec (fd)
int fd;
{
#ifdef F_SETFD
- if (fcntl (fd, F_SETFD, 1))
+ if (fcntl (fd, F_SETFD, 1) == -1)
error (1, errno, "can't set close-on-exec flag on %d", fd);
#endif
}
diff --git a/contrib/cvs/src/sanity.sh b/contrib/cvs/src/sanity.sh
index c6e504e..015d83e 100755
--- a/contrib/cvs/src/sanity.sh
+++ b/contrib/cvs/src/sanity.sh
@@ -19,17 +19,40 @@
# Original Author: K. Richard Pixley
# usage:
+usage ()
+{
+ echo "Usage: `basename $0` --help"
+ echo "Usage: `basename $0` [-klr] [-f FROM-TEST] [-h HOSTNAME] CVS-TO-TEST [TESTS-TO-RUN...]"
+}
+
exit_usage ()
{
- echo "Usage: `basename $0` [-kr] [-f FROM-TEST] CVS-TO-TEST [TESTS-TO-RUN...]" 1>&2
+ usage 1>&2
+ exit 2
+}
+
+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 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
+ 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
}
-# -r test remote instead of local cvs.
-# -k try to keep directories created by individual tests around
-# -f FROM-TEST run TESTS-TO-RUN, skipping all tests in the list before
-# FROM-TEST
-#
-# TESTS-TO-RUN are the names of the tests to run; if omitted default to all tests.
# See TODO list at end of file.
@@ -53,20 +76,60 @@ export LC_ALL
# read our options
#
unset fromtest
+unset remotehost
keep=false
+linkroot=false
remote=false
-while getopts f:kr option ; do
+while getopts f:h:Hklr-: option ; do
+ # convert the long opts to short opts
+ if test x$option = x-; then
+ case "$OPTARG" in
+ [hH]|[hH][eE]|[hH][eE][lL]|[hH][eE][lL][pP])
+ option=H;
+ OPTARG=
+ ;;
+ [kK]|[kK][eE]|[kK][eE][eE]|[kK][eE][eE][pP])
+ option=k;
+ OPTARG=
+ ;;
+ l|li|lin|link|link-|link-r]|link-ro|link-roo|link-root)
+ option=l;
+ OPTARG=
+ ;;
+ [rR]|[rR][eE]|[rR][eE][mM]|[rR][eE][mM][oO]|[rR][eE][mM][oO][tT]|[rR][eE][mM][oO][tT][eE])
+ option=k;
+ OPTARG=
+ ;;
+ *)
+ option=\?
+ OPTARG=
+ esac
+ fi
case "$option" in
f)
fromtest="$OPTARG"
;;
+ h)
+ # Set a remotehost to run the remote tests on via :ext:
+ # Implies `-r' and assumes that $TESTDIR resolves to the same
+ # directory on the client and the server.
+ remotehost="$OPTARG"
+ remote=:
+ ;;
+ H)
+ exit_help
+ ;;
k)
- # The -k (keep) option will eventually cause all the tests to leave around the
- # contents of the /tmp directory; right now only some implement it. Not
- # originally intended to be useful with more than one test, but this should work
- # if each test uses a uniquely named dir (use the name of the test).
+ # The -k (keep) option will eventually cause all the tests to
+ # leave around the contents of the /tmp directory; right now only
+ # some implement it. Not originally intended to be useful with
+ # more than one test, but this should work if each test uses a
+ # uniquely named dir (use the name of the test).
keep=:
;;
+ l)
+ linkroot=:
+ ;;
r)
remote=:
;;
@@ -97,6 +160,16 @@ case $1 in
esac
shift
+# If $remotehost is set, warn if $TESTDIR isn't since we are pretty sure
+# that its default value of `/tmp/cvs-sanity' will not resolve to the same
+# directory on two different machines.
+if test -n "$remotehost" && test -z "$TESTDIR"; then
+ echo "WARNING: CVS server hostname is set and \$TESTDIR is not. If" >&2
+ echo "$remotehost is not the local machine, then it is unlikely that" >&2
+ echo "the default value assigned to \$TESTDIR will resolve to the same" >&2
+ echo "directory on both this client and the CVS server." >&2
+fi
+
###
@@ -109,7 +182,8 @@ shift
echo 'This test should produce no other output than this message, and a final "OK".'
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.)'
+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.)"
# 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
@@ -132,6 +206,11 @@ tempname="[-a-zA-Z0-9/.%_]*"
RFCDATE="[a-zA-Z0-9 ][a-zA-Z0-9 ]* [0-9:][0-9:]* -0000"
RFCDATE_EPOCH="1 Jan 1970 00:00:00 -0000"
+# Regexp to match a date in standard Unix format as used by rdiff
+# FIXCVS: There's no reason for rdiff to use a different date format
+# than diff does
+DATE="[a-zA-Z]* [a-zA-Z]* [ 1-3][0-9] [0-9:]* [0-9]*"
+
# On cygwin32, we may not have /bin/sh.
if test -r /bin/sh; then
TESTSHELL="/bin/sh"
@@ -160,6 +239,12 @@ if test -f check.log; then
mv check.log check.plog
fi
+# Create the log file so check.log can be tailed almost immediately after
+# this script is started. Otherwise it can take up to a minute or two before
+# the log file gets created when $remotehost is specified on some systems,
+# which makes for a lot of failed `tail -f' attempts.
+touch check.log
+
# 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:
@@ -176,8 +261,18 @@ fi
# So this would be lost if everything was `pwd`-based. I suppose
# if we wanted to get baroque we could start making symlinks
# to ensure the two are different.
-tmp=`(cd /tmp; /bin/pwd || pwd) 2>/dev/null`
-: ${TMPDIR=$tmp}
+: ${CVS_RSH=rsh}; export CVS_RSH
+if test -n "$remotehost"; then
+ # We need to set $tmp on the server since $TMPDIR is compared against
+ # messages generated by the server.
+ tmp=`$CVS_RSH $remotehost 'cd /tmp; /bin/pwd || pwd' 2>/dev/null`
+ if test $? != 0; then
+ echo "$CVS_RSH $remotehost failed." >&2
+ exit 1
+ fi
+else
+ tmp=`(cd /tmp; /bin/pwd || pwd) 2>/dev/null`
+fi
# Now:
# 1) Set TESTDIR if it's not set already
@@ -197,14 +292,33 @@ fi
# wouldn't appreciate that.
mkdir ${TESTDIR} || exit 1
cd ${TESTDIR} || exit 1
-TESTDIR=`(/bin/pwd || pwd) 2>/dev/null`
# Ensure $TESTDIR is absolute
+if echo "${TESTDIR}" |grep '^[^/]'; then
+ # Don't resolve this unless we have to. This keeps symlinks intact. This
+ # is important at least when testing using -h $remotehost, because the same
+ # value for $TESTDIR must resolve to the same directory on the client and
+ # the server and we likely used Samba, and possibly symlinks, to do this.
+ TESTDIR=`(/bin/pwd || pwd) 2>/dev/null`
+fi
+
if test -z "${TESTDIR}" || echo "${TESTDIR}" |grep '^[^/]'; then
echo "Unable to resolve TESTDIR to an absolute directory." >&2
exit 1
fi
cd ${TESTDIR}
+# Now set $TMPDIR if the user hasn't overridden it.
+#
+# We use a $TMPDIR under $TESTDIR by default so that two tests may be run at
+# the same time without bumping heads without requiring the user to specify
+# more than $TESTDIR. See the test for leftover cvs-serv* directories near the
+# end of this script at the end of "The big loop".
+: ${TMPDIR=$TESTDIR/tmp}
+export TMPDIR
+if test -d $TMPDIR; then :; else
+ mkdir $TMPDIR
+fi
+
# Make sure various tools work the way we expect, or try to find
# versions that do.
: ${AWK=awk}
@@ -293,8 +407,8 @@ b' : 'a
c' >/dev/null; then
EXPR=`find_tool expr`
if test -z "$EXPR" ; then
- echo 'Warning: you are using a version of expr which does not correctly'
- echo 'match multi-line patterns. Some tests may spuriously pass.'
+ 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
@@ -312,8 +426,8 @@ if $EXPR "`cat ${TESTDIR}/bar`" : "`cat ${TESTDIR}/bar`" >/dev/null; then
else
EXPR=`find_tool expr`
if test -z "$EXPR" ; then
- echo 'Warning: you are using a version of expr which does not correctly'
- echo 'match large patterns. Some tests may spuriously fail.'
+ 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
@@ -321,8 +435,8 @@ 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 which does not correctly'
- echo 'match large patterns. Some tests may spuriously pass.'
+ 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
@@ -364,8 +478,8 @@ if $EXPR "`cat ${TESTDIR}/bar`" : "${DOTSTAR}xyzABC${DOTSTAR}$" >/dev/null; then
else
EXPR=`find_tool expr`
if test -z "$EXPR" ; then
- echo 'Warning: you are using a version of expr which does not correctly'
- echo 'match large patterns. Some tests may spuriously fail.'
+ 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
@@ -426,6 +540,7 @@ pass ()
fail ()
{
echo "FAIL: $1" | tee -a ${LOGFILE}
+ echo "*** Please see the \`TESTS' and \`check.log' files for more information." >&2
# This way the tester can go and see what remnants were left
exit 1
}
@@ -624,19 +739,6 @@ dotest_fail ()
dotest_internal "$@"
}
-# Like dotest except second argument is the required exitstatus.
-dotest_status ()
-{
- eval "$3" >${TESTDIR}/dotest.tmp 2>&1
- status=$?
- if test "$status" != "$2"; then
- cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
- echo "exit status was $status; expected $2" >>${LOGFILE}
- fail "$1"
- fi
- dotest_internal "$1" "$3" "$4" "$5"
-}
-
# Like dotest except output is sorted.
dotest_sort ()
{
@@ -671,24 +773,28 @@ RCSINIT=; export RCSINIT
if test x"$*" = x; then
# Basic/miscellaneous functionality
tests="version basica basicb basicc basic1 deep basic2"
- tests="${tests} files spacefiles commit-readonly"
+ tests="${tests} parseroot files spacefiles commit-readonly"
tests="${tests} commit-add-missing"
+ tests="${tests} status"
# Branching, tagging, removing, adding, multiple directories
- tests="${tests} rdiff diff death death2 rm-update-message rmadd rmadd2"
+ tests="${tests} rdiff rdiff-short"
+ tests="${tests} rdiff2 diff diffnl death death2"
+ tests="${tests} rm-update-message rmadd rmadd2 rmadd3 resurrection"
tests="${tests} dirs dirs2 branches branches2 tagc tagf"
- tests="${tests} rcslib multibranch import importb importc"
- tests="${tests} update-p import-after-initial"
- tests="${tests} join join2 join3 join-readonly-conflict"
- tests="${tests} join-admin join-admin-2"
+ tests="${tests} rcslib multibranch import importb importc import-CVS"
+ tests="${tests} update-p import-after-initial branch-after-import"
+ tests="${tests} join join2 join3 join4 join5 join6"
+ tests="${tests} join-readonly-conflict join-admin join-admin-2"
+ tests="${tests} join-rm"
tests="${tests} new newb conflicts conflicts2 conflicts3"
tests="${tests} clean"
# Checking out various places (modules, checkout -d, &c)
tests="${tests} modules modules2 modules3 modules4 modules5 modules6"
- tests="${tests} mkmodules-temp-file-removal"
- tests="${tests} cvsadm emptydir abspath toplevel toplevel2"
- tests="${tests} checkout_repository"
+ tests="${tests} mkmodules co-d"
+ tests="${tests} cvsadm emptydir abspath abspath2 toplevel toplevel2"
+ tests="${tests} top-level checkout_repository"
# Log messages, error messages.
- tests="${tests} mflag editor errmsg1 errmsg2 adderrmsg"
+ tests="${tests} mflag editor errmsg1 errmsg2 adderrmsg opterrmsg"
# Watches, binary files, history browsing, &c.
tests="${tests} devcom devcom2 devcom3 watch4 watch5"
tests="${tests} unedit-without-baserev"
@@ -705,7 +811,7 @@ if test x"$*" = x; then
# PreservePermissions stuff: permissions, symlinks et al.
# tests="${tests} perms symlinks symlinks2 hardlinks"
# More tag and branch tests, keywords.
- tests="${tests} sticky keyword keyword2 keywordlog"
+ tests="${tests} sticky keyword keywordlog keywordname keyword2"
tests="${tests} head tagdate multibranch2 tag8k"
# "cvs admin", reserved checkouts.
tests="${tests} admin reserved"
@@ -713,14 +819,39 @@ if test x"$*" = x; then
tests="${tests} diffmerge1 diffmerge2"
# Release of multiple directories
tests="${tests} release"
+ tests="${tests} recase"
# Multiple root directories and low-level protocol tests.
tests="${tests} multiroot multiroot2 multiroot3 multiroot4"
tests="${tests} rmroot reposmv pserver server server2 client"
- tests="${tests} fork commit-d"
+ tests="${tests} dottedroot fork commit-d"
else
tests="$*"
fi
+# Now check the -f argument for validity.
+if test -n "$fromtest"; then
+ # Don't allow spaces - they are our delimiters in tests
+ count=0
+ for sub in $fromtest; do
+ count=`expr $count + 1`
+ done
+ if test $count != 1; then
+ echo "No such test \`$fromtest'." >&2
+ exit 2
+ fi
+ # make sure it is in $tests
+ case " $tests " in
+ *" $fromtest "*)
+ ;;
+ *)
+ echo "No such test \`$fromtest'." >&2
+ exit 2
+ ;;
+ esac
+fi
+
+
+
# a simple function to compare directory contents
#
# Returns: 0 for same, 1 for different
@@ -732,14 +863,14 @@ directory_cmp ()
DIR_2=$2
cd $DIR_1
- find . -print | fgrep -v /CVS | sort > /tmp/dc$$d1
+ find . -print | fgrep -v /CVS | sort > $TESTDIR/dc$$d1
# go back where we were to avoid symlink hell...
cd $OLDPWD
cd $DIR_2
- find . -print | fgrep -v /CVS | sort > /tmp/dc$$d2
+ find . -print | fgrep -v /CVS | sort > $TESTDIR/dc$$d2
- if diff /tmp/dc$$d1 /tmp/dc$$d2 >/dev/null 2>&1
+ if diff $TESTDIR/dc$$d1 $TESTDIR/dc$$d2 >/dev/null 2>&1
then
:
else
@@ -754,8 +885,8 @@ directory_cmp ()
return 1
fi
fi
- done < /tmp/dc$$d1
- rm -f /tmp/dc$$*
+ done < $TESTDIR/dc$$d1
+ rm -f $TESTDIR/dc$$*
return 0
}
@@ -1563,21 +1694,57 @@ MTGTXM MtatRk = Zy;
EOF
}
+
+
+# Echo a new CVSROOT based on $1, $remote, and $remotehost
+newroot() {
+ if $remote; then
+ if test -n "$remotehost"; then
+ echo :ext:$remotehost$1
+ else
+ echo :fork:$1
+ fi
+ else
+ echo $1
+ fi
+}
+
+
+
# Set up CVSROOT (the crerepos tests will test operating without CVSROOT set).
-CVSROOT_DIRNAME=${TESTDIR}/cvsroot
-if $remote; then
- # Currently we test :fork: and :ext: (see crerepos test).
- # Testing :pserver: would be hard (inetd issues).
- # Also :ext: and :fork support CVS_SERVER in a convenient way.
- # If you want to edit this script to change the next line to
- # :ext:, you can run the tests that way. There is a known
- # difference in modes-15 (see comments there).
- CVSROOT=:fork:${CVSROOT_DIRNAME} ; export CVSROOT
- CVS_SERVER=${testcvs}; export CVS_SERVER
-else
- CVSROOT=${CVSROOT_DIRNAME} ; export CVSROOT
+#
+# Currently we test :fork: and :ext: (see crerepos test). There is a
+# known difference between the two in modes-15 (see comments there).
+#
+# :ext: can be tested against a remote machine if:
+#
+# 1. $remotehost is set using the `-h' option to this script.
+# 2. ${CVS_RSH=rsh} $remotehost works.
+# 3. The path to $TESTDIR is the same on both machines (symlinks are okay)
+# 4. The path to $testcvs is the same on both machines (symlinks are okay)
+# or $CVS_SERVER is overridden in this script's environment to point to
+# a working CVS exectuable on the remote machine.
+#
+# Testing :pserver: would be hard (inetd issues). (How about using tcpserver
+# and some high port number? DRP)
+
+# Allow CVS_SERVER to be overridden. This facilitates constructs like
+# testing a local case-insensitive client against a remote case
+# sensitive server and visa versa.
+: ${CVS_SERVER=$testcvs}; export CVS_SERVER
+
+if $linkroot; then
+ mkdir ${TESTDIR}/realcvsroot
+ ln -s realcvsroot ${TESTDIR}/cvsroot
fi
+CVSROOT_DIRNAME=${TESTDIR}/cvsroot
+CVSROOT=`newroot $CVSROOT_DIRNAME`; export CVSROOT
+
+
+###
+### The tests
+###
dotest 1 "${testcvs} init" ''
dotest 1a "${testcvs} init" ''
@@ -1675,11 +1842,11 @@ ${PROG}"' \[[a-z]* aborted\]: correct above errors first!' \
'"${PROG}"' \[[a-z]* aborted\]: correct above errors first!'
dotest basica-4 "${testcvs} add ssfile" \
-"${PROG}"' [a-z]*: scheduling file `ssfile'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `ssfile'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest_fail basica-4a "${testcvs} tag tag0 ssfile" \
-"${PROG} [a-z]*: nothing known about ssfile
-${PROG} "'\[[a-z]* aborted\]: correct the above errors first!'
+"${PROG} tag: nothing known about ssfile
+${PROG} "'\[tag aborted\]: correct the above errors first!'
cd ../..
dotest basica-5 "${testcvs} -q ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
@@ -1690,14 +1857,14 @@ initial revision: 1\.1
done"
dotest_fail basica-5a \
"${testcvs} -q tag BASE sdir/ssdir/ssfile" \
-"${PROG} [a-z]*: Attempt to add reserved tag name BASE
-${PROG} \[[a-z]* aborted\]: failed to set tag BASE to revision 1\.1 in ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v"
+"${PROG} tag: Attempt to add reserved tag name BASE
+${PROG} \[tag aborted\]: failed to set tag BASE to revision 1\.1 in ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v"
dotest basica-5b "${testcvs} -q tag NOT_RESERVED" \
'T sdir/ssdir/ssfile'
dotest basica-6 "${testcvs} -q update" ''
echo "ssfile line 2" >>sdir/ssdir/ssfile
- dotest_status basica-6.2 1 "${testcvs} -q diff -c" \
+ dotest_fail basica-6.2 "${testcvs} -q diff -c" \
"Index: sdir/ssdir/ssfile
===================================================================
RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
@@ -1710,7 +1877,7 @@ diff -c -r1\.1 ssfile
--- 1,2 ----
ssfile
${PLUS} ssfile line 2"
- dotest_status basica-6.3 1 "${testcvs} -q diff -c -rBASE" \
+ dotest_fail basica-6.3 "${testcvs} -q diff -c -rBASE" \
"Index: sdir/ssdir/ssfile
===================================================================
RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
@@ -1723,6 +1890,13 @@ diff -c -r1\.1 ssfile
--- 1,2 ----
ssfile
${PLUS} ssfile line 2"
+ dotest_fail basica-6.4 "${testcvs} -q diff -c -rBASE -C3isacrowd" \
+"Index: sdir/ssdir/ssfile
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
+retrieving revision 1\.1
+diff -c -C3isacrowd -r1\.1 ssfile
+${PROG} diff: invalid context length argument"
dotest basica-7 "${testcvs} -q ci -m modify-it" \
"Checking in sdir/ssdir/ssfile;
${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
@@ -1758,8 +1932,8 @@ done"
dotest_fail basica-8a3 "${testcvs} -q ci -m bogus -r 3.0.0" \
"Checking in ssfile;
${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v: can't find branch point 3\.0
-${PROG} [a-z]*: could not check in ssfile"
+${PROG} commit: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v: can't find branch point 3\.0
+${PROG} commit: could not check in ssfile"
dotest basica-8a4 "${testcvs} -q ci -m valid -r 3.1.2" \
"Checking in ssfile;
${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
@@ -1769,22 +1943,9 @@ done"
dotest basica-8a5 "${testcvs} -q up -A ./" "[UP] ssfile"
cd ../..
- dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" \
-"Index: sdir/ssdir/ssfile
-===================================================================
-RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
-retrieving revision 1\.2
-retrieving revision 1\.3
-diff -r1\.2 -r1\.3"
-
- dotest_fail basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd" \
-"Index: sdir/ssdir/ssfile
-===================================================================
-RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
-retrieving revision 1\.2
-retrieving revision 1\.3
-diff -C3isacrowd -r1\.2 -r1\.3
-${PROG} [a-z]*: invalid context length argument"
+ dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" ''
+ dotest basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd" \
+''
# The .* here will normally be "No such file or directory",
# but if memory serves some systems (AIX?) have a different message.
@@ -1805,8 +1966,8 @@ Annotations for sdir/ssdir/ssfile
# Test resurrecting with strange revision numbers
cd sdir/ssdir
dotest basica-r1 "${testcvs} rm -f ssfile" \
-"${PROG} [a-z]*: scheduling .ssfile. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .ssfile. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest basica-r2 "${testcvs} -q ci -m remove" \
"Removing ssfile;
${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
@@ -1814,8 +1975,8 @@ new revision: delete; previous revision: 3\.1
done"
dotest basica-r3 "${testcvs} -q up -p -r 3.1 ./ssfile >ssfile" ""
dotest basica-r4 "${testcvs} add ssfile" \
-"${PROG} [a-z]*: re-adding file ssfile (in place of dead revision 3\.2)
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: Re-adding file .ssfile. (in place of dead revision 3\.2)\.
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest basica-r5 "${testcvs} -q ci -m resurrect" \
"Checking in ssfile;
${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
@@ -1837,8 +1998,8 @@ done"
done"
dotest_fail basica-o2b "${testcvs} admin -o 1.1::NOT_EXIST ssfile" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v: Revision NOT_EXIST doesn't exist.
-${PROG} [a-z]*: RCS file for .ssfile. not modified\."
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v: Revision NOT_EXIST doesn't exist.
+${PROG} admin: RCS file for .ssfile. not modified\."
dotest basica-o3 "${testcvs} admin -o 1.2::1.3 ssfile" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
done"
@@ -1902,8 +2063,8 @@ add-it
dotest basicb-0a "${testcvs} -q co -l ." ''
touch topfile
dotest basicb-0b "${testcvs} add topfile" \
-"${PROG} [a-z]*: scheduling file .topfile. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .topfile. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest basicb-0c "${testcvs} -q ci -m add-it topfile" \
"RCS file: ${CVSROOT_DIRNAME}/topfile,v
done
@@ -1949,18 +2110,18 @@ Directory ${CVSROOT_DIRNAME}/first-dir/sdir2 added to the repository"
cd Emptydir
echo sfile1 starts >sfile1
dotest basicb-2a10 "${testcvs} -n add sfile1" \
-"${PROG} [a-z]*: scheduling file .sfile1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .sfile1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest basicb-2a11 "${testcvs} status sfile1" \
-"${PROG} [a-z]*: use .${PROG} add. to create an entry for sfile1
+"${PROG} status: use .${PROG} add. to create an entry for sfile1
===================================================================
File: sfile1 Status: Unknown
Working revision: No entry for sfile1
Repository revision: No revision control file"
dotest basicb-3 "${testcvs} add sfile1" \
-"${PROG} [a-z]*: scheduling file .sfile1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .sfile1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest basicb-3a1 "${testcvs} status sfile1" \
"===================================================================
File: sfile1 Status: Locally Added
@@ -1974,8 +2135,8 @@ File: sfile1 Status: Locally Added
cd ../sdir2
echo sfile2 starts >sfile2
dotest basicb-4 "${testcvs} add sfile2" \
-"${PROG} [a-z]*: scheduling file .sfile2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .sfile2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest basicb-4a "${testcvs} -q ci CVS" \
"${PROG} [a-z]*: warning: directory CVS specified in argument
${PROG} [a-z]*: but CVS uses CVS for its own purposes; skipping CVS directory"
@@ -2083,8 +2244,8 @@ U sub1/sub2/sdir2/sfile2"
cd second-dir
touch aa
dotest basicb-16 "${testcvs} add aa" \
-"${PROG} [a-z]*: scheduling file .aa. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .aa. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest basicb-17 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/second-dir/aa,v
done
@@ -2098,7 +2259,7 @@ done"
dotest_fail basicb-o1 "${testcvs} admin -o1.1 topfile" \
"RCS file: ${CVSROOT_DIRNAME}/topfile,v
deleting revision 1\.1
-${PROG} \[[a-z]* aborted\]: attempt to delete all revisions"
+${PROG} \[admin aborted\]: attempt to delete all revisions"
dotest basicb-o2 "${testcvs} -q update -d first-dir" \
"U first-dir/Emptydir/sfile1
U first-dir/sdir2/sfile2"
@@ -2107,7 +2268,7 @@ U first-dir/sdir2/sfile2"
"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v
deleting revision 1\.2
deleting revision 1\.1
-${PROG} \[[a-z]* aborted\]: attempt to delete all revisions"
+${PROG} \[admin aborted\]: attempt to delete all revisions"
cd ..
rm -r 1
@@ -2157,11 +2318,11 @@ Directory ${CVSROOT_DIRNAME}/second-dir added to the repository"
rm -rf CVS
dotest basicc-4 "echo *" "first-dir second-dir"
dotest basicc-5 "${testcvs} update" \
-"${PROG} [a-z]*: Updating first-dir
-${PROG} [a-z]*: Updating second-dir" \
-"${PROG} [a-z]*: Updating \.
-${PROG} [a-z]*: Updating first-dir
-${PROG} [a-z]*: Updating second-dir"
+"${PROG} update: Updating first-dir
+${PROG} update: Updating second-dir" \
+"${PROG} update: Updating \.
+${PROG} update: Updating first-dir
+${PROG} update: Updating second-dir"
cd first-dir
dotest basicc-6 "${testcvs} release -d" ""
@@ -2189,10 +2350,34 @@ ${PROG} [a-z]*: Updating second-dir"
mkdir 2; cd 2
dotest basicc-12 "${testcvs} -Q co ." ""
+ # actual entries can be in either Entries or Entries.log, do
+ # an update to get them consolidated into Entries
+ dotest basicc-12a "${testcvs} -Q up" ""
+ dotest basicc-12b "cat CVS/Entries" \
+"D/CVSROOT////
+D/first-dir////
+D/second-dir////"
dotest basicc-13 "echo *" "CVS CVSROOT first-dir second-dir"
dotest basicc-14 "${testcvs} -Q release first-dir second-dir" ""
+ # a normal release shouldn't affect the Entries file
+ dotest basicc-14b "cat CVS/Entries" \
+"D/CVSROOT////
+D/first-dir////
+D/second-dir////"
+ # FIXCVS: but release -d probably should
dotest basicc-15 "${testcvs} -Q release -d first-dir second-dir" ""
dotest basicc-16 "echo *" "CVS CVSROOT"
+ dotest basicc-17 "cat CVS/Entries" \
+"D/CVSROOT////
+D/first-dir////
+D/second-dir////"
+ # FIXCVS: if not, update should notice the missing directories
+ # and update Entries accordingly
+ dotest basicc-18 "${testcvs} -Q up" ""
+ dotest basicc-19 "cat CVS/Entries" \
+"D/CVSROOT////
+D/first-dir////
+D/second-dir////"
cd ..
rm -r 1 2
@@ -2213,11 +2398,11 @@ ${PROG} [a-z]*: Updating second-dir"
echo file5 >file5
dotest basic1-14-add-add "${testcvs} add file2 file3 file4 file5" \
-"${PROG} [a-z]*: scheduling file \`file2' for addition
-${PROG} [a-z]*: scheduling file \`file3' for addition
-${PROG} [a-z]*: scheduling file \`file4' for addition
-${PROG} [a-z]*: scheduling file \`file5' for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file \`file2' for addition
+${PROG} add: scheduling file \`file3' for addition
+${PROG} add: scheduling file \`file4' for addition
+${PROG} add: scheduling file \`file5' for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest basic1-15-add-add \
"${testcvs} -q update file2 file3 file4 file5" \
"A file2
@@ -2266,10 +2451,10 @@ File: file5 Status: Locally Added
Sticky Date: (none)
Sticky Options: (none)"
dotest basic1-18-add-add "${testcvs} -q log" \
-"${PROG} [a-z]*: file2 has been added, but not committed
-${PROG} [a-z]*: file3 has been added, but not committed
-${PROG} [a-z]*: file4 has been added, but not committed
-${PROG} [a-z]*: file5 has been added, but not committed"
+"${PROG} log: file2 has been added, but not committed
+${PROG} log: file3 has been added, but not committed
+${PROG} log: file4 has been added, but not committed
+${PROG} log: file5 has been added, but not committed"
cd ..
dotest basic1-21-add-add "${testcvs} -q update" \
"A first-dir/file2
@@ -2278,13 +2463,13 @@ A first-dir/file4
A first-dir/file5"
# FIXCVS? Shouldn't this read first-dir/file2 instead of file2?
dotest basic1-22-add-add "${testcvs} log first-dir" \
-"${PROG} [a-z]*: Logging first-dir
-${PROG} [a-z]*: file2 has been added, but not committed
-${PROG} [a-z]*: file3 has been added, but not committed
-${PROG} [a-z]*: file4 has been added, but not committed
-${PROG} [a-z]*: file5 has been added, but not committed"
+"${PROG} log: Logging first-dir
+${PROG} log: file2 has been added, but not committed
+${PROG} log: file3 has been added, but not committed
+${PROG} log: file4 has been added, but not committed
+${PROG} log: file5 has been added, but not committed"
dotest basic1-23-add-add "${testcvs} status first-dir" \
-"${PROG} [a-z]*: Examining first-dir
+"${PROG} status: Examining first-dir
===================================================================
File: file2 Status: Locally Added
@@ -2321,13 +2506,13 @@ File: file5 Status: Locally Added
Sticky Date: (none)
Sticky Options: (none)"
dotest basic1-24-add-add "${testcvs} update first-dir" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} update: Updating first-dir
A first-dir/file2
A first-dir/file3
A first-dir/file4
A first-dir/file5"
dotest basic1-27-add-add "${testcvs} co first-dir" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} checkout: Updating first-dir
A first-dir/file2
A first-dir/file3
A first-dir/file4
@@ -2430,11 +2615,11 @@ File: file5 Status: Up-to-date
cd first-dir
rm file2 file3 file4 file5
dotest basic1-14-rm-rm "${testcvs} rm file2 file3 file4 file5" \
-"${PROG} [a-z]*: scheduling .file2. for removal
-${PROG} [a-z]*: scheduling .file3. for removal
-${PROG} [a-z]*: scheduling .file4. for removal
-${PROG} [a-z]*: scheduling .file5. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove these files permanently"
+"${PROG} remove: scheduling .file2. for removal
+${PROG} remove: scheduling .file3. for removal
+${PROG} remove: scheduling .file4. for removal
+${PROG} remove: scheduling .file5. for removal
+${PROG} remove: use .${PROG} commit. to remove these files permanently"
# 15-rm-rm was commented out. Why?
dotest basic1-15-rm-rm \
"${testcvs} -q update file2 file3 file4 file5" \
@@ -2586,8 +2771,8 @@ done"
cd $i
echo file1 >file1
dotest deep-3-$i "${testcvs} add file1" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file1'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
done
cd ../../../../../../../../..
dotest_lit deep-4 "${testcvs} -q ci -m add-them first-dir" <<HERE
@@ -2644,8 +2829,8 @@ HERE
cd first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8
rm file1
dotest deep-4a0 "${testcvs} rm file1" \
-"${PROG} [a-z]*: scheduling .file1. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file1. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest deep-4a1 "${testcvs} -q ci -m rm-it" "Removing file1;
${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1,v <-- file1
new revision: delete; previous revision: 1\.1
@@ -2674,8 +2859,8 @@ U dir6/dir7/file1'
# but not committed.
cd dir6/dir7
dotest deep-rm1 "${testcvs} rm -f file1" \
-"${PROG} [a-z]*: scheduling .file1. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file1. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
cd ..
dotest deep-rm2 "${testcvs} -q update -d -P" 'R dir7/file1'
dotest deep-rm3 "test -d dir7" ''
@@ -2689,11 +2874,11 @@ done"
# Test rm -f -R.
cd ../..
dotest deep-rm7 "${testcvs} rm -f -R dir5" \
-"${PROG} [a-z]*: Removing dir5
-${PROG} [a-z]*: scheduling .dir5/file1. for removal
-${PROG} [a-z]*: Removing dir5/dir6
-${PROG} [a-z]*: scheduling .dir5/dir6/file1. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove these files permanently"
+"${PROG} remove: Removing dir5
+${PROG} remove: scheduling .dir5/file1. for removal
+${PROG} remove: Removing dir5/dir6
+${PROG} remove: scheduling .dir5/dir6/file1. for removal
+${PROG} remove: use .${PROG} commit. to remove these files permanently"
dotest deep-rm8 "${testcvs} -q ci -m rm-it" \
"Removing dir5/file1;
${CVSROOT_DIRNAME}/first-dir/dir1/dir2/dir3/dir4/dir5/file1,v <-- file1
@@ -2746,37 +2931,37 @@ done"
done
dotest basic2-3-$i "${testcvs} add file6 file7" \
-"${PROG} [a-z]*: scheduling file .file6. for addition
-${PROG} [a-z]*: scheduling file .file7. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .file6. for addition
+${PROG} add: scheduling file .file7. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
done
cd ../../..
dotest basic2-4 "${testcvs} update first-dir" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} update: Updating first-dir
A first-dir/file6
A first-dir/file7
-${PROG} [a-z]*: Updating first-dir/dir1
+${PROG} update: Updating first-dir/dir1
A first-dir/dir1/file6
A first-dir/dir1/file7
-${PROG} [a-z]*: Updating first-dir/dir1/dir2
+${PROG} update: Updating first-dir/dir1/dir2
A first-dir/dir1/dir2/file6
A first-dir/dir1/dir2/file7"
# fixme: doesn't work right for added files.
dotest basic2-5 "${testcvs} log first-dir" \
-"${PROG} [a-z]*: Logging first-dir
-${PROG} [a-z]*: file6 has been added, but not committed
-${PROG} [a-z]*: file7 has been added, but not committed
-${PROG} [a-z]*: Logging first-dir/dir1
-${PROG} [a-z]*: file6 has been added, but not committed
-${PROG} [a-z]*: file7 has been added, but not committed
-${PROG} [a-z]*: Logging first-dir/dir1/dir2
-${PROG} [a-z]*: file6 has been added, but not committed
-${PROG} [a-z]*: file7 has been added, but not committed"
+"${PROG} log: Logging first-dir
+${PROG} log: file6 has been added, but not committed
+${PROG} log: file7 has been added, but not committed
+${PROG} log: Logging first-dir/dir1
+${PROG} log: file6 has been added, but not committed
+${PROG} log: file7 has been added, but not committed
+${PROG} log: Logging first-dir/dir1/dir2
+${PROG} log: file6 has been added, but not committed
+${PROG} log: file7 has been added, but not committed"
dotest basic2-6 "${testcvs} status first-dir" \
-"${PROG} [a-z]*: Examining first-dir
+"${PROG} status: Examining first-dir
===================================================================
File: file6 Status: Locally Added
@@ -2795,7 +2980,7 @@ File: file7 Status: Locally Added
Sticky Date: (none)
Sticky Options: (none)
-${PROG} [a-z]*: Examining first-dir/dir1
+${PROG} status: Examining first-dir/dir1
===================================================================
File: file6 Status: Locally Added
@@ -2814,7 +2999,7 @@ File: file7 Status: Locally Added
Sticky Date: (none)
Sticky Options: (none)
-${PROG} [a-z]*: Examining first-dir/dir1/dir2
+${PROG} status: Examining first-dir/dir1/dir2
===================================================================
File: file6 Status: Locally Added
@@ -2879,13 +3064,13 @@ initial revision: 1\.1
done"
dotest basic2-9 "${testcvs} tag second-dive first-dir" \
-"${PROG} [a-z]*: Tagging first-dir
+"${PROG} tag: Tagging first-dir
T first-dir/file6
T first-dir/file7
-${PROG} [a-z]*: Tagging first-dir/dir1
+${PROG} tag: Tagging first-dir/dir1
T first-dir/dir1/file6
T first-dir/dir1/file7
-${PROG} [a-z]*: Tagging first-dir/dir1/dir2
+${PROG} tag: Tagging first-dir/dir1/dir2
T first-dir/dir1/dir2/file6
T first-dir/dir1/dir2/file7"
@@ -2902,36 +3087,36 @@ T first-dir/dir1/dir2/file7"
rm file7
dotest basic2-10-$i "${testcvs} rm file7" \
-"${PROG} [a-z]*: scheduling .file7. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file7. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
# and add a new file
echo file14 >file14
dotest basic2-11-$i "${testcvs} add file14" \
-"${PROG} [a-z]*: scheduling file .file14. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file14. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
done
cd ../../..
dotest basic2-12 "${testcvs} update first-dir" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} update: Updating first-dir
A first-dir/file14
M first-dir/file6
R first-dir/file7
-${PROG} [a-z]*: Updating first-dir/dir1
+${PROG} update: Updating first-dir/dir1
A first-dir/dir1/file14
M first-dir/dir1/file6
R first-dir/dir1/file7
-${PROG} [a-z]*: Updating first-dir/dir1/dir2
+${PROG} update: Updating first-dir/dir1/dir2
A first-dir/dir1/dir2/file14
M first-dir/dir1/dir2/file6
R first-dir/dir1/dir2/file7"
# FIXME: doesn't work right for added files
dotest basic2-13 "${testcvs} log first-dir" \
-"${PROG} [a-z]*: Logging first-dir
-${PROG} [a-z]*: file14 has been added, but not committed
+"${PROG} log: Logging first-dir
+${PROG} log: file14 has been added, but not committed
RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v
Working file: first-dir/file6
@@ -2966,8 +3151,8 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
second dive
=============================================================================
-${PROG} [a-z]*: Logging first-dir/dir1
-${PROG} [a-z]*: file14 has been added, but not committed
+${PROG} log: Logging first-dir/dir1
+${PROG} log: file14 has been added, but not committed
RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v
Working file: first-dir/dir1/file6
@@ -3002,8 +3187,8 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
second dive
=============================================================================
-${PROG} [a-z]*: Logging first-dir/dir1/dir2
-${PROG} [a-z]*: file14 has been added, but not committed
+${PROG} log: Logging first-dir/dir1/dir2
+${PROG} log: file14 has been added, but not committed
RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v
Working file: first-dir/dir1/dir2/file6
@@ -3040,7 +3225,7 @@ second dive
============================================================================="
dotest basic2-14 "${testcvs} status first-dir" \
-"${PROG} [a-z]*: Examining first-dir
+"${PROG} status: Examining first-dir
===================================================================
File: file14 Status: Locally Added
@@ -3068,7 +3253,7 @@ File: no file file7 Status: Locally Removed
Sticky Date: (none)
Sticky Options: (none)
-${PROG} [a-z]*: Examining first-dir/dir1
+${PROG} status: Examining first-dir/dir1
===================================================================
File: file14 Status: Locally Added
@@ -3096,7 +3281,7 @@ File: no file file7 Status: Locally Removed
Sticky Date: (none)
Sticky Options: (none)
-${PROG} [a-z]*: Examining first-dir/dir1/dir2
+${PROG} status: Examining first-dir/dir1/dir2
===================================================================
File: file14 Status: Locally Added
@@ -3180,13 +3365,13 @@ done"
dotest basic2-17 "${testcvs} -q update first-dir" ''
dotest basic2-18 "${testcvs} tag third-dive first-dir" \
-"${PROG} [a-z]*: Tagging first-dir
+"${PROG} tag: Tagging first-dir
T first-dir/file14
T first-dir/file6
-${PROG} [a-z]*: Tagging first-dir/dir1
+${PROG} tag: Tagging first-dir/dir1
T first-dir/dir1/file14
T first-dir/dir1/file6
-${PROG} [a-z]*: Tagging first-dir/dir1/dir2
+${PROG} tag: Tagging first-dir/dir1/dir2
T first-dir/dir1/dir2/file14
T first-dir/dir1/dir2/file6"
@@ -3201,29 +3386,29 @@ Are you sure you want to release (and delete) directory .first-dir.: "
# rtag HEADS
dotest basic2-21 "${testcvs} rtag rtagged-by-head first-dir" \
-"${PROG} [a-z]*: Tagging first-dir
-${PROG} [a-z]*: Tagging first-dir/dir1
-${PROG} [a-z]*: Tagging first-dir/dir1/dir2"
+"${PROG} rtag: Tagging first-dir
+${PROG} rtag: Tagging first-dir/dir1
+${PROG} rtag: Tagging first-dir/dir1/dir2"
# tag by tag
dotest basic2-22 "${testcvs} rtag -r rtagged-by-head rtagged-by-tag first-dir" \
-"${PROG} [a-z]*: Tagging first-dir
-${PROG} [a-z]*: Tagging first-dir/dir1
-${PROG} [a-z]*: Tagging first-dir/dir1/dir2"
+"${PROG} rtag: Tagging first-dir
+${PROG} rtag: Tagging first-dir/dir1
+${PROG} rtag: Tagging first-dir/dir1/dir2"
# tag by revision
dotest basic2-23 "${testcvs} rtag -r1.1 rtagged-by-revision first-dir" \
-"${PROG} [a-z]*: Tagging first-dir
-${PROG} [a-z]*: Tagging first-dir/dir1
-${PROG} [a-z]*: Tagging first-dir/dir1/dir2"
+"${PROG} rtag: Tagging first-dir
+${PROG} rtag: Tagging first-dir/dir1
+${PROG} rtag: Tagging first-dir/dir1/dir2"
# rdiff by revision
dotest basic2-24 "${testcvs} rdiff -r1.1 -rrtagged-by-head first-dir" \
-"${PROG} [a-z]*: Diffing first-dir
+"${PROG} rdiff: Diffing first-dir
Index: first-dir/file6
diff -c first-dir/file6:1\.1 first-dir/file6:1\.2
-\*\*\* first-dir/file6:1\.1 .*
---- first-dir/file6 .*
+\*\*\* first-dir/file6:1\.1 ${DATE}
+--- first-dir/file6 ${DATE}
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1 \*\*\*\*
--- 1,2 ----
@@ -3231,17 +3416,17 @@ diff -c first-dir/file6:1\.1 first-dir/file6:1\.2
${PLUS} file6
Index: first-dir/file7
diff -c first-dir/file7:1\.1 first-dir/file7:removed
-\*\*\* first-dir/file7:1.1 .*
---- first-dir/file7 .*
+\*\*\* first-dir/file7:1.1 ${DATE}
+--- first-dir/file7 ${DATE}
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1 \*\*\*\*
- file7
--- 0 ----
-${PROG} [a-z]*: Diffing first-dir/dir1
+${PROG} rdiff: Diffing first-dir/dir1
Index: first-dir/dir1/file6
diff -c first-dir/dir1/file6:1\.1 first-dir/dir1/file6:1\.2
-\*\*\* first-dir/dir1/file6:1\.1 .*
---- first-dir/dir1/file6 .*
+\*\*\* first-dir/dir1/file6:1\.1 ${DATE}
+--- first-dir/dir1/file6 ${DATE}
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1 \*\*\*\*
--- 1,2 ----
@@ -3249,17 +3434,17 @@ diff -c first-dir/dir1/file6:1\.1 first-dir/dir1/file6:1\.2
${PLUS} file6
Index: first-dir/dir1/file7
diff -c first-dir/dir1/file7:1\.1 first-dir/dir1/file7:removed
-\*\*\* first-dir/dir1/file7:1\.1 .*
---- first-dir/dir1/file7 .*
+\*\*\* first-dir/dir1/file7:1\.1 ${DATE}
+--- first-dir/dir1/file7 ${DATE}
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1 \*\*\*\*
- file7
--- 0 ----
-${PROG} [a-z]*: Diffing first-dir/dir1/dir2
+${PROG} rdiff: Diffing first-dir/dir1/dir2
Index: first-dir/dir1/dir2/file6
diff -c first-dir/dir1/dir2/file6:1\.1 first-dir/dir1/dir2/file6:1\.2
-\*\*\* first-dir/dir1/dir2/file6:1\.1 .*
---- first-dir/dir1/dir2/file6 .*
+\*\*\* first-dir/dir1/dir2/file6:1\.1 ${DATE}
+--- first-dir/dir1/dir2/file6 ${DATE}
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1 \*\*\*\*
--- 1,2 ----
@@ -3267,21 +3452,40 @@ diff -c first-dir/dir1/dir2/file6:1\.1 first-dir/dir1/dir2/file6:1\.2
${PLUS} file6
Index: first-dir/dir1/dir2/file7
diff -c first-dir/dir1/dir2/file7:1\.1 first-dir/dir1/dir2/file7:removed
-\*\*\* first-dir/dir1/dir2/file7:1\.1 .*
---- first-dir/dir1/dir2/file7 .*
+\*\*\* first-dir/dir1/dir2/file7:1\.1 ${DATE}
+--- first-dir/dir1/dir2/file7 ${DATE}
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
+\*\*\* 1 \*\*\*\*
+- file7
+--- 0 ----"
+ dotest basic2-24a "${testcvs} rdiff -l -r1.1 -rrtagged-by-head first-dir" \
+"${PROG} rdiff: Diffing first-dir
+Index: first-dir/file6
+diff -c first-dir/file6:1\.1 first-dir/file6:1\.2
+\*\*\* first-dir/file6:1\.1 ${DATE}
+--- first-dir/file6 ${DATE}
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
+\*\*\* 1 \*\*\*\*
+--- 1,2 ----
+ file6
+${PLUS} file6
+Index: first-dir/file7
+diff -c first-dir/file7:1\.1 first-dir/file7:removed
+\*\*\* first-dir/file7:1.1 ${DATE}
+--- first-dir/file7 ${DATE}
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1 \*\*\*\*
- file7
--- 0 ----"
# now export by rtagged-by-head and rtagged-by-tag and compare.
dotest basic2-25 "${testcvs} export -r rtagged-by-head -d 1dir first-dir" \
-"${PROG} [a-z]*: Updating 1dir
+"${PROG} export: Updating 1dir
U 1dir/file14
U 1dir/file6
-${PROG} [a-z]*: Updating 1dir/dir1
+${PROG} export: Updating 1dir/dir1
U 1dir/dir1/file14
U 1dir/dir1/file6
-${PROG} [a-z]*: Updating 1dir/dir1/dir2
+${PROG} export: Updating 1dir/dir1/dir2
U 1dir/dir1/dir2/file14
U 1dir/dir1/dir2/file6"
dotest_fail basic2-25a "test -d 1dir/CVS"
@@ -3289,13 +3493,13 @@ U 1dir/dir1/dir2/file6"
dotest_fail basic2-25c "test -d 1dir/dir1/dir2/CVS"
dotest basic2-26 "${testcvs} export -r rtagged-by-tag first-dir" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} export: Updating first-dir
U first-dir/file14
U first-dir/file6
-${PROG} [a-z]*: Updating first-dir/dir1
+${PROG} export: Updating first-dir/dir1
U first-dir/dir1/file14
U first-dir/dir1/file6
-${PROG} [a-z]*: Updating first-dir/dir1/dir2
+${PROG} export: Updating first-dir/dir1/dir2
U first-dir/dir1/dir2/file14
U first-dir/dir1/dir2/file6"
dotest_fail basic2-26a "test -d first-dir/CVS"
@@ -3308,15 +3512,15 @@ U first-dir/dir1/dir2/file6"
# checkout by revision vs export by rtagged-by-revision and compare.
mkdir export-dir
dotest basic2-28 "${testcvs} export -rrtagged-by-revision -d export-dir first-dir" \
-"${PROG} [a-z]*: Updating export-dir
+"${PROG} export: Updating export-dir
U export-dir/file14
U export-dir/file6
U export-dir/file7
-${PROG} [a-z]*: Updating export-dir/dir1
+${PROG} export: Updating export-dir/dir1
U export-dir/dir1/file14
U export-dir/dir1/file6
U export-dir/dir1/file7
-${PROG} [a-z]*: Updating export-dir/dir1/dir2
+${PROG} export: Updating export-dir/dir1/dir2
U export-dir/dir1/dir2/file14
U export-dir/dir1/dir2/file6
U export-dir/dir1/dir2/file7"
@@ -3325,15 +3529,15 @@ U export-dir/dir1/dir2/file7"
dotest_fail basic2-28c "test -d export-dir/dir1/dir2/CVS"
dotest basic2-29 "${testcvs} co -r1.1 first-dir" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} checkout: Updating first-dir
U first-dir/file14
U first-dir/file6
U first-dir/file7
-${PROG} [a-z]*: Updating first-dir/dir1
+${PROG} checkout: Updating first-dir/dir1
U first-dir/dir1/file14
U first-dir/dir1/file6
U first-dir/dir1/file7
-${PROG} [a-z]*: Updating first-dir/dir1/dir2
+${PROG} checkout: Updating first-dir/dir1/dir2
U first-dir/dir1/dir2/file14
U first-dir/dir1/dir2/file6
U first-dir/dir1/dir2/file7"
@@ -3359,20 +3563,20 @@ N second-dir/file14
N second-dir/file6
N second-dir/file7
No conflicts created by this import
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/second-dir/dir1
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/second-dir/dir1/dir2"
+${PROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/dir1
+${PROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/dir1/dir2"
cd ..
dotest basic2-32 "${testcvs} export -r HEAD second-dir" \
-"${PROG} [a-z]*: Updating second-dir
+"${PROG} export: Updating second-dir
U second-dir/file14
U second-dir/file6
U second-dir/file7
-${PROG} [a-z]*: Updating second-dir/dir1
+${PROG} export: Updating second-dir/dir1
U second-dir/dir1/file14
U second-dir/dir1/file6
U second-dir/dir1/file7
-${PROG} [a-z]*: Updating second-dir/dir1/dir2
+${PROG} export: Updating second-dir/dir1/dir2
U second-dir/dir1/dir2/file14
U second-dir/dir1/dir2/file6
U second-dir/dir1/dir2/file7"
@@ -3389,16 +3593,16 @@ U second-dir/dir1/dir2/file7"
cd first-dir
dotest basic2-34 "${testcvs} update -A -l *file*" \
"[UP] file6
-${PROG} [a-z]*: file7 is no longer in the repository"
+${PROG} update: file7 is no longer in the repository"
# If we don't delete the tag first, cvs won't retag it.
# This would appear to be a feature.
dotest basic2-35 "${testcvs} tag -l -d rtagged-by-revision" \
-"${PROG} [a-z]*: Untagging \.
+"${PROG} tag: Untagging \.
D file14
D file6"
dotest basic2-36 "${testcvs} tag -l rtagged-by-revision" \
-"${PROG} [a-z]*: Tagging \.
+"${PROG} tag: Tagging \.
T file14
T file6"
@@ -3410,9 +3614,9 @@ T file6"
dotest basic2-37 "${testcvs} -q diff -u" ''
dotest basic2-38 "${testcvs} update" \
-"${PROG} [a-z]*: Updating .
-${PROG} [a-z]*: Updating dir1
-${PROG} [a-z]*: Updating dir1/dir2"
+"${PROG} update: Updating .
+${PROG} update: Updating dir1
+${PROG} update: Updating dir1/dir2"
cd ..
@@ -3433,7 +3637,7 @@ ${PROG} [a-z]*: Updating dir1/dir2"
# why are there two lines at the end of the local output
# which don't exist in the remote output? would seem to be
# a CVS bug.
- dotest basic2-64 "${testcvs} his -x TOFWUCGMAR -a" \
+ dotest basic2-64 "${testcvs} his -x TOFWUPCGMAR -a" \
"O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= ${TESTDIR}/\*
A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == ${TESTDIR}
A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == ${TESTDIR}
@@ -3478,12 +3682,52 @@ T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\]
T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\]
T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\]
O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= <remote>/\*
-W [0-9-]* [0-9:]* ${PLUS}0000 ${username} file7 first-dir == <remote>" \
+P [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == <remote>
+W [0-9-]* [0-9:]* ${PLUS}0000 ${username} file7 first-dir == <remote>"
rm -rf ${CVSROOT_DIRNAME}/first-dir
rm -rf ${CVSROOT_DIRNAME}/second-dir
;;
+ parseroot)
+ mkdir 1; cd 1
+ # Test odd cases involving CVSROOT. At the moment, that means we
+ # are testing roots with '/'s on the end, which CVS should parse off.
+ CVSROOT_save=${CVSROOT}
+ CVSROOT="${CVSROOT}/////"
+ dotest parseroot-1 "${testcvs} -q co CVSROOT/modules" \
+"U CVSROOT/modules"
+ dotest parseroot-2 "${testcvs} -q ci -fmnull-change CVSROOT/modules" \
+"Checking in CVSROOT/modules;
+${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
+new revision: 1\.2; previous revision: 1\.1
+done
+${PROG} commit: Rebuilding administrative file database"
+
+ if $remote; then
+ # I only test these when testing remote in case CVS was compiled
+ # without client support.
+
+ # logout does not try to contact the server.
+ CVSROOT=":pserver;proxy=localhost;proxyport=8080:localhost/dev/null"
+ dotest parseroot-3r "$testcvs -d'$CVSROOT' logout" \
+"$PROG logout: WARNING: Ignoring method options found in CVSROOT: \`proxy=localhost;proxyport=8080'\.
+$PROG logout: Use CVS version 1\.12\.7 or later to handle method options\.
+Logging out of :pserver:$username@localhost:2401/dev/null
+$PROG logout: warning: failed to open $HOME/\.cvspass for reading: No such file or directory
+$PROG logout: Entry not found\."
+ fi
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ CVSROOT=$CVSROOT_save
+ cd ..
+ rm -r 1
+ ;;
+
files)
# Test of how we specify files on the command line
# (recurse.c and that sort of thing). Vaguely similar to
@@ -3500,8 +3744,8 @@ W [0-9-]* [0-9:]* ${PLUS}0000 ${username} file7 first-dir == <
cd first-dir
touch tfile
dotest files-3 "${testcvs} add tfile" \
-"${PROG} [a-z]*: scheduling file .tfile. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .tfile. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest files-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v
done
@@ -3518,8 +3762,8 @@ done"
cd dir
touch .file
dotest files-6 "${testcvs} add .file" \
-"${PROG} [a-z]*: scheduling file .\.file' for addition on branch .C.
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .\.file' for addition on branch .C.
+${PROG} add: use .${PROG} commit. to add this file permanently"
mkdir sdir
dotest files-7 "${testcvs} add sdir" \
"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir added to the repository
@@ -3532,8 +3776,8 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
cd ssdir
touch .file
dotest files-9 "${testcvs} add .file" \
-"${PROG} [a-z]*: scheduling file .\.file' for addition on branch .C.
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .\.file' for addition on branch .C.
+${PROG} add: use .${PROG} commit. to add this file permanently"
cd ../..
dotest files-10 "${testcvs} -q ci -m test" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v
@@ -3566,8 +3810,8 @@ done"
# might be a mistake.
dotest_fail files-12 \
"${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \
-"${PROG} server: Up-to-date check failed for .\.file'
-${PROG} \[server aborted\]: correct above errors first!"
+"${PROG} commit: Up-to-date check failed for .\.file'
+${PROG} \[commit aborted\]: correct above errors first!"
# Sync up the version numbers so that the rest of the
# tests don't need to expect different numbers based
@@ -3601,9 +3845,12 @@ ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file
new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3
done"
if $remote; then
- dotest_fail files-14 \
+ dotest files-14 \
"${testcvs} commit -fmtest ../../first-dir/dir/.file" \
-"protocol error: .\.\./\.\./first-dir/dir' has too many \.\."
+"Checking in \.\./\.\./first-dir/dir/\.file;
+${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- .file
+new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3
+done"
else
dotest files-14 \
"${testcvs} commit -fmtest ../../first-dir/dir/.file" \
@@ -3624,48 +3871,30 @@ done"
# basica or some other test instead, always good to keep the
# testsuite concise).
- # I wrote this test to worry about problems in do_module;
- # but then I found that the CVS server has its own problems
- # with filenames starting with "-". Work around it for now.
- if $remote; then
- dashb=dashb
- dashc=dashc
- else
- dashb=-b
- dashc=-c
- fi
-
mkdir 1; cd 1
dotest spacefiles-1 "${testcvs} -q co -l ." ""
- touch ./${dashc} top
- dotest spacefiles-2 "${testcvs} add -- ${dashc} top" \
-"${PROG} [a-z]*: scheduling file .${dashc}. for addition
-${PROG} [a-z]*: scheduling file .top. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+ touch ./-c
+ dotest spacefiles-2 "${testcvs} add -- -c" \
+"${PROG} add: scheduling file .-c. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest spacefiles-3 "${testcvs} -q ci -m add" \
-"RCS file: ${CVSROOT_DIRNAME}/${dashc},v
+"RCS file: ${CVSROOT_DIRNAME}/-c,v
done
-Checking in ${dashc};
-${CVSROOT_DIRNAME}/${dashc},v <-- ${dashc}
-initial revision: 1\.1
-done
-RCS file: ${CVSROOT_DIRNAME}/top,v
-done
-Checking in top;
-${CVSROOT_DIRNAME}/top,v <-- top
+Checking in -c;
+${CVSROOT_DIRNAME}/-c,v <-- -c
initial revision: 1\.1
done"
mkdir 'first dir'
dotest spacefiles-4 "${testcvs} add 'first dir'" \
"Directory ${CVSROOT_DIRNAME}/first dir added to the repository"
- mkdir ./${dashb}
- dotest spacefiles-5 "${testcvs} add -- ${dashb}" \
-"Directory ${CVSROOT_DIRNAME}/${dashb} added to the repository"
+ mkdir ./-b
+ dotest spacefiles-5 "${testcvs} add -- -b" \
+"Directory ${CVSROOT_DIRNAME}/-b added to the repository"
cd 'first dir'
touch 'a file'
dotest spacefiles-6 "${testcvs} add 'a file'" \
-"${PROG} [a-z]*: scheduling file .a file. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .a file. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest spacefiles-7 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first dir/a file,v
done
@@ -3677,16 +3906,10 @@ done"
cd ../..
mkdir 2; cd 2
- # Leading slash strikes me as kind of oddball, but there is
- # a special case for it in do_module. And (in the case of
- # "top", rather than "-c") it has worked in CVS 1.10.6 and
- # presumably back to CVS 1.3 or so.
- dotest spacefiles-9 "${testcvs} -q co -- /top" "U \./top"
- dotest spacefiles-10 "${testcvs} co -- ${dashb}" \
-"${PROG} [a-z]*: Updating ${dashb}"
- dotest spacefiles-11 "${testcvs} -q co -- ${dashc}" "U \./${dashc}"
- rm ./${dashc}
- dotest spacefiles-12 "${testcvs} -q co -- /${dashc}" "U \./${dashc}"
+ dotest spacefiles-10 "${testcvs} co -- -b" \
+"${PROG} checkout: Updating -b"
+ dotest spacefiles-11 "${testcvs} -q co -- -c" "U \./-c"
+ rm ./-c
dotest spacefiles-13 "${testcvs} -q co 'first dir'" \
"U first dir/a file"
cd ..
@@ -3698,8 +3921,8 @@ done"
rm -r 1 2 3
rm -rf "${CVSROOT_DIRNAME}/first dir"
- rm -r ${CVSROOT_DIRNAME}/${dashb}
- rm -f ${CVSROOT_DIRNAME}/${dashc},v ${CVSROOT_DIRNAME}/top,v
+ rm -r ${CVSROOT_DIRNAME}/-b
+ rm -f ${CVSROOT_DIRNAME}/-c,v
;;
commit-readonly)
@@ -3717,8 +3940,8 @@ done"
echo '$Id''$' > $file
dotest commit-readonly-3 "$testcvs add $file" \
-"${PROG} [a-z]*: scheduling file .$file. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .$file. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest commit-readonly-4 "$testcvs -Q ci -m . $file" \
"RCS file: ${CVSROOT_DIRNAME}/$module/$file,v
done
@@ -3742,6 +3965,149 @@ done"
rm -rf ${CVSROOT_DIRNAME}/$module
;;
+ status)
+ # This tests for a bug in the status command which failed to
+ # notice resolved conflicts.
+ mkdir status; cd status
+ dotest status-init-1 "${testcvs} -q co -l ." ""
+ mkdir first-dir
+ dotest status-init-2 "${testcvs} add first-dir" \
+"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
+ cd first-dir
+ echo a line >tfile
+ dotest status-init-3 "${testcvs} add tfile" \
+"${PROG} add: scheduling file .tfile. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
+ dotest status-init-4 "${testcvs} -q ci -m add" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v
+done
+Checking in tfile;
+${CVSROOT_DIRNAME}/first-dir/tfile,v <-- tfile
+initial revision: 1\.1
+done"
+ cd ..
+ dotest status-init-5 "${testcvs} -q co -dsecond-dir first-dir" \
+"U second-dir/tfile"
+ cd second-dir
+ echo some junk >>tfile
+ dotest status-init-6 "${testcvs} -q ci -maline" \
+"Checking in tfile;
+${CVSROOT_DIRNAME}/first-dir/tfile,v <-- tfile
+new revision: 1\.2; previous revision: 1\.1
+done"
+ cd ../first-dir
+ echo force a conflict >>tfile
+ dotest status-init-7 "${testcvs} -q up" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v
+retrieving revision 1\.1
+retrieving revision 1\.2
+Merging differences between 1\.1 and 1\.2 into tfile
+rcsmerge: warning: conflicts during merge
+${PROG} update: conflicts found in tfile
+C tfile"
+
+ # Now note our status
+ dotest status-1 "${testcvs} status tfile" \
+"===================================================================
+File: tfile Status: File had conflicts on merge
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+
+ # touch the file, leaving conflict markers in place
+ # and note our status
+ touch tfile
+ dotest status-2 "${testcvs} status tfile" \
+"===================================================================
+File: tfile Status: File had conflicts on merge
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+
+ # resolve the conflict
+ echo resolution >tfile
+ dotest status-3 "${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)"
+
+ # FIXCVS:
+ # Update is supposed to re-Register() the file when it
+ # finds resolved conflicts:
+ dotest status-4 "grep 'Result of merge' CVS/Entries" \
+"/tfile/1\.2/Result of merge${PLUS}[a-zA-Z0-9 :]*//"
+
+ cd ..
+ mkdir fourth-dir
+ dotest status-init-8 "$testcvs add fourth-dir" \
+"Directory $CVSROOT_DIRNAME/fourth-dir added to the repository"
+ cd fourth-dir
+ echo yet another line >t3file
+ dotest status-init-9 "$testcvs add t3file" \
+"$PROG add: scheduling file .t3file. for addition
+$PROG add: use .$PROG commit. to add this file permanently"
+ dotest status-init-10 "$testcvs -q ci -m add" \
+"RCS file: $CVSROOT_DIRNAME/fourth-dir/t3file,v
+done
+Checking in t3file;
+$CVSROOT_DIRNAME/fourth-dir/t3file,v <-- t3file
+initial revision: 1\.1
+done"
+ cd ../first-dir
+ mkdir third-dir
+ dotest status-init-11 "$testcvs add third-dir" \
+"Directory $CVSROOT_DIRNAME/first-dir/third-dir added to the repository"
+ cd third-dir
+ echo another line >t2file
+ dotest status-init-12 "$testcvs add t2file" \
+"$PROG add: scheduling file .t2file. for addition
+$PROG add: use .$PROG commit. to add this file permanently"
+ dotest status-init-13 "$testcvs -q ci -m add" \
+"RCS file: $CVSROOT_DIRNAME/first-dir/third-dir/t2file,v
+done
+Checking in t2file;
+$CVSROOT_DIRNAME/first-dir/third-dir/t2file,v <-- t2file
+initial revision: 1\.1
+done"
+ dotest status-5 "$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)"
+ dotest status-6 "$testcvs status ../../fourth-dir/t3file" \
+"===================================================================
+File: t3file Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 $CVSROOT_DIRNAME/fourth-dir/t3file,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../../..
+ rm -rf status
+ rm -rf $CVSROOT_DIRNAME/first-dir $CVSROOT_DIRNAME/fourth-dir
+ ;;
rdiff)
# Test rdiff
@@ -3763,7 +4129,7 @@ N trdiff/foo
No conflicts created by this import'
dotest rdiff-2 \
"${testcvs} co -ko trdiff" \
-"${PROG} [a-z]*: Updating trdiff
+"${PROG} checkout: Updating trdiff
U trdiff/bar
U trdiff/foo"
cd trdiff
@@ -3778,8 +4144,8 @@ done"
echo "new file" >> new
dotest rdiff-4 \
"${testcvs} add -m new-file-description new" \
-"${PROG} [a-z]*: scheduling file \`new' for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file \`new' for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest rdiff-5 \
"${testcvs} commit -m added-new-file new" \
"RCS file: ${CVSROOT_DIRNAME}/trdiff/new,v
@@ -3790,7 +4156,7 @@ initial revision: 1\.1
done"
dotest rdiff-6 \
"${testcvs} tag local-v0" \
-"${PROG} [a-z]*: Tagging .
+"${PROG} tag: Tagging .
T bar
T foo
T new"
@@ -3815,11 +4181,11 @@ File: foo Status: Up-to-date
dotest rdiff-8 \
"${testcvs} rdiff -r T1 -r local-v0 trdiff" \
-"${PROG}"' [a-z]*: Diffing trdiff
+"${PROG}"' rdiff: Diffing trdiff
Index: trdiff/foo
diff -c trdiff/foo:1\.1\.1\.1 trdiff/foo:1\.2
-\*\*\* trdiff/foo:1\.1\.1\.1 .*
---- trdiff/foo .*
+\*\*\* trdiff/foo:1\.1\.1\.1 '"${DATE}"'
+--- trdiff/foo '"${DATE}"'
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1,2 \*\*\*\*
! \$''Id: foo,v 1\.1\.1\.1 [0-9/]* [0-9:]* '"${username}"' Exp \$
@@ -3830,8 +4196,8 @@ diff -c trdiff/foo:1\.1\.1\.1 trdiff/foo:1\.2
! something
Index: trdiff/new
diff -c /dev/null trdiff/new:1\.1
-\*\*\* /dev/null .*
---- trdiff/new .*
+\*\*\* /dev/null '"${DATE}"'
+--- trdiff/new '"${DATE}"'
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 0 \*\*\*\*
--- 1,2 ----
@@ -3848,6 +4214,182 @@ diff -c /dev/null trdiff/new:1\.1
rm -rf ${CVSROOT_DIRNAME}/trdiff
;;
+ rdiff-short)
+ # Test that the short patch behaves as expected
+ # 1) Added file.
+ # 2) Removed file.
+ # 3) Different revision number with no difference.
+ # 4) Different revision number with changes.
+ # 5) Against trunk.
+ # 6) Same revision number (no difference).
+ mkdir rdiff-short; cd rdiff-short
+ mkdir abc
+ dotest rdiff-short-init-1 \
+"${testcvs} -q import -I ! -m initial-import abc vendor initial" \
+'
+No conflicts created by this import'
+
+ dotest rdiff-short-init-2 "${testcvs} -q get abc" ''
+ cd abc
+ echo "abc" >file1.txt
+ dotest rdiff-short-init-3 "${testcvs} add file1.txt" \
+"${PROG} add: scheduling file .file1\.txt' for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
+ dotest rdiff-short-init-4 \
+"${testcvs} commit -madd-file1 file1.txt" \
+"RCS file: ${CVSROOT_DIRNAME}/abc/file1\.txt,v
+done
+Checking in file1\.txt;
+${CVSROOT_DIRNAME}/abc/file1\.txt,v <-- file1\.txt
+initial revision: 1\.1
+done"
+ echo def >>file1.txt
+ dotest rdiff-short-init-5 \
+"${testcvs} commit -mchange-file1 file1.txt" \
+"Checking in file1\.txt;
+${CVSROOT_DIRNAME}/abc/file1\.txt,v <-- file1\.txt
+new revision: 1\.2; previous revision: 1\.1
+done"
+ echo "abc" >file1.txt
+ dotest rdiff-short-init-6 \
+"${testcvs} commit -mrestore-file1-rev1 file1.txt" \
+"Checking in file1\.txt;
+${CVSROOT_DIRNAME}/abc/file1\.txt,v <-- file1\.txt
+new revision: 1\.3; previous revision: 1\.2
+done"
+ dotest rdiff-short-init-7 \
+"${testcvs} tag -r 1.1 tag1 file1.txt" \
+"T file1\.txt"
+ dotest rdiff-short-init-8 \
+"${testcvs} tag -r 1.2 tag2 file1.txt" \
+"T file1\.txt"
+ dotest rdiff-short-init-9 \
+"${testcvs} tag -r 1.3 tag3 file1.txt" \
+"T file1\.txt"
+ echo "abc" >file2.txt
+ dotest rdiff-short-init-10 \
+"${testcvs} add file2.txt" \
+"${PROG} add: scheduling file .file2\.txt' for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
+ dotest rdiff-add-remove-nodiff-init-11 \
+"${testcvs} commit -madd-file2 file2.txt" \
+"RCS file: ${CVSROOT_DIRNAME}/abc/file2\.txt,v
+done
+Checking in file2\.txt;
+${CVSROOT_DIRNAME}/abc/file2\.txt,v <-- file2\.txt
+initial revision: 1\.1
+done"
+ dotest rdiff-short-init-12 \
+"${testcvs} tag -r 1.1 tag4 file2.txt" \
+"T file2\.txt"
+ dotest rdiff-short-init-13 \
+"${testcvs} tag -r 1.1 tag5 file2.txt" \
+"T file2\.txt"
+ cd ../..
+ rm -fr rdiff-short
+
+ # 3) Different revision number with no difference.
+ dotest rdiff-short-no-real-change \
+"${testcvs} -q rdiff -s -r tag1 -r tag3 abc"
+
+ # 4) Different revision number with changes.
+ dotest rdiff-short-real-change \
+"${testcvs} -q rdiff -s -r tag1 -r tag2 abc" \
+'File abc/file1.txt changed from revision 1\.1 to 1\.2'
+
+ # 1) Added file.
+ # 2) Removed file.
+ dotest_sort rdiff-short-remove-add \
+"${testcvs} -q rdiff -s -r tag2 -r tag4 abc" \
+'File abc/file1\.txt is removed; tag2 revision 1\.2
+File abc/file2\.txt is new; tag4 revision 1\.1'
+
+ # 6) Same revision number (no difference).
+ dotest rdiff-short-no-change \
+"${testcvs} -q rdiff -s -r tag4 -r tag5 abc"
+
+ # 5) Against trunk.
+ # Check that the messages change when we diff against the trunk
+ # rather than a tag or date.
+ dotest rdiff-short-against-trunk-1 \
+"${testcvs} -q rdiff -s -rtag4 abc" \
+"File abc/file1\.txt is new; current revision 1\.3"
+
+ dotest rdiff-short-against-trunk-2 \
+"${testcvs} -q rdiff -s -rtag2 abc" \
+"File abc/file1\.txt changed from revision 1\.2 to 1\.3
+File abc/file2\.txt is new; current revision 1\.1"
+
+ rm -rf ${CVSROOT_DIRNAME}/abc
+ ;;
+
+ rdiff2)
+ # Test for the segv problem reported by James Cribb
+ # Somewhere to work
+ mkdir rdiff2; cd rdiff2
+ # Create a module "m" with files "foo" and "d/bar"
+ mkdir m; cd m
+ echo foo >foo
+ mkdir d
+ echo bar >d/bar
+ dotest_sort rdiff2-1 \
+"${testcvs} -q import -I ! -m initial-import m vendor initial" \
+'
+
+N m/d/bar
+N m/foo
+No conflicts created by this import'
+
+ cd ..
+ rm -r m
+
+ # Remove "foo"
+ dotest rdiff2-2 "${testcvs} get m" \
+"${PROG} checkout: Updating m
+U m/foo
+${PROG} checkout: Updating m/d
+U m/d/bar"
+ cd m
+ dotest rdiff2-3 "${testcvs} rm -f foo" \
+"${PROG} remove: scheduling .foo. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
+
+ dotest rdiff2-4 "${testcvs} commit -m Removed foo" \
+"Removing foo;
+${CVSROOT_DIRNAME}/m/foo,v <-- foo
+new revision: delete; previous revision: 1\.1\.1\.1
+done"
+
+ # Modify "d/bar"
+ echo foo >d/bar
+ dotest rdiff2-5 "${testcvs} commit -m Changed d/bar" \
+"Checking in d/bar;
+${CVSROOT_DIRNAME}/m/d/bar,v <-- bar
+new revision: 1\.2; previous revision: 1\.1
+done"
+
+ # Crash before showing d/bar diffs
+ dotest_fail rdiff2-6 "${testcvs} rdiff -t m" \
+"${PROG} rdiff: Diffing m
+${PROG} rdiff: Diffing m/d
+Index: m/d/bar
+diff -c m/d/bar:1\.1\.1\.1 m/d/bar:1\.2
+\*\*\* m/d/bar:1\.1\.1\.1 ${DATE}
+--- m/d/bar ${DATE}
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
+\*\*\* 1 \*\*\*\*
+! bar
+--- 1 ----
+! foo"
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+ cd ../..
+ rm -rf rdiff2
+ rm -rf ${CVSROOT_DIRNAME}/m
+ ;;
+
diff)
# Various tests specific to the "cvs diff" command.
# Related tests:
@@ -3866,11 +4408,11 @@ diff -c /dev/null trdiff/new:1\.1
# known" message (or worse yet, no message in some cases) but
# diff says "I know nothing". Shrug.
dotest_fail diff-3 "${testcvs} diff xyzpdq" \
-"${PROG} [a-z]*: I know nothing about xyzpdq"
+"${PROG} diff: I know nothing about xyzpdq"
touch abc
dotest diff-4 "${testcvs} add abc" \
-"${PROG} [a-z]*: scheduling file .abc. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .abc. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest diff-5 "${testcvs} -q ci -mtest" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
done
@@ -3908,6 +4450,166 @@ extern int gethostname ();
rm -r 1
;;
+ diffnl)
+ # Test handling of 'cvs diff' of files without newlines
+ mkdir 1; cd 1
+ dotest diffnl-000 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest diffnl-001 "${testcvs} add first-dir" \
+"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
+ cd first-dir
+
+ ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nfive\nsix")}' </dev/null >abc
+ dotest diffnl-002 "${testcvs} add abc" \
+"${PROG} add: scheduling file .abc. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
+ dotest diffnl-003 "${testcvs} -q ci -mtest" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
+done
+Checking in abc;
+${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc
+initial revision: 1\.1
+done"
+
+ # change to line near EOF
+ ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nsix")}' </dev/null >abc
+ dotest_fail diffnl-100 "${testcvs} diff abc" \
+"Index: abc
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
+retrieving revision 1\.1
+diff -r1\.1 abc
+5d4
+< five"
+ dotest_fail diffnl-101 "${testcvs} diff -u abc" \
+"Index: abc
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
+retrieving revision 1\.1
+diff -u -r1\.1 abc
+--- abc ${RFCDATE} 1\.1
++++ abc ${RFCDATE}
+@@ -2,5 +2,4 @@
+ two
+ three
+ four
+-five
+ six
+\\\\ No newline at end of file"
+ dotest diffnl-102 "${testcvs} -q ci -mtest abc" \
+"Checking in abc;
+${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc
+new revision: 1\.2; previous revision: 1\.1
+done"
+
+ # Change to last line
+ ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nseven")}' </dev/null >abc
+ dotest_fail diffnl-200 "${testcvs} diff abc" \
+"Index: abc
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
+retrieving revision 1\.2
+diff -r1\.2 abc
+5c5
+< six
+\\\\ No newline at end of file
+---
+> seven
+\\\\ No newline at end of file"
+ dotest_fail diffnl-201 "${testcvs} diff -u abc" \
+"Index: abc
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
+retrieving revision 1\.2
+diff -u -r1\.2 abc
+--- abc ${RFCDATE} 1\.2
++++ abc ${RFCDATE}
+@@ -2,4 +2,4 @@
+ two
+ three
+ four
+-six
+\\\\ No newline at end of file
++seven
+\\\\ No newline at end of file"
+ dotest diffnl-202 "${testcvs} ci -mtest abc" \
+"Checking in abc;
+${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc
+new revision: 1\.3; previous revision: 1\.2
+done"
+
+ # Addition of newline
+ echo "one
+two
+three
+four
+seven" > abc
+ dotest_fail diffnl-300 "${testcvs} diff abc" \
+"Index: abc
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
+retrieving revision 1\.3
+diff -r1\.3 abc
+5c5
+< seven
+\\\\ No newline at end of file
+---
+> seven"
+ dotest_fail diffnl-301 "${testcvs} diff -u abc" \
+"Index: abc
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
+retrieving revision 1\.3
+diff -u -r1\.3 abc
+--- abc ${RFCDATE} 1\.3
++++ abc ${RFCDATE}
+@@ -2,4 +2,4 @@
+ two
+ three
+ four
+-seven
+\\\\ No newline at end of file
++seven"
+ dotest diffnl-302 "${testcvs} ci -mtest abc" \
+"Checking in abc;
+${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc
+new revision: 1\.4; previous revision: 1\.3
+done"
+
+ # Removal of newline
+ ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nseven")}' </dev/null >abc
+ dotest_fail diffnl-400 "${testcvs} diff abc" \
+"Index: abc
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
+retrieving revision 1\.4
+diff -r1\.4 abc
+5c5
+< seven
+---
+> seven
+\\\\ No newline at end of file"
+ dotest_fail diffnl-401 "${testcvs} diff -u abc" \
+"Index: abc
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
+retrieving revision 1\.4
+diff -u -r1\.4 abc
+--- abc ${RFCDATE} 1\.4
++++ abc ${RFCDATE}
+@@ -2,4 +2,4 @@
+ two
+ three
+ four
+-seven
++seven
+\\\\ No newline at end of file"
+
+ cd ../..
+ rm -r 1
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
death)
# next dive. test death support.
@@ -3933,8 +4635,8 @@ extern int gethostname ();
cd subdir
echo file in subdir >sfile
dotest 65a1 "${testcvs} add sfile" \
-"${PROG}"' [a-z]*: scheduling file `sfile'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `sfile'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest 65a2 "${testcvs} -q ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v
done
@@ -3944,8 +4646,8 @@ initial revision: 1\.1
done"
rm sfile
dotest 65a3 "${testcvs} rm sfile" \
-"${PROG}"' [a-z]*: scheduling `sfile'\'' for removal
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove this file permanently'
+"${PROG}"' remove: scheduling `sfile'\'' for removal
+'"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently'
dotest 65a4 "${testcvs} -q ci -m remove-it" \
"Removing sfile;
${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v <-- sfile
@@ -4019,8 +4721,8 @@ done"
# file4 will be dead at the time of branching and stay dead.
echo file4 > file4
dotest death-file4-add "${testcvs} add file4" \
-"${PROG}"' [a-z]*: scheduling file `file4'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file4'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest death-file4-ciadd "${testcvs} -q ci -m add file4" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v
done
@@ -4030,8 +4732,8 @@ initial revision: 1\.1
done"
rm file4
dotest death-file4-rm "${testcvs} remove file4" \
-"${PROG}"' [a-z]*: scheduling `file4'\'' for removal
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove this file permanently'
+"${PROG}"' remove: scheduling `file4'\'' for removal
+'"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently'
dotest death-file4-cirm "${testcvs} -q ci -m remove file4" \
"Removing file4;
${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4
@@ -4077,22 +4779,22 @@ T file2'
"${testcvs} -q rdiff -r bp_branch1 -r branch1 first-dir" \
"Index: first-dir/file3
diff -c /dev/null first-dir/file3:1\.1\.2\.1
-\*\*\* /dev/null .*
---- first-dir/file3 .*
+\*\*\* /dev/null ${DATE}
+--- first-dir/file3 ${DATE}
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 0 \*\*\*\*
--- 1 ----
${PLUS} line1 from branch1"
dotest death-76a1 \
"${testcvs} -q rdiff -r branch1 -r bp_branch1 first-dir" \
-'Index: first-dir/file3
+"Index: first-dir/file3
diff -c first-dir/file3:1\.1\.2\.1 first-dir/file3:removed
-\*\*\* first-dir/file3:1\.1\.2\.1 .*
---- first-dir/file3 .*
+\*\*\* first-dir/file3:1\.1\.2\.1 ${DATE}
+--- first-dir/file3 ${DATE}
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1 \*\*\*\*
- line1 from branch1
---- 0 ----'
+--- 0 ----"
# remove
rm file3
@@ -4170,7 +4872,7 @@ diff -c first-dir/file3:1\.1\.2\.1 first-dir/file3:removed
retrieving revision 1\.3
retrieving revision 1\.3\.2\.1
Merging differences between 1\.3 and 1\.3\.2\.1 into file1
-${PROG} [a-z]*: scheduling file2 for removal
+${PROG} update: scheduling file2 for removal
U file3"
dotest_fail death-file4-5 "test -f file4" ''
@@ -4241,7 +4943,7 @@ U first-dir/file3'
# typo; try to get to the branch and fail
dotest_fail 92.1a "${testcvs} update -r brnach1" \
- "${PROG}"' \[[a-z]* aborted\]: no such tag brnach1'
+ "${PROG}"' \[update aborted\]: no such tag brnach1'
# Make sure we are still on the trunk
if test -f file1 ; then
fail 92.1b
@@ -4271,8 +4973,8 @@ U first-dir/file3'
# and join
dotest 95 "${testcvs} -q update -j HEAD" \
-"${PROG}"' [a-z]*: file file1 has been modified, but has been removed in revision HEAD
-'"${PROG}"' [a-z]*: file file3 exists, but has been added in revision HEAD'
+"${PROG}"' update: file file1 has been modified, but has been removed in revision HEAD
+'"${PROG}"' update: file file3 exists, but has been added in revision HEAD'
dotest_fail death-file4-7 "test -f file4" ''
@@ -4297,9 +4999,9 @@ U first-dir/file3'
echo "first revision" > file1
echo "file4 first revision" > file4
dotest death2-2 "${testcvs} add file1 file4" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: scheduling file `file4'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add these files permanently'
+"${PROG}"' add: scheduling file `file1'\'' for addition
+'"${PROG}"' add: scheduling file `file4'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently'
dotest death2-3 "${testcvs} -q commit -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
@@ -4329,12 +5031,12 @@ T file4'
# Delete the file on the branch.
rm file1
dotest death2-7 "${testcvs} rm file1" \
-"${PROG} [a-z]*: scheduling .file1. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file1. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
# Test diff of the removed file before it is committed.
dotest_fail death2-diff-1 "${testcvs} -q diff file1" \
-"${PROG} [a-z]*: file1 was removed, no comparison available"
+"${PROG} diff: file1 was removed, no comparison available"
dotest_fail death2-diff-2 "${testcvs} -q diff -N -c file1" \
"Index: file1
@@ -4351,13 +5053,19 @@ diff -N file1
dotest death2-8 "${testcvs} -q ci -m removed" \
"Removing file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
-new revision: delete; previous revision: 1\.1\.2
+new revision: delete; previous revision: 1\.1
done"
# Test diff of a dead file.
dotest_fail death2-diff-3 \
"${testcvs} -q diff -r1.1 -rbranch -c file1" \
-"${PROG} [a-z]*: file1 was removed, no comparison available"
+"${PROG} diff: Tag branch refers to a dead (removed) revision in file .file1.\.
+${PROG} diff: No comparison available\. Pass .-N. to .${PROG} diff.${QUESTION}"
+ # and in reverse
+ dotest_fail death2-diff-3a \
+"${testcvs} -q diff -rbranch -r1.1 -c file1" \
+"${PROG} diff: Tag branch refers to a dead (removed) revision in file .file1.\.
+${PROG} diff: No comparison available\. Pass .-N. to .${PROG} diff.${QUESTION}"
dotest_fail death2-diff-4 \
"${testcvs} -q diff -r1.1 -rbranch -N -c file1" \
@@ -4371,9 +5079,23 @@ diff -N file1
\*\*\* 1 \*\*\*\*
- first revision
--- 0 ----"
+ # and in reverse
+ dotest_fail death2-diff-4a \
+"${testcvs} -q diff -rbranch -r1.1 -N -c file1" \
+"Index: file1
+===================================================================
+RCS file: file1
+diff -N file1
+\*\*\* /dev/null ${RFCDATE_EPOCH}
+--- file1 ${RFCDATE} [0-9.]*
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
+\*\*\* 0 \*\*\*\*
+--- 1 ----
++ first revision"
+
dotest_fail death2-diff-5 "${testcvs} -q diff -rtag -c ." \
-"${PROG} [a-z]*: file1 no longer exists, no comparison available"
+"${PROG} diff: file1 no longer exists, no comparison available"
dotest_fail death2-diff-6 "${testcvs} -q diff -rtag -N -c ." \
"Index: file1
@@ -4404,12 +5126,12 @@ diff -c first-dir/file1:1\.1 first-dir/file1:removed
# Readd the file to the branch.
echo "second revision" > file1
dotest death2-9 "${testcvs} add file1" \
-"${PROG}"' [a-z]*: file `file1'\'' will be added on branch `branch'\'' from version 1\.1\.2\.1
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: file `file1'\'' will be added on branch `branch'\'' from version 1\.1\.2\.1
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
# Test diff of the added file before it is committed.
dotest_fail death2-diff-7 "${testcvs} -q diff file1" \
-"${PROG} [a-z]*: file1 is a new entry, no comparison available"
+"${PROG} diff: file1 is a new entry, no comparison available"
dotest_fail death2-diff-8 "${testcvs} -q diff -N -c file1" \
"Index: file1
@@ -4431,12 +5153,12 @@ done"
# Delete file4 from the branch
dotest death2-10a "${testcvs} rm -f file4" \
-"${PROG} [a-z]*: scheduling .file4. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file4. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest death2-10b "${testcvs} -q ci -m removed" \
"Removing file4;
${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4
-new revision: delete; previous revision: 1\.1\.2
+new revision: delete; previous revision: 1\.1
done"
# Back to the trunk.
@@ -4447,8 +5169,8 @@ U file4"
# Add another file on the trunk.
echo "first revision" > file2
dotest death2-12 "${testcvs} add file2" \
-"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file2'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest death2-13 "${testcvs} -q commit -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
done
@@ -4471,14 +5193,14 @@ done"
# this case.
dotest death2-14 "${testcvs} -q update -r branch" \
"[UP] file1
-${PROG} [a-z]*: file2 is no longer in the repository
-${PROG} [a-z]*: file4 is no longer in the repository"
+${PROG} update: file2 is no longer in the repository
+${PROG} update: file4 is no longer in the repository"
# Add a file on the branch with the same name.
echo "branch revision" > file2
dotest death2-15 "${testcvs} add file2" \
-"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition on branch `branch'\''
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file2'\'' for addition on branch `branch'\''
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest death2-16 "${testcvs} -q commit -m add" \
"Checking in file2;
${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
@@ -4488,8 +5210,8 @@ done"
# Add a new file on the branch.
echo "first revision" > file3
dotest death2-17 "${testcvs} add file3" \
-"${PROG}"' [a-z]*: scheduling file `file3'\'' for addition on branch `branch'\''
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file3'\'' for addition on branch `branch'\''
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest death2-18 "${testcvs} -q commit -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
done
@@ -4500,7 +5222,7 @@ done"
# Test diff of a nonexistent tag
dotest_fail death2-diff-9 "${testcvs} -q diff -rtag -c file3" \
-"${PROG} [a-z]*: tag tag is not in file file3"
+"${PROG} diff: tag tag is not in file file3"
dotest_fail death2-diff-10 "${testcvs} -q diff -rtag -N -c file3" \
"Index: file3
@@ -4528,9 +5250,9 @@ diff -c -r1\.1 -r1\.1\.2\.2
! first revision
--- 1 ----
! second revision
-${PROG} [a-z]*: tag tag is not in file file2
-${PROG} [a-z]*: tag tag is not in file file3
-${PROG} [a-z]*: file4 no longer exists, no comparison available"
+${PROG} diff: tag tag is not in file file2
+${PROG} diff: tag tag is not in file file3
+${PROG} diff: file4 no longer exists, no comparison available"
dotest_fail death2-diff-12 "${testcvs} -q diff -rtag -c -N ." \
"Index: file1
@@ -4580,15 +5302,16 @@ diff -N file4
# Switch to the nonbranch tag.
dotest death2-19 "${testcvs} -q update -r tag" \
"[UP] file1
-${PROG} [a-z]*: file2 is no longer in the repository
-${PROG} [a-z]*: file3 is no longer in the repository
+${PROG} update: file2 is no longer in the repository
+${PROG} update: file3 is no longer in the repository
U file4"
dotest_fail death2-20 "test -f file2"
# Make sure diff only reports appropriate files.
dotest_fail death2-diff-13 "${testcvs} -q diff -r rdiff-tag" \
-"${PROG} [a-z]*: file1 is a new entry, no comparison available"
+"${PROG} diff: Tag rdiff-tag refers to a dead (removed) revision in file .file1.\.
+${PROG} diff: No comparison available\. Pass .-N. to .${PROG} diff.${QUESTION}"
dotest_fail death2-diff-14 "${testcvs} -q diff -r rdiff-tag -c -N" \
"Index: file1
@@ -4615,8 +5338,8 @@ U first-dir/file4"
cd first-dir
dotest death2-23 "${testcvs} rm -f file4" \
-"${PROG} [a-z]*: scheduling .file4. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file4. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest death2-24 "${testcvs} -q ci -m removed file4" \
"Removing file4;
${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4
@@ -4625,7 +5348,7 @@ done"
cd ..
echo "new stuff" >file4
dotest_fail death2-25 "${testcvs} up file4" \
-"${PROG} [a-z]*: conflict: file4 is modified but no longer in the repository
+"${PROG} update: conflict: file4 is modified but no longer in the repository
C file4"
cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir
@@ -4642,7 +5365,7 @@ C file4"
file=x
echo >$file
dotest rm-update-message-setup-2 "$testcvs -q add $file" \
-"$PROG [a-z]*: use .$PROG commit. to add this file permanently"
+"${PROG} add: use .${PROG} commit. to add this file permanently"
dotest rm-update-message-setup-3 "$testcvs -q ci -mcreate $file" \
"RCS file: $CVSROOT_DIRNAME/rm-update-message/$file,v
done
@@ -4652,13 +5375,9 @@ initial revision: 1\.1
done"
rm $file
- if $remote; then
- dotest rm-update-message-1 "$testcvs up $file" "U $file"
- else
- dotest rm-update-message-1 "$testcvs up $file" \
-"$PROG [a-z]*: warning: $file was lost
+ dotest rm-update-message-1 "$testcvs up $file" \
+"${PROG} update: warning: $file was lost
U $file"
- fi
cd ../..
if $keep; then :; else
@@ -4684,17 +5403,17 @@ U $file"
cd first-dir
echo first file1 >file1
dotest rmadd-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest_fail rmadd-4 "${testcvs} -q ci -r 1.2.2.4 -m add" \
-"${PROG} [a-z]*: cannot add file .file1' with revision .1\.2\.2\.4'; must be on trunk
-${PROG} \[[a-z]* aborted\]: correct above errors first!"
+"${PROG} commit: cannot add file .file1' with revision .1\.2\.2\.4'; must be on trunk
+${PROG} \[commit aborted\]: correct above errors first!"
dotest_fail rmadd-5 "${testcvs} -q ci -r 1.2.2 -m add" \
-"${PROG} [a-z]*: cannot add file .file1' with revision .1\.2\.2'; must be on trunk
-${PROG} \[[a-z]* aborted\]: correct above errors first!"
+"${PROG} commit: cannot add file .file1' with revision .1\.2\.2'; must be on trunk
+${PROG} \[commit aborted\]: correct above errors first!"
dotest_fail rmadd-6 "${testcvs} -q ci -r mybranch -m add" \
-"${PROG} \[[a-z]* aborted\]: no such tag mybranch"
+"${PROG} \[commit aborted\]: no such tag mybranch"
# The thing with the trailing periods strikes me as a very
# bizarre behavior, but it would seem to be intentional
@@ -4726,8 +5445,8 @@ done"
# saying "sticky tag is not a branch" like keywordlog-4b.
# Or something.
dotest rmadd-10 "${testcvs} add file2" \
-"${PROG} [a-z]*: scheduling file .file2. for addition on branch .7'
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file2. for addition on branch .7'
+${PROG} add: use .${PROG} commit. to add this file permanently"
# As in the previous example, CVS is confused....
dotest rmadd-11 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
@@ -4740,12 +5459,12 @@ done"
dotest rmadd-12 "${testcvs} -q update -A" ""
touch file3
dotest rmadd-13 "${testcvs} add file3" \
-"${PROG} [a-z]*: scheduling file .file3. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file3. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
# Huh? file2 is not up to date? Seems buggy to me....
dotest_fail rmadd-14 "${testcvs} -q ci -r mybranch -m add" \
-"${PROG} [a-z]*: Up-to-date check failed for .file2'
-${PROG} \[[a-z]* aborted\]: correct above errors first!"
+"${PROG} commit: Up-to-date check failed for .file2'
+${PROG} \[commit aborted\]: correct above errors first!"
# Whatever, let's not let file2 distract us....
dotest rmadd-15 "${testcvs} -q ci -r mybranch -m add file3" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
@@ -4757,15 +5476,15 @@ done"
touch file4
dotest rmadd-16 "${testcvs} add file4" \
-"${PROG} [a-z]*: scheduling file .file4. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file4. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
# Same "Up-to-date check" issues as in rmadd-14.
# The "no such tag" thing is due to the fact that we only
# update val-tags when the tag is used (might be more of a
# bug than a feature, I dunno).
dotest_fail rmadd-17 \
"${testcvs} -q ci -r mynonbranch -m add file4" \
-"${PROG} \[[a-z]* aborted\]: no such tag mynonbranch"
+"${PROG} \[commit aborted\]: no such tag mynonbranch"
# Try to make CVS write val-tags.
dotest rmadd-18 "${testcvs} -q update -p -r mynonbranch file1" \
"first file1"
@@ -4773,7 +5492,7 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
# behavior).
dotest_fail rmadd-19 \
"${testcvs} -q ci -r mynonbranch -m add file4" \
-"${PROG} \[[a-z]* aborted\]: no such tag mynonbranch"
+"${PROG} \[commit aborted\]: no such tag mynonbranch"
# Now make CVS write val-tags for real.
dotest rmadd-20 "${testcvs} -q update -r mynonbranch file1" ""
# Oops - CVS isn't distinguishing between a branch tag and
@@ -4791,8 +5510,8 @@ done"
# a modification with ci -r and sniff around for sticky tags.
echo file5 >file5
dotest rmadd-22 "${testcvs} add file5" \
-"${PROG} [a-z]*: scheduling file .file5. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file5. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
if $remote; then
# Interesting bug (or missing feature) here. findmaxrev
# gets the major revision from the Entries. Well, remote
@@ -4823,8 +5542,8 @@ done"
dotest_fail rmadd-24 "${testcvs} -q ci -r 4.8 -m change file5" \
"Checking in file5;
${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/file5,v: revision 4\.8 too low; must be higher than 7\.1
-${PROG} [a-z]*: could not check in file5"
+${PROG} commit: ${CVSROOT_DIRNAME}/first-dir/file5,v: revision 4\.8 too low; must be higher than 7\.1
+${PROG} commit: could not check in file5"
dotest rmadd-24a "${testcvs} -q ci -r 8.4 -m change file5" \
"Checking in file5;
${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5
@@ -4848,7 +5567,7 @@ File: file5 Status: Up-to-date
"Directory ${CVSROOT_DIRNAME}/first-dir/sub added to the repository"
echo hello >sub/subfile
dotest rmadd-27 "${testcvs} -q add sub/subfile" \
-"${PROG} [a-z]*: use .$PROG commit. to add this file permanently"
+"${PROG} add: use .${PROG} commit. to add this file permanently"
dotest rmadd-28 "${testcvs} -q ci -m. sub" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/sub/subfile,v
@@ -4860,8 +5579,8 @@ done"
# lose the branch
dotest rmadd-29 "${testcvs} -q up -A" \
-"${PROG} [a-z]*: file3 is no longer in the repository
-${PROG} [a-z]*: file4 is no longer in the repository"
+"${PROG} update: file3 is no longer in the repository
+${PROG} update: file4 is no longer in the repository"
# -f disables recursion
dotest rmadd-30 "${testcvs} -q ci -f -r9 -m." \
@@ -4921,8 +5640,8 @@ done"
cd first-dir
echo 'initial contents' >file1
dotest rmadd2-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest rmadd2-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -4932,8 +5651,8 @@ initial revision: 1\.1
done"
dotest rmadd2-4a "${testcvs} -Q tag tagone" ""
dotest rmadd2-5 "${testcvs} rm -f file1" \
-"${PROG} [a-z]*: scheduling .file1. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file1. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest rmadd2-6 "${testcvs} -q ci -m remove" \
"Removing file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
@@ -4967,7 +5686,7 @@ done"
# Hmm, might be a bit odd that this works even if 1.3 is not
# the head.
dotest rmadd2-14 "${testcvs} -q update -j 1.3 -j 1.2 file1" \
-"${PROG} [a-z]*: scheduling file1 for removal"
+"${PROG} update: scheduling file1 for removal"
# Check that -p can get arbitrary revisions of a removed file
dotest rmadd2-14a "${testcvs} -q update -p" "initial contents"
@@ -5007,6 +5726,155 @@ File: no file file1 Status: Up-to-date
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ rmadd3)
+ # This test demonstrates that CVS notices that file1 exists rather
+ # that deleting or writing over it after:
+ #
+ # cvs remove -f file1; touch file1; cvs add file1.
+ #
+ # According to the manual, this should work for:
+ #
+ # rm file1; cvs remove file1; cvs add file1
+ #
+ # but in past version of CVS, new content in file1 would be
+ # erroneously deleted when file1 reappeared between the remove and
+ # the add.
+ #
+ # Later versions of CVS would refuse to perform the add, but still
+ # allow a subsequent local commit to erase the file from the
+ # workspace, possibly losing data.
+ mkdir 1; cd 1
+ dotest rmadd3-init1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest rmadd3-init2 "${testcvs} add first-dir" \
+"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
+ cd first-dir
+
+ echo initial content for file1 >file1
+ dotest rmadd3-init3 "${testcvs} add file1" \
+"${PROG} add: scheduling file \`file1' for addition
+${PROG} add: use '${PROG} commit' to add this file permanently"
+ dotest rmadd3-init4 "${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"
+
+ # Here begins the guts of this test, as detailed above.
+ dotest rmadd3-1 "${testcvs} rm -f file1" \
+"${PROG} remove: scheduling \`file1' for removal
+${PROG} remove: use '${PROG} commit' to remove this file permanently"
+
+ # Now recreate the file:
+ echo desired future contents for file1 >file1
+
+ # And attempt to resurrect it at the same time:
+ dotest_fail rmadd3-2 "${testcvs} add file1" \
+"${PROG} add: file1 should be removed and is still there (or is back again)"
+
+ # Now prove that commit knows that it shouldn't erase files.
+ dotest_fail rmadd3-3 "${testcvs} -q ci -m." \
+"$PROG commit: \`file1' should be removed and is still there (or is back again)
+$PROG \[commit aborted\]: correct above errors first!"
+
+ # Then these should pass too:
+ dotest rmadd3-4 "test -f file1"
+ dotest rmadd3-5 "cat file1" "desired future contents for file1"
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ rm -r 1
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
+ resurrection)
+ # This test tests a few file resurrection scenarios.
+ mkdir 1; cd 1
+ dotest resurrection-init1 "$testcvs -q co -l ." ''
+ mkdir first-dir
+ dotest resurrection-init2 "$testcvs add first-dir" \
+"Directory $CVSROOT_DIRNAME/first-dir added to the repository"
+ cd first-dir
+
+ echo initial content for file1 >file1
+ dotest resurrection-init3 "$testcvs add file1" \
+"$PROG add: scheduling file \`file1' for addition
+$PROG add: use '$PROG commit' to add this file permanently"
+ dotest resurrection-init4 "$testcvs -q ci -m add" \
+"RCS file: $CVSROOT_DIRNAME/first-dir/file1,v
+done
+Checking in file1;
+$CVSROOT_DIRNAME/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done"
+
+ dotest resurrection-init5 "$testcvs -Q rm -f file1"
+
+ # The first test is that `cvs add' will resurrect a file before it
+ # has been committed.
+ dotest_sort resurrection-1 "$testcvs add file1" \
+"U file1
+$PROG add: file1, version 1\.1, resurrected"
+ dotest resurrection-2 "$testcvs -Q diff file1" ""
+
+ dotest resurrection-init6 "$testcvs -Q tag -b resurrection"
+ dotest resurrection-init7 "$testcvs -Q rm -f file1"
+ dotest resurrection-init8 "$testcvs -Q ci -mrm" \
+"Removing file1;
+$CVSROOT_DIRNAME/first-dir/file1,v <-- file1
+new revision: delete; previous revision: 1\.1
+done"
+
+ # The next test is that CVS will resurrect a committed removal.
+ dotest_sort resurrection-3 "$testcvs add file1" \
+"U file1
+$PROG add: Re-adding file \`file1' (in place of dead revision 1\.2)\.
+$PROG add: Resurrecting file \`file1' from revision 1\.1\.
+$PROG add: use 'cvs commit' to add this file permanently"
+ dotest resurrection-4 "$testcvs -q diff -r1.1 file1" ""
+ dotest resurrection-5 "$testcvs -q ci -mreadd" \
+"Checking in file1;
+$CVSROOT_DIRNAME/first-dir/file1,v <-- file1
+new revision: 1\.3; previous revision: 1\.2
+done"
+
+ dotest resurrection-init9 "$testcvs -Q up -rresurrection"
+ dotest resurrection-init10 "$testcvs -Q rm -f file1"
+ dotest resurrection-init11 "$testcvs -Q ci -mrm-on-resurrection" \
+"Removing file1;
+$CVSROOT_DIRNAME/first-dir/file1,v <-- file1
+new revision: delete; previous revision: 1\.1
+done"
+
+ # The next test is that CVS will resurrect a committed removal to a
+ # branch.
+ dotest_sort resurrection-6 "$testcvs add file1" \
+"U file1
+$PROG add: Resurrecting file \`file1' from revision 1\.1\.
+$PROG add: file \`file1' will be added on branch \`resurrection' from version 1\.1\.2\.1
+$PROG add: use 'cvs commit' to add this file permanently"
+ dotest resurrection-7 "$testcvs -Q diff -r1.1 file1" ""
+ dotest resurrection-8 "$testcvs -q ci -mreadd" \
+"Checking in file1;
+$CVSROOT_DIRNAME/first-dir/file1,v <-- file1
+new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
+done"
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ rm -r 1
+ rm -rf $CVSROOT_DIRNAME/first-dir
+ ;;
+
dirs)
# Tests related to removing and adding directories.
# See also:
@@ -5028,7 +5896,7 @@ File: no file file1 Status: Up-to-date
N dir1/file1
N dir1/sdir/sfile
No conflicts created by this import
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/dir1/sdir"
+${PROG} import: Importing ${CVSROOT_DIRNAME}/dir1/sdir"
cd ..
mkdir 1; cd 1
@@ -5043,23 +5911,23 @@ ${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/dir1/sdir"
rm -rf ${CVSROOT_DIRNAME}/dir1/sdir
dotest dirs-3 "${testcvs} update" \
-"${PROG} [a-z]*: Updating dir1
-${PROG} [a-z]*: Updating dir1/sdir
-${PROG} [a-z]*: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory
-${PROG} [a-z]*: skipping directory dir1/sdir"
+"${PROG} update: Updating dir1
+${PROG} update: Updating dir1/sdir
+${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory
+${PROG} update: skipping directory dir1/sdir"
dotest dirs-3a "${testcvs} update -d" \
-"${PROG} [a-z]*: Updating dir1
-${PROG} [a-z]*: Updating dir1/sdir
-${PROG} [a-z]*: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory
-${PROG} [a-z]*: skipping directory dir1/sdir"
+"${PROG} update*: Updating dir1
+${PROG} update: Updating dir1/sdir
+${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory
+${PROG} update: skipping directory dir1/sdir"
# If we say "yes", then CVS gives errors about not being able to
# create lock files.
# The fact that it says "skipping directory " rather than
# "skipping directory dir1/sdir" is some kind of bug.
- echo no | dotest dirs-4 "${testcvs} release -d dir1/sdir" \
-"${PROG} [a-z]*: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory
-${PROG} [a-z]*: skipping directory
+ dotest dirs-4 "echo no | ${testcvs} release -d dir1/sdir" \
+"${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory
+${PROG} update: skipping directory
You have \[0\] altered files in this repository\.
Are you sure you want to release (and delete) directory .dir1/sdir': .. .release' aborted by user choice."
@@ -5069,12 +5937,12 @@ Are you sure you want to release (and delete) directory .dir1/sdir': .. .release
dotest dirs-5 "cat dir1/CVS/Entries" \
"/file1/1.1.1.1/[a-zA-Z0-9 :]*//
D/sdir////"
- dotest dirs-6 "${testcvs} update" "${PROG} [a-z]*: Updating dir1"
+ dotest dirs-6 "${testcvs} update" "${PROG} update: Updating dir1"
dotest dirs-7 "cat dir1/CVS/Entries" \
"/file1/1.1.1.1/[a-zA-Z0-9 :]*//
D/sdir////"
dotest dirs-8 "${testcvs} update -d dir1" \
-"${PROG} [a-z]*: Updating dir1"
+"${PROG} update: Updating dir1"
cd ..
@@ -5098,8 +5966,8 @@ D/sdir////"
"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository"
touch sdir/file1
dotest dirs2-4 "${testcvs} add sdir/file1" \
-"${PROG} [a-z]*: scheduling file .sdir/file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .sdir/file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest dirs2-5 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/file1,v
done
@@ -5112,8 +5980,8 @@ done"
# This is just like conflicts3-23
dotest_fail dirs2-6 "${testcvs} update -d" \
"${QUESTION} sdir
-${PROG} server: Updating \.
-${PROG} server: Updating sdir
+${PROG} update: Updating \.
+${PROG} update: Updating sdir
${PROG} update: move away sdir/file1; it is in the way
C sdir/file1"
rm sdir/file1
@@ -5122,8 +5990,8 @@ C sdir/file1"
# This is where things are not just like conflicts3-23
dotest dirs2-7 "${testcvs} update -d" \
"${QUESTION} sdir
-${PROG} server: Updating \.
-${PROG} server: Updating sdir
+${PROG} update: Updating \.
+${PROG} update: Updating sdir
U sdir/file1"
else
dotest dirs2-6 "${testcvs} update -d" \
@@ -5148,14 +6016,14 @@ ${QUESTION} sdir"
# get updated.
dotest_fail dirs2-10 "${testcvs} update -d -r br" \
"${QUESTION} sdir
-${PROG} \[server aborted\]: no such tag br"
- dotest dirs2-10-rem \
+${PROG} \[update aborted\]: no such tag br"
+ dotest dirs2-10ar \
"${testcvs} -q rdiff -u -r 1.1 -r br first-dir/sdir/file1" \
""
dotest_fail dirs2-10-again "${testcvs} update -d -r br" \
"${QUESTION} sdir
-${PROG} server: Updating \.
-${PROG} server: Updating sdir
+${PROG} update: Updating \.
+${PROG} update: Updating sdir
${PROG} update: move away sdir/file1; it is in the way
C sdir/file1"
else
@@ -5177,19 +6045,19 @@ ${PROG} \[update aborted\]: there is no version here; do '${PROG} checkout' firs
# Hmm, this doesn't mention the branch like add does. That's
# an odd non-orthogonality.
dotest dirs2-12 "${testcvs} rm -f sdir/file1" \
-"${PROG} [a-z]*: scheduling .sdir/file1. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .sdir/file1. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest dirs2-13 "${testcvs} -q ci -m remove" \
"Removing sdir/file1;
${CVSROOT_DIRNAME}/first-dir/sdir/file1,v <-- file1
-new revision: delete; previous revision: 1\.1\.2
+new revision: delete; previous revision: 1\.1
done"
cd ../../2/first-dir
if $remote; then
dotest dirs2-14 "${testcvs} update -d -r br" \
"${QUESTION} sdir/file1
-${PROG} server: Updating \.
-${PROG} server: Updating sdir"
+${PROG} update: Updating \.
+${PROG} update: Updating sdir"
else
dotest dirs2-14 "${testcvs} update -d -r br" \
"${PROG} update: Updating \.
@@ -5211,11 +6079,11 @@ ${QUESTION} sdir"
echo 3:ancest >file3
echo 4:trunk-1 >file4
dotest branches-2 "${testcvs} add file1 file2 file3 file4" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition
-'"${PROG}"' [a-z]*: scheduling file `file3'\'' for addition
-'"${PROG}"' [a-z]*: scheduling file `file4'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add these files permanently'
+"${PROG}"' add: scheduling file `file1'\'' for addition
+'"${PROG}"' add: scheduling file `file2'\'' for addition
+'"${PROG}"' add: scheduling file `file3'\'' for addition
+'"${PROG}"' add: scheduling file `file4'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently'
dotest branches-2a "${testcvs} -n -q ci -m dont-commit" ""
dotest_lit branches-3 "${testcvs} -q ci -m add-it" <<HERE
RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
@@ -5260,13 +6128,13 @@ T file4"
# someone is hacking along, says "oops, I should be doing this on
# a branch", and only then creates the branch.
echo 1:br1 >file1
- dotest branches-4 "${testcvs} tag -b br1" "${PROG}"' [a-z]*: Tagging \.
+ dotest branches-4 "${testcvs} tag -b br1" "${PROG}"' tag: Tagging \.
T file1
T file2
T file3
T file4'
dotest branches-5 "${testcvs} update -r br1" \
-"${PROG} [a-z]*: Updating \.
+"${PROG} update: Updating \.
M file1"
echo 2:br1 >file2
echo 4:br1 >file4
@@ -5371,7 +6239,7 @@ revision 1\.2\.2\.1\.2\.1
date: [0-9/: ]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1
modify
============================================================================="
- dotest_status branches-14.4 1 \
+ dotest_fail branches-14.4 \
"${testcvs} diff -c -r 1.1 -r 1.3 file4" \
"Index: file4
===================================================================
@@ -5386,7 +6254,7 @@ diff -c -r1\.1 -r1\.3
! 4:trunk-1
--- 1 ----
! 4:trunk-3"
- dotest_status branches-14.5 1 \
+ dotest_fail branches-14.5 \
"${testcvs} diff -c -r 1.1 -r 1.2.2.1 file4" \
"Index: file4
===================================================================
@@ -5449,8 +6317,8 @@ done"
cd first-dir
echo "file1 first revision" > file1
dotest branches2-2 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest branches2-3 "${testcvs} commit -m add file1" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -5474,16 +6342,16 @@ done"
cd first-dir
echo "file2 first revision" > file2
dotest branches2-8 "${testcvs} add file2" \
-"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition on branch `b1'\''
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file2'\'' for addition on branch `b1'\''
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
mkdir dir1
dotest branches2-9 "${testcvs} add dir1" \
"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository
--> Using per-directory sticky tag "'`'"b1'"
echo "file3 first revision" > dir1/file3
dotest branches2-10 "${testcvs} add dir1/file3" \
-"${PROG}"' [a-z]*: scheduling file `dir1/file3'\'' for addition on branch `b1'\''
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `dir1/file3'\'' for addition on branch `b1'\''
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest branches2-11 "${testcvs} -q ci -madd ." \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file2,v
done
@@ -5507,7 +6375,7 @@ done"
'U first-dir/file1'
cd first-dir
dotest branches2-13 "${testcvs} update -d -r b1 dir1" \
-"${PROG} [a-z]*: Updating dir1
+"${PROG} update: Updating dir1
U dir1/file3"
dotest branches2-14 "${testcvs} -q status" \
"===================================================================
@@ -5534,7 +6402,7 @@ File: file3 Status: Up-to-date
# below as well.
rm -r dir1
dotest branches2-15 "${testcvs} update -d -j b1 dir1" \
-"${PROG} [a-z]*: Updating dir1
+"${PROG} update: Updating dir1
U dir1/file3"
# FIXCVS: The `No revision control file' stuff seems to be
# CVS's way of telling us that we're adding the file on a
@@ -5561,10 +6429,10 @@ File: file3 Status: Locally Added
cd ../../trunk/first-dir
dotest branches2-17 "${testcvs} update -d -P dir1" \
-"${PROG} [a-z]*: Updating dir1"
+"${PROG} update: Updating dir1"
dotest_fail branches2-18 "test -d dir1"
dotest branches2-19 "${testcvs} update -d -P -r b1 dir1" \
-"${PROG} [a-z]*: Updating dir1
+"${PROG} update: Updating dir1
U dir1/file3"
dotest branches2-20 "${testcvs} -q status" \
"===================================================================
@@ -5587,7 +6455,7 @@ File: file3 Status: Up-to-date
rm -r dir1
dotest branches2-21 "${testcvs} update -d -P -j b1 dir1" \
-"${PROG} [a-z]*: Updating dir1
+"${PROG} update: Updating dir1
U dir1/file3"
dotest branches2-22 "${testcvs} -q status" \
"===================================================================
@@ -5633,8 +6501,8 @@ U first-dir/dir1/file3'
--> Using per-directory sticky tag "'`'"b1'"
echo "file4 first revision" > dir2/file4
dotest branches2-26 "${testcvs} add dir2/file4" \
-"${PROG}"' [a-z]*: scheduling file `dir2/file4'\'' for addition on branch `b1'\''
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `dir2/file4'\'' for addition on branch `b1'\''
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest branches2-27 "${testcvs} -q commit -madd" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/dir2/Attic/file4,v
done
@@ -5645,7 +6513,7 @@ done"
cd ../../b1b/first-dir
dotest branches2-28 "${testcvs} update -d dir2" \
-"${PROG} [a-z]*: Updating dir2
+"${PROG} update: Updating dir2
U dir2/file4"
cd dir2
dotest branches2-29 "${testcvs} -q status" \
@@ -5663,7 +6531,7 @@ File: file4 Status: Up-to-date
cd ..
rm -r dir2
dotest branches2-31 "${testcvs} update -A -d dir2" \
-"${PROG} [a-z]*: Updating dir2"
+"${PROG} update: Updating dir2"
cd dir2
dotest branches2-32 "${testcvs} -q status" ''
dotest_fail branches2-33 "test -f CVS/Tag"
@@ -5671,8 +6539,8 @@ File: file4 Status: Up-to-date
# Add a file on the trunk.
echo "file5 first revision" > file5
dotest branches2-34 "${testcvs} add file5" \
-"${PROG}"' [a-z]*: scheduling file `file5'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file5'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest branches2-35 "${testcvs} -q commit -madd" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/dir2/file5,v
done
@@ -5710,9 +6578,9 @@ File: file5 Status: Up-to-date
cd first-dir
touch file1 file2
dotest tagc-3 "${testcvs} add file1 file2" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest tagc-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -5738,17 +6606,17 @@ T file2"
sleep 1
echo myedit >>file1
dotest tagc-6a "${testcvs} rm -f file2" \
-"${PROG} [a-z]*: scheduling .file2. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file2. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
touch file3
dotest tagc-6b "${testcvs} add file3" \
-"${PROG} [a-z]*: scheduling file .file3. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file3. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest_fail tagc-7 "${testcvs} -q tag -c tag3" \
-"${PROG} [a-z]*: file1 is locally modified
-${PROG} [a-z]*: file2 is locally modified
-${PROG} [a-z]*: file3 is locally modified
-${PROG} \[[a-z]* aborted\]: correct the above errors first!"
+"${PROG} tag: file1 is locally modified
+${PROG} tag: file2 is locally modified
+${PROG} tag: file3 is locally modified
+${PROG} \[tag aborted\]: correct the above errors first!"
cd ../..
mkdir 2
cd 2
@@ -5773,7 +6641,7 @@ initial revision: 1\.1
done"
cd ../../2/first-dir
dotest tagc-10 "${testcvs} -q tag -c tag4" \
-"${PROG} [a-z]*: file2 is no longer in the repository
+"${PROG} tag: file2 is no longer in the repository
T file1
T file2"
cd ../..
@@ -5803,10 +6671,10 @@ T file2"
echo v1 > $file
dotest update-p-4 "$testcvs -Q add $file" ''
dotest update-p-5 "$testcvs -Q ci -m. $file" \
-"RCS file: ${TESTDIR}/cvsroot/$module/$file,v
+"RCS file: ${CVSROOT_DIRNAME}/$module/$file,v
done
Checking in $file;
-${TESTDIR}/cvsroot/$module/$file,v <-- $file
+${CVSROOT_DIRNAME}/$module/$file,v <-- $file
initial revision: 1\.1
done"
dotest update-p-6 "$testcvs -Q tag T $file" ''
@@ -5821,7 +6689,7 @@ done"
dotest update-p-9 "$testcvs update -p -rT $file" \
"===================================================================
Checking out $file
-RCS: ${TESTDIR}/cvsroot/$module/$file,v
+RCS: ${CVSROOT_DIRNAME}/$module/$file,v
VERS: 1\.1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
v1"
@@ -5835,7 +6703,7 @@ v1"
dotest update-p-10 "$testcvs update -p -rT $file" \
"===================================================================
Checking out $file
-RCS: ${TESTDIR}/cvsroot/$module/$file,v
+RCS: ${CVSROOT_DIRNAME}/$module/$file,v
VERS: 1\.1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
v1"
@@ -5852,25 +6720,25 @@ v1"
# to return to the state of being on the trunk with a $file
# that we can then remove.
dotest update-p-undead-0 "$testcvs update -A" \
-"${PROG} [a-z]*: Updating \.
-${PROG} [a-z]*: warning: new-born $file has disappeared"
+"${PROG} update: Updating \.
+${PROG} update: warning: new-born $file has disappeared"
dotest update-p-undead-1 "$testcvs update" \
-"${PROG} [a-z]*: Updating \.
+"${PROG} update: Updating \.
U $file"
dotest update-p-undead-2 "$testcvs -Q update -p -rT $file" v1
dotest update-p-undead-3 "$testcvs -Q rm -f $file" ''
dotest update-p-undead-4 "$testcvs -Q update -p -rT $file" v1
dotest update-p-undead-5 "$testcvs -Q ci -m. $file" \
"Removing $file;
-${TESTDIR}/cvsroot/$module/$file,v <-- $file
+${CVSROOT_DIRNAME}/$module/$file,v <-- $file
new revision: delete; previous revision: 1\.1
done"
dotest update-p-undead-6 "$testcvs -Q update -p -rT $file" v1
echo v2 > $file
dotest update-p-undead-7 "$testcvs -Q update -p -rT $file" v1
dotest update-p-undead-8 "$testcvs add $file" \
-"${PROG} [a-z]*: re-adding file $file (in place of dead revision 1\.2)
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: Re-adding file .$file. (in place of dead revision 1\.2)\.
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest update-p-undead-9 "$testcvs -Q update -p -rT $file" v1
@@ -5892,9 +6760,9 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
cd first-dir
touch file1 file2
dotest tagf-3 "${testcvs} add file1 file2" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest tagf-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -5929,8 +6797,8 @@ done"
# because converting a branch tag to non-branch
# is potentially catastrophic.
dotest tagf-8a "${testcvs} -q tag -F br" \
-"${PROG} [a-z]*: file1: Not moving branch tag .br. from 1\.1\.2\.1 to 1\.1\\.2\.1\.
-${PROG} [a-z]*: file2: Not moving branch tag .br. from 1\.1\.2\.1 to 1\.1\.2\.1\."
+"${PROG} tag: file1: Not moving branch tag .br. from 1\.1\.2\.1 to 1\.1\\.2\.1\.
+${PROG} tag: file2: Not moving branch tag .br. from 1\.1\.2\.1 to 1\.1\.2\.1\."
# however, if we *really* are sure we want to move a branch tag,
# "-F -B" will do the trick
dotest tagf-8 "${testcvs} -q tag -F -B br" "T file1
@@ -5970,7 +6838,7 @@ retrieving revision 1\.1\.2\.1
retrieving revision 1\.1
Merging differences between 1\.1\.2\.1 and 1\.1 into file1
rcsmerge: warning: conflicts during merge
-${PROG} [a-z]*: conflicts found in file1
+${PROG} update: conflicts found in file1
C file1
M file2"
# CVS is giving a conflict because we are trying to get back to
@@ -5994,42 +6862,42 @@ new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
# try accidentally deleting branch tag, "tag -d"
dotest_fail tagf-16 "${testcvs} tag -d br" \
-"${PROG} [a-z]*: Untagging \.
-${PROG} [a-z]*: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file1,v.\.
-${PROG} [a-z]*: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file2,v.\."
+"${PROG} tag: Untagging \.
+${PROG} tag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file1,v.\.
+${PROG} tag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file2,v.\."
# try accidentally deleting branch tag, "rtag -d"
dotest_fail tagf-17 "${testcvs} rtag -d br first-dir" \
-"${PROG} [a-z]*: Untagging first-dir
-${PROG} [a-z]*: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file1,v.\.
-${PROG} [a-z]*: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file2,v.\."
+"${PROG} rtag: Untagging first-dir
+${PROG} rtag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file1,v.\.
+${PROG} rtag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file2,v.\."
# try accidentally converting branch tag to non-branch tag "tag -F"
dotest tagf-18 "${testcvs} tag -r1.1 -F br file1" \
-"${PROG} [a-z]*: file1: Not moving branch tag .br. from 1\.1\.4\.1 to 1\.1\."
+"${PROG} tag: file1: Not moving branch tag .br. from 1\.1\.4\.1 to 1\.1\."
# try accidentally converting branch tag to non-branch tag "rtag -F"
dotest tagf-19 "${testcvs} rtag -r1.1 -F br first-dir" \
-"${PROG} [a-z]*: Tagging first-dir
-${PROG} [a-z]*: first-dir/file1: Not moving branch tag .br. from 1\.1\.4\.1 to 1\.1\.
-${PROG} [a-z]*: first-dir/file2: Not moving branch tag .br. from 1\.1\.2\.2 to 1\.1\."
+"${PROG} rtag: Tagging first-dir
+${PROG} rtag: first-dir/file1: Not moving branch tag .br. from 1\.1\.4\.1 to 1\.1\.
+${PROG} rtag: first-dir/file2: Not moving branch tag .br. from 1\.1\.2\.2 to 1\.1\."
# create a non-branch tag
dotest tagf-20 "${testcvs} rtag regulartag first-dir" \
-"${PROG} [a-z]*: Tagging first-dir"
+"${PROG} rtag: Tagging first-dir"
# try accidentally converting non-branch tag to branch tag (tag -F -B -b)
dotest tagf-21 "${testcvs} tag -F -B -b regulartag file1" \
-"${PROG} [a-z]*: file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1\.0\.2 due to .-B. option\."
+"${PROG} tag: file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1\.0\.2 due to .-B. option\."
# try accidentally converting non-branch tag to branch rtag (rtag -F -B -b)
dotest tagf-22 "${testcvs} rtag -F -B -b regulartag first-dir" \
-"${PROG} [a-z]*: Tagging first-dir
-${PROG} [a-z]*: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.0\.6 due to .-B. option\.
-${PROG} [a-z]*: first-dir/file2: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.0\.4 due to .-B. option\."
+"${PROG} rtag: Tagging first-dir
+${PROG} rtag: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.0\.6 due to .-B. option\.
+${PROG} rtag: first-dir/file2: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.0\.4 due to .-B. option\."
# Try accidentally deleting non-branch: (tag -d -B)
dotest_fail tagf-23 "${testcvs} tag -d -B regulartag file1" \
-"${PROG} [a-z]*: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file1,v. due to .-B. option\."
+"${PROG} tag: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file1,v. due to .-B. option\."
# Try accidentally deleting non-branch: (rtag -d -B)
dotest_fail tagf-24 \
"${testcvs} rtag -d -B regulartag first-dir" \
-"${PROG} [a-z]*: Untagging first-dir
-${PROG} [a-z]*: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file1,v. due to .-B. option\.
-${PROG} [a-z]*: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file2,v. due to .-B. option\."
+"${PROG} rtag: Untagging first-dir
+${PROG} rtag: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file1,v. due to .-B. option\.
+${PROG} rtag: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file2,v. due to .-B. option\."
# the following tests (throught the next commit) keep moving the same
# tag back and forth between 1.1.6 & 1.1.8 in file1 and between
@@ -6043,14 +6911,14 @@ ${PROG} [a-z]*: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME
"T file1"
# try intentionally converting mixed tags to branch tags (rtag -F -b)
dotest tagf-26a "${testcvs} rtag -F -b regulartag first-dir" \
-"${PROG} [a-z]*: Tagging first-dir
-${PROG} [a-z]*: first-dir/file1: Not moving branch tag .regulartag. from 1\.1 to 1\.1\.0\.8\."
+"${PROG} rtag: Tagging first-dir
+${PROG} rtag: first-dir/file1: Not moving branch tag .regulartag. from 1\.1 to 1\.1\.0\.8\."
# try intentionally converting a branch to a new branch tag (rtag -F -b -B)
dotest tagf-26b "${testcvs} rtag -F -B -b -r1.1 regulartag first-dir" \
-"${PROG} [a-z]*: Tagging first-dir"
+"${PROG} rtag: Tagging first-dir"
# update to our new branch
dotest tagf-27 "${testcvs} update -r regulartag" \
-"${PROG} [a-z]*: Updating \.
+"${PROG} update: Updating \.
U file1
U file2"
# commit some changes and see that all rev numbers look right
@@ -6071,26 +6939,26 @@ done"
"T file1"
# try non-branch to non-branch (tag -F -B)
dotest tagf-29a "${testcvs} tag -F -B -r br regulartag file1" \
-"${PROG} [a-z]*: file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1 due to .-B. option\."
+"${PROG} tag: file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1 due to .-B. option\."
# try mixed-branch to non-branch (rtag -F -B )
dotest tagf-29b "${testcvs} rtag -F -B -r br regulartag first-dir" \
-"${PROG} [a-z]*: Tagging first-dir
-${PROG} [a-z]*: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1 due to .-B. option\."
+"${PROG} rtag: Tagging first-dir
+${PROG} rtag: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1 due to .-B. option\."
# at this point, regulartag is a regular tag within
# file1 and file2
# try intentional branch to non-branch (rtag -F -B)
dotest tagf-30 "${testcvs} rtag -F -B -r1.1 br first-dir" \
-"${PROG} [a-z]*: Tagging first-dir"
+"${PROG} rtag: Tagging first-dir"
# create a branch tag so we can try to delete it.
dotest tagf-31 "${testcvs} rtag -b brtag first-dir" \
-"${PROG} [a-z]*: Tagging first-dir"
+"${PROG} rtag: Tagging first-dir"
# try intentinal deletion of branch tag (tag -d -B)
dotest tagf-32 "${testcvs} tag -d -B brtag file1" "D file1"
# try intentinal deletion of branch tag (rtag -d -B)
dotest tagf-33 "${testcvs} rtag -d -B brtag first-dir" \
-"${PROG} [a-z]*: Untagging first-dir"
+"${PROG} rtag: Untagging first-dir"
cd ../..
@@ -6110,8 +6978,8 @@ ${PROG} [a-z]*: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.
cd first-dir
echo "I am the first foo, and my name is $""Name$." > foo.c
dotest rcsdiff-2 "${testcvs} add -m new-file foo.c" \
-"${PROG} [a-z]*: scheduling file .foo\.c. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .foo\.c. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest rcsdiff-3 "${testcvs} commit -m rev1 foo.c" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v
done
@@ -6144,7 +7012,7 @@ VERS: 1\.2
I am the second foo, and my name is \$""Name: second \$\."
dotest_fail rcsdiff-9 "${testcvs} diff -r first -r second" \
-"${PROG} [a-z]*: Diffing \.
+"${PROG} diff: Diffing \.
Index: foo\.c
===================================================================
RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v
@@ -6158,7 +7026,7 @@ diff -r1\.1 -r1\.2
echo "I am the once and future foo, and my name is $""Name$." > foo.c
dotest_fail rcsdiff-10 "${testcvs} diff -r first" \
-"${PROG} [a-z]*: Diffing \.
+"${PROG} diff: Diffing \.
Index: foo\.c
===================================================================
RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v
@@ -6186,7 +7054,7 @@ grumble;
EOF
dotest rcslib-diffrgx-1 "${testcvs} -q add -m '' rgx.c" \
-"${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: use .${PROG} commit. to add this file permanently"
dotest rcslib-diffrgx-2 "${testcvs} -q ci -m '' rgx.c" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/rgx\.c,v
done
@@ -6250,7 +7118,7 @@ diff -c -F\.\*( -r1\.1 rgx\.c
echo '2' >> file1
echo '3' >> file1
dotest rcslib-merge-4 "${testcvs} -q add file1" \
-"${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: use .${PROG} commit. to add this file permanently"
dotest rcslib-merge-5 "${testcvs} -q commit -m '' file1" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -6304,7 +7172,15 @@ two
[>]>>>>>> 1\.2"
# Test behavior of symlinks in the repository.
- dotest rcslib-symlink-1 "ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v"
+ if test -n "$remotehost"; then
+ # Create the link on the remote system. This is because Cygwin's
+ # Windows support creates *.lnk files for Windows. When creating
+ # these in an SMB share from UNIX, these links won't work from the
+ # UNIX side.
+ dotest rcslib-symlink-1remotehost "${CVS_RSH} $remotehost 'ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v'"
+ else
+ dotest rcslib-symlink-1 "ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v"
+ fi
dotest rcslib-symlink-2 "${testcvs} update file2" "U file2"
echo "This is a change" >> file2
dotest rcslib-symlink-3 "${testcvs} ci -m because file2" \
@@ -6312,19 +7188,22 @@ two
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file2
new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
- dotest rcslib-symlink-4 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \
+
+ # Switch as for rcslib-symlink-1
+ if test -n "$remotehost"; then
+ dotest rcslib-symlink-4 "$CVS_RSH $remotehost 'ls -l $CVSROOT_DIRNAME/first-dir/file2,v'" \
+".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v"
+ else
+ dotest rcslib-symlink-4 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \
".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v"
+ fi
# CVS was failing to check both the symlink and the file
# for timestamp changes for a while. Test that.
rm file1
- if $remote; then
- dotest rcslib-symlink-3ar "${testcvs} -q up file1" "U file1"
- else
- dotest rcslib-symlink-3a "${testcvs} -q up file1" \
-"${PROG} [a-z]*: warning: file1 was lost
+ dotest rcslib-symlink-3a "${testcvs} -q up file1" \
+"${PROG} update: warning: file1 was lost
U file1"
- fi
echo "This is a change" >> file1
dotest rcslib-symlink-3b "${testcvs} ci -m because file1" \
"Checking in file1;
@@ -6342,8 +7221,15 @@ Checking in file3;
${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3
new revision: 1\.1\.2\.1; previous revision: 1\.1
done"
+
rm -f ${CVSROOT_DIRNAME}/first-dir/file2,v
- dotest rcslib-symlink-3f "ln -s Attic/file3,v ${CVSROOT_DIRNAME}/first-dir/file2,v"
+ # As for rcslib-symlink-1
+ if test -n "$remotehost"; then
+ dotest rcslib-symlink-3f "$CVS_RSH $remotehost 'ln -s Attic/file3,v ${CVSROOT_DIRNAME}/first-dir/file2,v'"
+ else
+ dotest rcslib-symlink-3f "ln -s Attic/file3,v ${CVSROOT_DIRNAME}/first-dir/file2,v"
+ fi
+
dotest rcslib-symlink-3g "${testcvs} update file2" "U file2"
# restore the link to file1 for the following tests
@@ -6355,7 +7241,12 @@ new revision: delete; previous revision: 1\.1\.2\.1
done"
rm -f ${CVSROOT_DIRNAME}/first-dir/file2,v
rm -f ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
- dotest rcslib-symlink-3h "ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v"
+ # As for rcslib-symlink-1
+ if test -n "$remotehost"; then
+ dotest rcslib-symlink-3h "$CVS_RSH $remotehost 'ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v'"
+ else
+ dotest rcslib-symlink-3h "ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v"
+ fi
# Test 5 reveals a problem with having symlinks in the
# repository. CVS will try to tag both of the files
@@ -6365,11 +7256,17 @@ done"
# changing operations to notice cases like this? This
# strikes me as a difficult problem. -Noel
dotest rcslib-symlink-5 "${testcvs} tag the_tag" \
-"${PROG} [a-z]*: Tagging .
+"${PROG} tag: Tagging .
T file1
W file2 : the_tag already exists on version 1.1.2.3 : NOT MOVING tag to version 1.1.2.1"
- dotest rcslib-symlink-6 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \
+ # As for rcslib-symlink-1
+ if test -n "$remotehost"; then
+ dotest rcslib-symlink-6 "$CVS_RSH $remotehost 'ls -l $CVSROOT_DIRNAME/first-dir/file2,v'" \
+".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v"
+ else
+ dotest rcslib-symlink-6 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \
".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v"
+ fi
# Symlinks tend to interact poorly with the Attic.
cd ..
@@ -6379,8 +7276,8 @@ W file2 : the_tag already exists on version 1.1.2.3 : NOT MOVING tag to version
U first-dir/file2"
cd first-dir
dotest rcslib-symlink-8 "${testcvs} rm -f file2" \
-"${PROG} [a-z]*: scheduling .file2. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file2. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest rcslib-symlink-9 "${testcvs} -q ci -m rm-it" \
"Removing file2;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file2
@@ -6391,9 +7288,9 @@ done"
# Why it happens a third time I didn't try to find out.
dotest rcslib-symlink-10 \
"${testcvs} -q rtag -b -r the_tag brtag first-dir" \
-"${PROG} [a-z]*: could not read RCS file for file2
-${PROG} [a-z]*: could not read RCS file for first-dir/file2
-${PROG} [a-z]*: could not read RCS file for first-dir/file2"
+"${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 ..
@@ -6403,6 +7300,18 @@ ${PROG} [a-z]*: could not read RCS file for first-dir/file2"
exit 0
fi
+ # 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
+ # rm -rf will fail since it doesn't find file2,v and it still gets
+ # directory not empty errors removing cvsroot/first-dir.
+ #
+ # I'm not sure why I need to do this on $remotehost. The rm above
+ # 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"
+ fi
rm -rf ${CVSROOT_DIRNAME}/first-dir
rm -r first-dir 2
;;
@@ -6415,8 +7324,8 @@ ${PROG} [a-z]*: could not read RCS file for first-dir/file2"
cd first-dir
echo 1:trunk-1 >file1
dotest multibranch-2 "${testcvs} add file1" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file1'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest_lit multibranch-3 "${testcvs} -q ci -m add-it" <<HERE
RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -6426,10 +7335,10 @@ initial revision: 1.1
done
HERE
dotest multibranch-4 "${testcvs} tag -b br1" \
-"${PROG} [a-z]*: Tagging \.
+"${PROG} tag: Tagging \.
T file1"
dotest multibranch-5 "${testcvs} tag -b br2" \
-"${PROG} [a-z]*: Tagging \.
+"${PROG} tag: Tagging \.
T file1"
dotest multibranch-6 "${testcvs} -q update -r br1" ''
echo on-br1 >file1
@@ -6504,6 +7413,7 @@ modify-on-br1
# info -- imports which are rejected by verifymsg
# 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
mkdir import-dir ; cd import-dir
@@ -6552,8 +7462,8 @@ U first-dir/imported-f4"
# remove
rm imported-f1
dotest import-99 "${testcvs} rm imported-f1" \
-"${PROG}"' [a-z]*: scheduling `imported-f1'\'' for removal
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove this file permanently'
+"${PROG}"' remove: scheduling `imported-f1'\'' for removal
+'"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently'
# change
echo local-change >> imported-f2
@@ -6602,15 +7512,15 @@ first-import
# update into the vendor branch.
dotest import-102 "${testcvs} update -rvendor-branch" \
-"${PROG} [a-z]*: Updating .
+"${PROG} update: Updating .
[UP] imported-f1
[UP] imported-f2"
# remove file4 on the vendor branch
rm imported-f4
dotest import-103 "${testcvs} rm imported-f4" \
-"${PROG}"' [a-z]*: scheduling `imported-f4'\'' for removal
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove this file permanently'
+"${PROG}"' remove: scheduling `imported-f4'\'' for removal
+'"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently'
# commit
dotest import-104 \
@@ -6622,7 +7532,7 @@ done"
# update to main line
dotest import-105 "${testcvs} -q update -A" \
-"${PROG} [a-z]*: imported-f1 is no longer in the repository
+"${PROG} update: imported-f1 is no longer in the repository
[UP] imported-f2"
# second import - file4 deliberately unchanged
@@ -6655,7 +7565,7 @@ Use the following command to help the merge:"
# co
dotest import-107 "${testcvs} co first-dir" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} checkout: Updating first-dir
[UP] first-dir/imported-f3
[UP] first-dir/imported-f4"
@@ -6676,19 +7586,21 @@ Use the following command to help the merge:"
# update to main line
dotest import-112 "${testcvs} -q update -A" \
-"${PROG} [a-z]*: imported-f1 is no longer in the repository
+"${PROG} update: imported-f1 is no longer in the repository
[UP] imported-f2"
cd ..
dotest import-113 \
"${testcvs} -q co -jjunk-1_0 -jjunk-2_0 first-dir" \
-"${PROG} [a-z]*: file first-dir/imported-f1 does not exist, but is present in revision junk-2_0
+"${PROG} checkout: file first-dir/imported-f1 does not exist, but is present in revision junk-2_0
RCS file: ${CVSROOT_DIRNAME}/first-dir/imported-f2,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 imported-f2
-rcsmerge: warning: conflicts during merge"
+rcsmerge: warning: conflicts during merge
+first-dir/imported-f3 already contains the differences between 1\.1\.1\.1 and 1\.1\.1\.2
+first-dir/imported-f4 already contains the differences between 1\.1\.1\.1 and 1\.1\.1\.3"
cd first-dir
@@ -6835,13 +7747,13 @@ N first-dir/adir/sub2/file2
N first-dir/bdir/subdir/file1
N first-dir/cdir/cfile
No conflicts created by this import
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/first-dir/adir
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub1
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub1/ssdir
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub2
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/first-dir/bdir
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/first-dir/bdir/subdir
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/first-dir/cdir"
+${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir
+${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub1
+${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub1/ssdir
+${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub2
+${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/bdir
+${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/bdir/subdir
+${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/cdir"
cd ..
mkdir 2; cd 2
dotest importc-2 "${testcvs} -q co first-dir" \
@@ -6852,12 +7764,12 @@ U first-dir/bdir/subdir/file1
U first-dir/cdir/cfile"
cd first-dir
dotest importc-3 "${testcvs} update adir/sub1" \
-"${PROG} [a-z]*: Updating adir/sub1
-${PROG} [a-z]*: Updating adir/sub1/ssdir"
+"${PROG} update: Updating adir/sub1
+${PROG} update: Updating adir/sub1/ssdir"
dotest importc-4 "${testcvs} update adir/sub1 bdir/subdir" \
-"${PROG} [a-z]*: Updating adir/sub1
-${PROG} [a-z]*: Updating adir/sub1/ssdir
-${PROG} [a-z]*: Updating bdir/subdir"
+"${PROG} update: Updating adir/sub1
+${PROG} update: Updating adir/sub1/ssdir
+${PROG} update: Updating bdir/subdir"
echo modify >>cdir/cfile
dotest importc-5 \
@@ -6944,6 +7856,42 @@ import-it
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ import-CVS)
+ mkdir import-CVS
+ cd import-CVS
+ touch file1 file2 file3
+ dotest_fail import-CVS-1 "$testcvs import CVS vtag rtag" \
+"$PROG import: The word \`CVS' is reserved by CVS and may not be used
+$PROG \[import aborted\]: as a directory in a path or as a file name\."
+ mkdir sdir
+ mkdir sdir/CVS
+ touch sdir/CVS/file4 sdir/CVS/file5 sdir/file6 sdir/file7
+ # Calling the imported directory import-CVS is dual purpose in the
+ # following test. It makes sure the path test which matched above
+ # wasn't too strict.
+ dotest_sort import-CVS-2 \
+"$testcvs import -I! -mimport import-CVS vtag rtag" \
+"
+
+I import-CVS/sdir/CVS
+N import-CVS/file1
+N import-CVS/file2
+N import-CVS/file3
+N import-CVS/sdir/file6
+N import-CVS/sdir/file7
+No conflicts created by this import
+$PROG import: Importing $CVSROOT_DIRNAME/import-CVS/sdir"
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ cd ..
+ rm -r import-CVS
+ rm -rf $CVSROOT_DIRNAME/import-CVS
+ ;;
+
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
@@ -6999,6 +7947,70 @@ done"
rm -rf ${CVSROOT_DIRNAME}/$module
;;
+ branch-after-import)
+ # Test branching after an import via both cvs tag -b and
+ # cvs add to verify that the HEAD remains at 1.1.1.1
+ # This was a FreeBSD bug documented at the URL:
+ # http://www.freebsd.org/cgi/query-pr.cgi?pr=4033
+
+ mkdir branch-after-import
+ cd branch-after-import
+
+ # OK, first we get some sources from the NetMunger project,
+ # and import them into the 1.1.1 vendor branch.
+ mkdir imp-dir
+ cd imp-dir
+ echo 'OpenMunger sources' >file1
+ echo 'OpenMunger sources' >file2
+ dotest_sort branch-after-import-1 \
+"${testcvs} import -m add first-dir openmunger openmunger-1_0" \
+'
+
+N first-dir/file1
+N first-dir/file2
+No conflicts created by this import'
+ cd ..
+
+ # Next checkout the new module
+ dotest branch-after-import-2 \
+"${testcvs} -q co first-dir" \
+'U first-dir/file1
+U first-dir/file2'
+ cd first-dir
+ # Branch tag the file1 and cvs add file2,
+ # the branch should remain the same in both cases
+ # such that a new import will not require a conflict
+ # resolution.
+ dotest branch-after-import-3 \
+"${testcvs} tag -b TESTTOTRON file1" \
+'T file1'
+ dotest branch-after-import-4 \
+"${testcvs} -q update -r TESTTOTRON" \
+"${PROG} update: file2 is no longer in the repository"
+
+ cp ../imp-dir/file2 .
+ dotest branch-after-import-5 \
+"${testcvs} add file2" \
+"${PROG} add: scheduling file .file2. for addition on branch .TESTTOTRON.
+${PROG} add: use .${PROG} commit. to add this file permanently"
+
+ dotest branch-after-import-6 \
+"${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
+done"
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ rm -r branch-after-import
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
join)
# Test doing joins which involve adding and removing files.
# Variety of scenarios (see list below), in the context of:
@@ -7043,9 +8055,13 @@ done"
# Nothing should happen.
# 6) File removed between T1 and T2, also removed on main line.
# Nothing should happen.
- # 7) File added on main line, not added between T1 and T2.
+ # 7) File not added between T1 and T2, added on main line.
# Nothing should happen.
- # 8) File removed on main line, not modified between T1 and T2.
+ # 8) File not modified between T1 and T2, removed on main line.
+ # Nothing should happen.
+ # 9) File modified between T1 and T2, removed on main line.
+ # Conflict.
+ # 10) File was never on branch, removed on main line.
# Nothing should happen.
# We also check merging changes from a branch into the main
@@ -7066,6 +8082,10 @@ done"
# Nothing should happen.
# 8) File removed on main line, not modified on branch.
# Nothing should happen.
+ # 9) File modified on branch, removed on main line.
+ # Conflict.
+ # 10) File was never on branch, removed on main line.
+ # Nothing should happen.
# In the tests below, fileN represents case N in the above
# lists.
@@ -7082,12 +8102,14 @@ done"
echo 'first revision of file4' > file4
echo 'first revision of file6' > file6
echo 'first revision of file8' > file8
- dotest join-2 "${testcvs} add file3 file4 file6 file8" \
-"${PROG}"' [a-z]*: scheduling file `file3'\'' for addition
-'"${PROG}"' [a-z]*: scheduling file `file4'\'' for addition
-'"${PROG}"' [a-z]*: scheduling file `file6'\'' for addition
-'"${PROG}"' [a-z]*: scheduling file `file8'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add these files permanently'
+ echo 'first revision of file9' > file9
+ dotest join-2 "${testcvs} add file3 file4 file6 file8 file9" \
+"${PROG}"' add: scheduling file `file3'\'' for addition
+'"${PROG}"' add: scheduling file `file4'\'' for addition
+'"${PROG}"' add: scheduling file `file6'\'' for addition
+'"${PROG}"' add: scheduling file `file8'\'' for addition
+'"${PROG}"' add: scheduling file `file9'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently'
dotest join-3 "${testcvs} -q commit -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v
@@ -7113,6 +8135,12 @@ done
Checking in file8;
${CVSROOT_DIRNAME}/first-dir/file8,v <-- file8
initial revision: 1\.1
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file9,v
+done
+Checking in file9;
+${CVSROOT_DIRNAME}/first-dir/file9,v <-- file9
+initial revision: 1\.1
done"
# Make a branch.
@@ -7120,23 +8148,34 @@ done"
'T file3
T file4
T file6
-T file8'
+T file8
+T file9'
- # Add file2 and file7, modify file4, and remove file6 and file8.
+ # Add file2, file7, and file10, modify file4, and remove
+ # file6, file8, and file9.
echo 'first revision of file2' > file2
echo 'second revision of file4' > file4
echo 'first revision of file7' > file7
- rm file6 file8
- dotest join-5 "${testcvs} add file2 file7" \
-"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition
-'"${PROG}"' [a-z]*: scheduling file `file7'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add these files permanently'
- dotest join-6 "${testcvs} rm file6 file8" \
-"${PROG}"' [a-z]*: scheduling `file6'\'' for removal
-'"${PROG}"' [a-z]*: scheduling `file8'\'' for removal
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove these files permanently'
+ rm file6 file8 file9
+ echo 'first revision of file10' > file10
+ dotest join-5 "${testcvs} add file2 file7 file10" \
+"${PROG}"' add: scheduling file `file2'\'' for addition
+'"${PROG}"' add: scheduling file `file7'\'' for addition
+'"${PROG}"' add: scheduling file `file10'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently'
+ dotest join-6 "${testcvs} rm file6 file8 file9" \
+"${PROG}"' remove: scheduling `file6'\'' for removal
+'"${PROG}"' remove: scheduling `file8'\'' for removal
+'"${PROG}"' remove: scheduling `file9'\'' for removal
+'"${PROG}"' remove: use .'"${PROG}"' commit. to remove these files permanently'
dotest join-7 "${testcvs} -q ci -mx ." \
-"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/file10,v
+done
+Checking in file10;
+${CVSROOT_DIRNAME}/first-dir/file10,v <-- file10
+initial revision: 1\.1
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
done
Checking in file2;
${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
@@ -7159,6 +8198,20 @@ done
Removing file8;
${CVSROOT_DIRNAME}/first-dir/file8,v <-- file8
new revision: delete; previous revision: 1\.1
+done
+Removing file9;
+${CVSROOT_DIRNAME}/first-dir/file9,v <-- file9
+new revision: delete; previous revision: 1\.1
+done"
+
+ # Remove file10
+ dotest join-7a "${testcvs} rm -f file10" \
+"${PROG}"' remove: scheduling `file10'\'' for removal
+'"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently'
+ dotest join-7b "${testcvs} -q ci -mx ." \
+"Removing file10;
+${CVSROOT_DIRNAME}/first-dir/file10,v <-- file10
+new revision: delete; previous revision: 1\.1
done"
# Check out the branch.
@@ -7169,7 +8222,8 @@ done"
'U first-dir/file3
U first-dir/file4
U first-dir/file6
-U first-dir/file8'
+U first-dir/file8
+U first-dir/file9'
cd first-dir
@@ -7177,11 +8231,12 @@ U first-dir/file8'
# ancestor of the main line, and add file5
echo 'first branch revision of file3' > file3
echo 'first branch revision of file4' > file4
- echo 'first branch revision of file6' > file6
echo 'first branch revision of file5' > file5
+ echo 'first branch revision of file6' > file6
+ echo 'first branch revision of file9' > file9
dotest join-9 "${testcvs} add file5" \
-"${PROG}"' [a-z]*: scheduling file `file5'\'' for addition on branch `branch'\''
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file5'\'' for addition on branch `branch'\''
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest join-10 "${testcvs} -q ci -mx ." \
"Checking in file3;
${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3
@@ -7200,6 +8255,10 @@ done
Checking in file6;
${CVSROOT_DIRNAME}/first-dir/Attic/file6,v <-- file6
new revision: 1\.1\.2\.1; previous revision: 1\.1
+done
+Checking in file9;
+${CVSROOT_DIRNAME}/first-dir/Attic/file9,v <-- file9
+new revision: 1\.1\.2\.1; previous revision: 1\.1
done"
# Tag the current revisions on the branch.
@@ -7208,22 +8267,24 @@ done"
T file4
T file5
T file6
-T file8'
+T file8
+T file9'
- # Add file1 and file2, and remove the other files.
+ # Add file1 and file2, modify file9, and remove the other files.
echo 'first branch revision of file1' > file1
echo 'first branch revision of file2' > file2
+ echo 'second branch revision of file9' > file9
rm file3 file4 file5 file6
dotest join-12 "${testcvs} add file1 file2" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition on branch `branch'\''
-'"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition on branch `branch'\''
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add these files permanently'
+"${PROG}"' add: scheduling file `file1'\'' for addition on branch `branch'\''
+'"${PROG}"' add: scheduling file `file2'\'' for addition on branch `branch'\''
+'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently'
dotest join-13 "${testcvs} rm file3 file4 file5 file6" \
-"${PROG}"' [a-z]*: scheduling `file3'\'' for removal
-'"${PROG}"' [a-z]*: scheduling `file4'\'' for removal
-'"${PROG}"' [a-z]*: scheduling `file5'\'' for removal
-'"${PROG}"' [a-z]*: scheduling `file6'\'' for removal
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove these files permanently'
+"${PROG}"' remove: scheduling `file3'\'' for removal
+'"${PROG}"' remove: scheduling `file4'\'' for removal
+'"${PROG}"' remove: scheduling `file5'\'' for removal
+'"${PROG}"' remove: scheduling `file6'\'' for removal
+'"${PROG}"' remove: use .'"${PROG}"' commit. to remove these files permanently'
dotest join-14 "${testcvs} -q ci -mx ." \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
done
@@ -7250,13 +8311,18 @@ done
Removing file6;
${CVSROOT_DIRNAME}/first-dir/Attic/file6,v <-- file6
new revision: delete; previous revision: 1\.1\.2\.1
+done
+Checking in file9;
+${CVSROOT_DIRNAME}/first-dir/Attic/file9,v <-- file9
+new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
# Tag the current revisions on the branch.
dotest join-15 "${testcvs} -q tag T2 ." \
'T file1
T file2
-T file8'
+T file8
+T file9'
# Do a checkout with a merge.
cd ../..
@@ -7265,12 +8331,13 @@ T file8'
dotest join-16 "${testcvs} -q co -jT1 -jT2 first-dir" \
'U first-dir/file1
U first-dir/file2
-'"${PROG}"' [a-z]*: file first-dir/file2 exists, but has been added in revision T2
+'"${PROG}"' checkout: file first-dir/file2 exists, but has been added in revision T2
U first-dir/file3
-'"${PROG}"' [a-z]*: scheduling first-dir/file3 for removal
+'"${PROG}"' checkout: scheduling first-dir/file3 for removal
U first-dir/file4
-'"${PROG}"' [a-z]*: scheduling first-dir/file4 for removal
-U first-dir/file7'
+'"${PROG}"' checkout: scheduling first-dir/file4 for removal
+U first-dir/file7
+'"${PROG}"' checkout: file first-dir/file9 does not exist, but is present in revision T2'
# Verify that the right changes have been scheduled.
cd first-dir
@@ -7284,10 +8351,11 @@ R file4'
echo 'third revision of file4' > file4
dotest join-18 "${testcvs} -q update -jT1 -jT2 ." \
'U file1
-'"${PROG}"' [a-z]*: file file2 exists, but has been added in revision T2
-'"${PROG}"' [a-z]*: scheduling file3 for removal
+'"${PROG}"' update: file file2 exists, but has been added in revision T2
+'"${PROG}"' update: scheduling file3 for removal
M file4
-'"${PROG}"' [a-z]*: file file4 is locally modified, but has been removed in revision T2'
+'"${PROG}"' update: file file4 is locally modified, but has been removed in revision T2
+'"${PROG}"' update: file file9 does not exist, but is present in revision T2'
# Verify that the right changes have been scheduled.
dotest join-19 "${testcvs} -q update" \
@@ -7316,10 +8384,11 @@ retrieving revision 1\.1
retrieving revision 1\.1\.2\.1
Merging differences between 1\.1 and 1\.1\.2\.1 into file2
U first-dir/file3
-${PROG} [a-z]*: scheduling first-dir/file3 for removal
+${PROG} checkout: scheduling first-dir/file3 for removal
U first-dir/file4
-${PROG} [a-z]*: file first-dir/file4 has been modified, but has been removed in revision branch
-U first-dir/file7"
+${PROG} checkout: file first-dir/file4 has been modified, but has been removed in revision branch
+U first-dir/file7
+${PROG} checkout: file first-dir/file9 does not exist, but is present in revision branch"
# Verify that the right changes have been scheduled.
# The M file2 line is a bug; see above join-20.
@@ -7349,9 +8418,10 @@ 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
-${PROG} [a-z]*: scheduling file3 for removal
+${PROG} update: scheduling file3 for removal
M file4
-${PROG} [a-z]*: file file4 is locally modified, but has been removed in revision branch"
+${PROG} update: file file4 is locally modified, but has been removed in revision branch
+${PROG} update: file file9 does not exist, but is present in revision branch"
# Verify that the right changes have been scheduled.
# The M file2 line is a bug; see above join-20
@@ -7378,8 +8448,8 @@ T file3
T file4
T file7"
dotest join-27 "${testcvs} -q update -r br2" ""
- # The handling of file8 here looks fishy to me. I don't see
- # why it should be different from the case where we merge to
+ # The handling of file8 and file9 here look fishy to me. I don't
+ # see why it should be different from the case where we merge to
# the trunk (e.g. join-23).
dotest join-28 "${testcvs} -q update -j branch" \
"U file1
@@ -7387,15 +8457,17 @@ 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
-${PROG} [a-z]*: scheduling file3 for removal
-${PROG} [a-z]*: file file4 has been modified, but has been removed in revision branch
-U file8"
+${PROG} update: scheduling file3 for removal
+${PROG} update: file file4 has been modified, but has been removed in revision branch
+U file8
+U file9"
# Verify that the right changes have been scheduled.
dotest join-29 "${testcvs} -q update" \
"A file1
M file2
R file3
-A file8"
+A file8
+A file9"
# Checkout the mainline again to try updating and merging between two
# branches in the same step
@@ -7408,10 +8480,11 @@ A file8"
dotest join-twobranch-1 "${testcvs} -q co -rbranch first-dir" \
'U first-dir/file1
U first-dir/file2
-U first-dir/file8'
+U first-dir/file8
+U first-dir/file9'
cd first-dir
dotest join-twobranch-2 "${testcvs} -q update -rbr2 -jbranch" \
-"$PROG [a-z]*: file1 is no longer in the repository
+"${PROG} update: file1 is no longer in the repository
U file1
U file2
RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
@@ -7419,18 +8492,21 @@ retrieving revision 1\.1
retrieving revision 1\.1\.2\.1
Merging differences between 1\.1 and 1\.1\.2\.1 into file2
U file3
-${PROG} [a-z]*: scheduling file3 for removal
+${PROG} update: scheduling file3 for removal
U file4
-${PROG} [a-z]*: file file4 has been modified, but has been removed in revision branch
+${PROG} update: file file4 has been modified, but has been removed in revision branch
U file7
-${PROG} [a-z]*: file8 is no longer in the repository
-U file8"
+${PROG} update: file8 is no longer in the repository
+U file8
+${PROG} update: file9 is no longer in the repository
+U file9"
# Verify that the right changes have been scheduled.
dotest join-twobranch-3 "${testcvs} -q update" \
"A file1
M file2
R file3
-A file8"
+A file8
+A file9"
# Checkout the mainline again to try merging from the trunk
# to a branch.
@@ -7468,7 +8544,7 @@ T file7'
# Now update branch to T3.
cd ../../2/first-dir
dotest join-34 "${testcvs} -q up -jT3" \
-"${PROG} [a-z]*: file file4 does not exist, but is present in revision T3
+"${PROG} update: file file4 does not exist, but is present in revision T3
U file7"
# Verify that the right changes have been scheduled.
@@ -7508,8 +8584,8 @@ Merging differences between 1\.1 and 1\.2 into file7"
cd first-dir
echo 'initial contents of file1' >file1
dotest join2-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest join2-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -7522,8 +8598,8 @@ done"
echo 'modify on branch' >>file1
touch bradd
dotest join2-6a "${testcvs} add bradd" \
-"${PROG} [a-z]*: scheduling file .bradd. for addition on branch .br1.
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .bradd. for addition on branch .br1.
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest join2-7 "${testcvs} -q ci -m modify" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/bradd,v
done
@@ -7588,10 +8664,10 @@ done"
# CVS, would be a lot of work and I'm not sure this case justifies
# it.
dotest join2-17-circumvent "${testcvs} -q update -A" \
-"${PROG} [a-z]*: bradd is no longer in the repository
+"${PROG} update: bradd is no longer in the repository
[UP] file1"
: dotest join2-17 "${testcvs} -q update -A bradd" \
-"${PROG} [a-z]*: warning: bradd is not (any longer) pertinent"
+"${PROG} update: warning: bradd is not (any longer) pertinent"
dotest join2-18 "${testcvs} -q update -j br1 bradd" "U bradd"
dotest join2-19 "${testcvs} -q status bradd" \
"===================================================================
@@ -7625,8 +8701,8 @@ done"
cd first-dir
echo 'initial contents of file1' >file1
dotest join3-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest join3-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -7649,8 +8725,8 @@ done"
dotest join3-8 "${testcvs} -q update -A" "[UP] file1"
echo 'trunk:line1' > file2
dotest join3-8a "${testcvs} add file2" \
-"${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
echo 'trunk:line1' >>file1
dotest join3-9 "${testcvs} -q ci -m modify" \
"Checking in file1;
@@ -7668,7 +8744,7 @@ T file2"
# Before we actually have any revision on br2, let's try a join
dotest join3-11 "${testcvs} -q update -r br1" "[UP] file1
-${PROG} [a-z]*: file2 is no longer in the repository"
+${PROG} update: file2 is no longer in the repository"
dotest join3-12 "${testcvs} -q update -j br2" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
retrieving revision 1\.1
@@ -7687,7 +8763,7 @@ trunk:line1
# OK, we'll try the same thing with a revision on br2.
dotest join3-14 "${testcvs} -q update -r br2 file1" \
-"${PROG} [a-z]*: warning: file1 was lost
+"${PROG} update: warning: file1 was lost
U file1" "U file1"
echo 'br2:line1' >>file1
dotest join3-15 "${testcvs} -q ci -m modify file1" \
@@ -7722,6 +8798,500 @@ br2:line1
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ join4)
+ # Like join, but with local (uncommitted) modifications.
+
+ mkdir ${CVSROOT_DIRNAME}/first-dir
+ mkdir 1
+ cd 1
+ dotest join4-1 "${testcvs} -q co first-dir" ''
+
+ cd first-dir
+
+ # Add two files.
+ echo 'first revision of file3' > file3
+ echo 'first revision of file4' > file4
+ echo 'first revision of file6' > file6
+ echo 'first revision of file8' > file8
+ echo 'first revision of file9' > file9
+ dotest join4-2 "${testcvs} add file3 file4 file6 file8 file9" \
+"${PROG}"' add: scheduling file `file3'\'' for addition
+'"${PROG}"' add: scheduling file `file4'\'' for addition
+'"${PROG}"' add: scheduling file `file6'\'' for addition
+'"${PROG}"' add: scheduling file `file8'\'' for addition
+'"${PROG}"' add: scheduling file `file9'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently'
+
+ dotest join4-3 "${testcvs} -q commit -m add" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v
+done
+Checking in file3;
+${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3
+initial revision: 1\.1
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v
+done
+Checking in file4;
+${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4
+initial revision: 1\.1
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v
+done
+Checking in file6;
+${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6
+initial revision: 1\.1
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file8,v
+done
+Checking in file8;
+${CVSROOT_DIRNAME}/first-dir/file8,v <-- file8
+initial revision: 1\.1
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file9,v
+done
+Checking in file9;
+${CVSROOT_DIRNAME}/first-dir/file9,v <-- file9
+initial revision: 1\.1
+done"
+
+ # Make a branch.
+ dotest join4-4 "${testcvs} -q tag -b branch ." \
+'T file3
+T file4
+T file6
+T file8
+T file9'
+
+ # Add file10
+ echo 'first revision of file10' > file10
+ dotest join4-7a "${testcvs} add file10" \
+"${PROG}"' add: scheduling file `file10'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
+ dotest join4-7b "${testcvs} -q ci -mx ." \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/file10,v
+done
+Checking in file10;
+${CVSROOT_DIRNAME}/first-dir/file10,v <-- file10
+initial revision: 1\.1
+done"
+
+ # Add file2 and file7, modify file4, and remove
+ # file6, file8, file9, and file10.
+ echo 'first revision of file2' > file2
+ echo 'second revision of file4' > file4
+ echo 'first revision of file7' > file7
+ rm file6 file8 file9 file10
+ dotest join4-5 "${testcvs} add file2 file7" \
+"${PROG}"' add: scheduling file `file2'\'' for addition
+'"${PROG}"' add: scheduling file `file7'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently'
+ dotest join4-6 "${testcvs} rm file6 file8 file9 file10" \
+"${PROG}"' remove: scheduling `file6'\'' for removal
+'"${PROG}"' remove: scheduling `file8'\'' for removal
+'"${PROG}"' remove: scheduling `file9'\'' for removal
+'"${PROG}"' remove: scheduling `file10'\'' for removal
+'"${PROG}"' remove: use .'"${PROG}"' commit. to remove these files permanently'
+
+ # Check out the branch.
+ cd ../..
+ mkdir 2
+ cd 2
+ dotest join4-8 "${testcvs} -q co -r branch first-dir" \
+'U first-dir/file3
+U first-dir/file4
+U first-dir/file6
+U first-dir/file8
+U first-dir/file9'
+
+ cd first-dir
+
+ # Modify the files on the branch, so that T1 is not an
+ # ancestor of the main line, and add file5
+ echo 'first branch revision of file3' > file3
+ echo 'first branch revision of file4' > file4
+ echo 'first branch revision of file5' > file5
+ echo 'first branch revision of file6' > file6
+ echo 'first branch revision of file9' > file9
+ dotest join4-9 "${testcvs} add file5" \
+"${PROG}"' add: scheduling file `file5'\'' for addition on branch `branch'\''
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
+ dotest join4-10 "${testcvs} -q ci -mx ." \
+"Checking in file3;
+${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done
+Checking in file4;
+${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file5,v
+done
+Checking in file5;
+${CVSROOT_DIRNAME}/first-dir/Attic/file5,v <-- file5
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done
+Checking in file6;
+${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done
+Checking in file9;
+${CVSROOT_DIRNAME}/first-dir/file9,v <-- file9
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done"
+
+ # Tag the current revisions on the branch.
+ dotest join4-11 "${testcvs} -q tag T1 ." \
+'T file3
+T file4
+T file5
+T file6
+T file8
+T file9'
+
+ # Add file1 and file2, modify file9, and remove the other files.
+ echo 'first branch revision of file1' > file1
+ echo 'first branch revision of file2' > file2
+ echo 'second branch revision of file9' > file9
+ rm file3 file4 file5 file6
+ dotest join4-12 "${testcvs} add file1 file2" \
+"${PROG}"' add: scheduling file `file1'\'' for addition on branch `branch'\''
+'"${PROG}"' add: scheduling file `file2'\'' for addition on branch `branch'\''
+'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently'
+ dotest join4-13 "${testcvs} rm file3 file4 file5 file6" \
+"${PROG}"' remove: scheduling `file3'\'' for removal
+'"${PROG}"' remove: scheduling `file4'\'' for removal
+'"${PROG}"' remove: scheduling `file5'\'' for removal
+'"${PROG}"' remove: scheduling `file6'\'' for removal
+'"${PROG}"' remove: use .'"${PROG}"' commit. to remove these files permanently'
+ dotest join4-14 "${testcvs} -q ci -mx ." \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
+done
+Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/Attic/file1,v <-- file1
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done
+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
+Removing file3;
+${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3
+new revision: delete; previous revision: 1\.1\.2\.1
+done
+Removing file4;
+${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4
+new revision: delete; previous revision: 1\.1\.2\.1
+done
+Removing file5;
+${CVSROOT_DIRNAME}/first-dir/Attic/file5,v <-- file5
+new revision: delete; previous revision: 1\.1\.2\.1
+done
+Removing file6;
+${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6
+new revision: delete; previous revision: 1\.1\.2\.1
+done
+Checking in file9;
+${CVSROOT_DIRNAME}/first-dir/file9,v <-- file9
+new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
+done"
+
+ # Tag the current revisions on the branch.
+ dotest join4-15 "${testcvs} -q tag T2 ." \
+'T file1
+T file2
+T file8
+T file9'
+
+ # Modify file4 locally, and do an update with a merge.
+ cd ../../1/first-dir
+ echo 'third revision of file4' > file4
+ dotest join4-18 "${testcvs} -q update -jT1 -jT2 ." \
+'U file1
+R file10
+A file2
+'"${PROG}"' update: file file2 exists, but has been added in revision T2
+'"${PROG}"' update: scheduling file3 for removal
+M file4
+'"${PROG}"' update: file file4 is locally modified, but has been removed in revision T2
+R file6
+A file7
+R file8
+R file9
+'"${PROG}"' update: file file9 does not exist, but is present in revision T2'
+
+ # Verify that the right changes have been scheduled.
+ dotest join4-19 "${testcvs} -q update" \
+'A file1
+R file10
+A file2
+R file3
+M file4
+R file6
+A file7
+R file8
+R file9'
+
+ cd ../..
+
+ rm -r 1 2
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
+ join5)
+ # This test verifies that CVS can handle filenames starting with a
+ # dash (`-') properly. What used to happen was that CVS handled it
+ # just fine, until it went to pass them as arguments to the diff
+ # library, at which point it neglected to pass `--' before the file
+ # list, causing the diff library to attempt to interpret the file
+ # name as an argument.
+ mkdir join5; cd join5
+ mkdir 1; cd 1
+ dotest join5-init-1 "${testcvs} -Q co -l ."
+ mkdir join5
+ dotest join5-init-2 "${testcvs} -Q add join5"
+ cd join5
+ echo "there once was a file from harrisburg" >-file
+ echo "who's existance it seems was quiteabsurd" >>-file
+ dotest join5-init-3 "${testcvs} -Q add -- -file"
+ dotest join5-init-4 "${testcvs} -q ci -minitial" \
+"RCS file: ${CVSROOT_DIRNAME}/join5/-file,v
+done
+Checking in -file;
+${CVSROOT_DIRNAME}/join5/-file,v <-- -file
+initial revision: 1\.1
+done"
+ cd ../..
+
+ mkdir 2; cd 2
+ dotest join5-init-5 "${testcvs} -Q co join5"
+ cd join5
+ echo "it tested for free" >>-file
+ echo "when paid it should be" >>-file
+ dotest join5-init-4 "${testcvs} -q ci -msecond" \
+"Checking in -file;
+${CVSROOT_DIRNAME}/join5/-file,v <-- -file
+new revision: 1\.2; previous revision: 1\.1
+done"
+ cd ../..
+
+ cd 1/join5
+ echo "but maybe it could charge bytheword" >>-file
+ # This is the test that used to spew complaints from diff3:
+ dotest join5 "${testcvs} up" \
+"${PROG} update: Updating \.
+RCS file: ${CVSROOT_DIRNAME}/join5/-file,v
+retrieving revision 1\.1
+retrieving revision 1\.2
+Merging differences between 1\.1 and 1\.2 into -file
+rcsmerge: warning: conflicts during merge
+${PROG} update: conflicts found in -file
+C -file"
+ cd ../..
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ cd ..
+ rm -r join5
+ rm -rf ${CVSROOT_DIRNAME}/join5
+ ;;
+
+ join6)
+ mkdir join6; cd join6
+ mkdir 1; cd 1
+ dotest join6-init-1 "${testcvs} -Q co -l ."
+ mkdir join6
+ dotest join6-init-2 "${testcvs} -Q add join6"
+ cd join6
+ echo aaa >temp.txt
+ echo bbb >>temp.txt
+ echo ccc >>temp.txt
+ dotest join6-1 "${testcvs} -Q add temp.txt"
+ dotest join6-2 "${testcvs} -q commit -minitial temp.txt" \
+"RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v
+done
+Checking in temp\.txt;
+${CVSROOT_DIRNAME}/join6/temp.txt,v <-- temp\.txt
+initial revision: 1\.1
+done"
+ cp temp.txt temp2.txt
+ echo ddd >>temp.txt
+ dotest join6-3 "${testcvs} -q commit -madd temp.txt" \
+"Checking in temp\.txt;
+${CVSROOT_DIRNAME}/join6/temp.txt,v <-- temp\.txt
+new revision: 1\.2; previous revision: 1\.1
+done"
+
+ # The case where the merge target is up-to-date and its base revision
+ # matches the second argument to -j: CVS doesn't bother attempting
+ # the merge since it already knows that the target contains the
+ # change.
+ dotest join6-3.3 "${testcvs} update -j1.1 -j1.2 temp.txt" \
+"temp\.txt already contains the differences between 1\.1 and 1\.2"
+ dotest join6-3.4 "${testcvs} diff temp.txt" ""
+
+ # The case where the merge target is modified but already contains
+ # the change.
+ echo bbb >temp.txt
+ echo ccc >>temp.txt
+ echo ddd >>temp.txt
+ dotest join6-3.5 "${testcvs} update -j1.1 -j1.2 temp.txt" \
+"M temp\.txt
+RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v
+retrieving revision 1\.1
+retrieving revision 1\.2
+Merging differences between 1\.1 and 1\.2 into temp\.txt
+temp\.txt already contains the differences between 1\.1 and 1\.2"
+ dotest_fail join6-3.6 "${testcvs} diff temp.txt" \
+"Index: temp\.txt
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v
+retrieving revision 1\.2
+diff -r1\.2 temp.txt
+1d0
+< aaa"
+
+ cp temp2.txt temp.txt
+ dotest_fail join6-4 "${testcvs} diff temp.txt" \
+"Index: temp.txt
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v
+retrieving revision 1\.2
+diff -r1\.2 temp\.txt
+4d3
+< ddd"
+
+ dotest join6-5 "${testcvs} update -j1.1 -j1.2 temp.txt" \
+"M temp\.txt
+RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v
+retrieving revision 1\.1
+retrieving revision 1\.2
+Merging differences between 1\.1 and 1\.2 into temp\.txt"
+ dotest join6-6 "${testcvs} diff temp.txt" ""
+ mv temp.txt temp3.txt
+ dotest join6-7 "sed 's/ddd/dddd/' < temp3.txt > temp.txt" ""
+ dotest join6-8 "${testcvs} update -j1.1 -j1.2 temp.txt" \
+"M temp\.txt
+RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v
+retrieving revision 1\.1
+retrieving revision 1\.2
+Merging differences between 1\.1 and 1\.2 into temp\.txt
+rcsmerge: warning: conflicts during merge"
+ dotest_fail join6-9 "${testcvs} diff temp.txt" \
+"Index: temp\.txt
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v
+retrieving revision 1\.2
+diff -r1\.2 temp\.txt
+3a4,6
+> <<<<<<< temp\.txt
+> dddd
+> =======
+4a8
+> >>>>>>> 1\.2"
+ cp temp2.txt temp.txt
+ dotest join6-10 "${testcvs} -q ci -m del temp.txt" \
+"Checking in temp\.txt;
+${CVSROOT_DIRNAME}/join6/temp.txt,v <-- temp\.txt
+new revision: 1\.3; previous revision: 1\.2
+done"
+ cp temp3.txt temp.txt
+ dotest_fail join6-11 "${testcvs} diff temp.txt" \
+"Index: temp\.txt
+===================================================================
+RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v
+retrieving revision 1\.3
+diff -r1\.3 temp\.txt
+3a4
+> ddd"
+ dotest join6-12 "${testcvs} update -j1.2 -j1.3 temp.txt" \
+"M temp\.txt
+RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v
+retrieving revision 1\.2
+retrieving revision 1\.3
+Merging differences between 1\.2 and 1\.3 into temp\.txt"
+ dotest join6-13 "${testcvs} diff temp.txt" ""
+
+ # The case where the merge target wasn't created until after the
+ # first tag was applied
+ rm temp2.txt temp3.txt
+ dotest join6-20 "${testcvs} -q tag -r1.1 t1" \
+"T temp.txt"
+ echo xxx >temp2.txt
+ dotest join6-21 "${testcvs} -Q add temp2.txt"
+ dotest join6-22 "${testcvs} -q ci -m." \
+"RCS file: ${CVSROOT_DIRNAME}/join6/temp2.txt,v
+done
+Checking in temp2\.txt;
+${CVSROOT_DIRNAME}/join6/temp2\.txt,v <-- temp2\.txt
+initial revision: 1\.1
+done"
+ dotest join6-23 "${testcvs} -q tag t2" \
+"T temp.txt
+T temp2.txt"
+ echo xxx >>temp.txt
+ dotest join6-24 "${testcvs} -q ci -m." \
+"Checking in temp\.txt;
+${CVSROOT_DIRNAME}/join6/temp.txt,v <-- temp\.txt
+new revision: 1\.4; previous revision: 1\.3
+done"
+ dotest join6-25 "${testcvs} -q up -jt1 -jt2" \
+"RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v
+retrieving revision 1\.1
+retrieving revision 1\.3
+Merging differences between 1\.1 and 1\.3 into temp.txt
+temp.txt already contains the differences between 1\.1 and 1\.3
+temp2.txt already contains the differences between creation and 1\.1"
+
+ # Now for my next trick: delete the file, recreate it, and
+ # try to merge
+ dotest join6-30 "${testcvs} -q rm -f temp2.txt" \
+"${PROG} remove: use .${PROG} commit. to remove this file permanently"
+ dotest join6-31 "${testcvs} -q ci -m. temp2.txt" \
+"Removing temp2\.txt;
+${CVSROOT_DIRNAME}/join6/temp2\.txt,v <-- temp2\.txt
+new revision: delete; previous revision: 1\.1
+done"
+ echo new >temp2.txt
+ # FIXCVS: Local and remote really shouldn't be different and there
+ # really shouldn't be two different status lines for temp2.txt
+ if $remote; then
+ dotest_fail join6-32 "${testcvs} -q up -jt1 -jt2" \
+"? temp2\.txt
+RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v
+retrieving revision 1\.1
+retrieving revision 1\.3
+Merging differences between 1\.1 and 1\.3 into temp.txt
+temp.txt already contains the differences between 1\.1 and 1\.3
+${PROG} update: move away \./temp2\.txt; it is in the way
+C temp2\.txt"
+ else
+ dotest join6-32 "${testcvs} -q up -jt1 -jt2" \
+"RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v
+retrieving revision 1\.1
+retrieving revision 1\.3
+Merging differences between 1\.1 and 1\.3 into temp.txt
+temp.txt already contains the differences between 1\.1 and 1\.3
+${PROG} update: use .${PROG} add. to create an entry for temp2\.txt
+U temp2\.txt
+? temp2\.txt"
+ fi
+
+ cd ../../..
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ rm -r join6
+ rm -rf ${CVSROOT_DIRNAME}/join6
+ ;;
+
join-readonly-conflict)
# Previously, only tests 1 & 11 were being tested. I added the
# intermediate dotest's to try and diagnose a different failure
@@ -7773,7 +9343,7 @@ retrieving revision 1\.1
retrieving revision 1\.1\.2\.1
Merging differences between 1\.1 and 1\.1\.2\.1 into $file
rcsmerge: warning: conflicts during merge
-$PROG [a-z]*: conflicts found in $file
+${PROG} update: conflicts found in $file
C $file"
# restore to the trunk
@@ -7796,7 +9366,7 @@ retrieving revision 1\.1
retrieving revision 1\.1\.2\.1
Merging differences between 1\.1 and 1\.1\.2\.1 into $file
rcsmerge: warning: conflicts during merge
-$PROG [a-z]*: conflicts found in $file
+${PROG} update: conflicts found in $file
C m"
cd ../..
@@ -7905,22 +9475,24 @@ done"
dotest join-admin-2-13 "$testcvs -Q update -r T" '' "${QUESTION} e0"
dotest join-admin-2-14 "$testcvs update -kk -jM1 -jM2" \
-"${PROG} [a-z]*: Updating .
+"${PROG} update: Updating .
U b
U e
RCS file: ${CVSROOT_DIRNAME}/x/e,v
retrieving revision 1\.1
retrieving revision 1\.2
Merging differences between 1\.1 and 1\.2 into e
+e already contains the differences between 1\.1 and 1\.2
${QUESTION} e0" \
"${QUESTION} e0
-${PROG} [a-z]*: Updating .
+${PROG} update: Updating .
U b
U e
RCS file: ${CVSROOT_DIRNAME}/x/e,v
retrieving revision 1\.1
retrieving revision 1\.2
-Merging differences between 1\.1 and 1\.2 into e"
+Merging differences between 1\.1 and 1\.2 into e
+e already contains the differences between 1\.1 and 1\.2"
# Verify that the $Id.$ string is not expanded.
dotest join-admin-2-15 "cat e" '$''Id$'
@@ -7930,6 +9502,183 @@ Merging differences between 1\.1 and 1\.2 into e"
rm -rf ${CVSROOT_DIRNAME}/$module
;;
+ join-rm)
+ # This first half of this test checks that a single-argument merge
+ # from a branch is capable of removing files.
+ #
+ # The second half verifies that an update to another location with an
+ # uncommitted removal will transfer the destination branch of the
+ # removal.
+
+ module=join-rm
+ mkdir $module; cd $module
+
+ dotest join-rm-init-1 "$testcvs -q co -l ." ''
+ mkdir $module
+ dotest join-rm-init-2 "$testcvs -q add $module" \
+"Directory $CVSROOT_DIRNAME/$module added to the repository"
+ cd $module
+
+ # add some files.
+ touch a b c d e f g
+ dotest join-rm-init-3 "$testcvs -Q add a b c d e f g"
+ dotest join-rm-init-4 "$testcvs -Q ci -m add-em" \
+"RCS file: $CVSROOT_DIRNAME/join-rm/a,v
+done
+Checking in a;
+$CVSROOT_DIRNAME/join-rm/a,v <-- a
+initial revision: 1\.1
+done
+RCS file: $CVSROOT_DIRNAME/join-rm/b,v
+done
+Checking in b;
+$CVSROOT_DIRNAME/join-rm/b,v <-- b
+initial revision: 1\.1
+done
+RCS file: $CVSROOT_DIRNAME/join-rm/c,v
+done
+Checking in c;
+$CVSROOT_DIRNAME/join-rm/c,v <-- c
+initial revision: 1\.1
+done
+RCS file: $CVSROOT_DIRNAME/join-rm/d,v
+done
+Checking in d;
+$CVSROOT_DIRNAME/join-rm/d,v <-- d
+initial revision: 1\.1
+done
+RCS file: $CVSROOT_DIRNAME/join-rm/e,v
+done
+Checking in e;
+$CVSROOT_DIRNAME/join-rm/e,v <-- e
+initial revision: 1\.1
+done
+RCS file: $CVSROOT_DIRNAME/join-rm/f,v
+done
+Checking in f;
+$CVSROOT_DIRNAME/join-rm/f,v <-- f
+initial revision: 1\.1
+done
+RCS file: $CVSROOT_DIRNAME/join-rm/g,v
+done
+Checking in g;
+$CVSROOT_DIRNAME/join-rm/g,v <-- g
+initial revision: 1\.1
+done"
+
+ # create the branch and update to it
+ dotest join-rm-init-5 "$testcvs -Q tag -b br"
+ dotest join-rm-init-6 "$testcvs -Q up -rbr"
+
+ # remove a few files from the branch
+ dotest join-rm-init-7 "$testcvs -Q rm -f b d g"
+ dotest join-rm-init-8 "$testcvs -Q ci -mrm" \
+"Removing b;
+$CVSROOT_DIRNAME/join-rm/b,v <-- b
+new revision: delete; previous revision: 1\.1
+done
+Removing d;
+$CVSROOT_DIRNAME/join-rm/d,v <-- d
+new revision: delete; previous revision: 1\.1
+done
+Removing g;
+$CVSROOT_DIRNAME/join-rm/g,v <-- g
+new revision: delete; previous revision: 1\.1
+done"
+
+ # update to the trunk
+ dotest join-rm-init-9 "$testcvs -Q up -A"
+
+ # now for the test - try and merge the removals.
+ dotest join-rm-1 "$testcvs -q up -jbr" \
+"$PROG update: scheduling b for removal
+$PROG update: scheduling d for removal
+$PROG update: scheduling g for removal"
+
+ # And make sure the merge took
+ dotest join-rm-2 "$testcvs -qn up" \
+"R b
+R d
+R g"
+
+ dotest join-rm-3 "$testcvs -q ci -m 'save the merge'" \
+"Removing b;
+$CVSROOT_DIRNAME/join-rm/b,v <-- b
+new revision: delete; previous revision: 1\.1
+done
+Removing d;
+$CVSROOT_DIRNAME/join-rm/d,v <-- d
+new revision: delete; previous revision: 1\.1
+done
+Removing g;
+$CVSROOT_DIRNAME/join-rm/g,v <-- g
+new revision: delete; previous revision: 1\.1
+done"
+
+ # and verify that it was the head revision which was removed.
+ dotest join-rm-4 "$testcvs -q log b" "
+RCS file: $CVSROOT_DIRNAME/join-rm/Attic/b,v
+Working file: b
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ br: 1\.1\.0\.2
+keyword substitution: kv
+total revisions: 3; selected revisions: 3
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: ${PLUS}0 -0
+save the merge
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+branches: 1.1.2;
+add-em
+----------------------------
+revision 1\.1\.2\.1
+date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: ${PLUS}0 -0
+rm
+============================================================================="
+
+ # go back to the branch to set up for the second set of tests
+ dotest join-rm-init-10 "$testcvs -Q up -rbr"
+ dotest join-rm-init-11 "$testcvs -Q rm -f a"
+ dotest join-rm-init-12 "$testcvs -Q ci -m rma" \
+"Removing a;
+$CVSROOT_DIRNAME/join-rm/a,v <-- a
+new revision: delete; previous revision: 1\.1
+done"
+
+ # now the test: update to the trunk
+ #
+ # FIXCVS: This update should merge the removal to the trunk. It does
+ # not.
+ dotest join-rm-5 "$testcvs -q up -A" "U a"
+
+ # and verify that there is no sticky tag
+ dotest join-rm-6 "$testcvs status a" \
+"===================================================================
+File: a Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 $CVSROOT_DIRNAME/join-rm/a,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ rm -rf $CVSROOT_DIRNAME/$module
+ rm -r $module
+ ;;
+
new) # look for stray "no longer pertinent" messages.
mkdir ${CVSROOT_DIRNAME}/first-dir
@@ -7998,8 +9747,8 @@ Merging differences between 1\.1 and 1\.2 into e"
cd first-dir
touch a
dotest newb-123b "${testcvs} add a" \
-"${PROG} [a-z]*: scheduling file .a. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .a. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest newb-123c "${testcvs} -q ci -m added" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v
done
@@ -8028,12 +9777,12 @@ done"
cd first-dir
rm a
dotest newb-123g "${testcvs} rm a" \
-"${PROG} [a-z]*: scheduling .a. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .a. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest newb-123h "${testcvs} -q ci -m removed" \
"Removing a;
${CVSROOT_DIRNAME}/first-dir/a,v <-- a
-new revision: delete; previous revision: 1\.1\.2
+new revision: delete; previous revision: 1\.1
done"
# Check out the file on the branch. This should report
@@ -8042,14 +9791,14 @@ done"
cd ..
rm -r first-dir
dotest newb-123i "${testcvs} -q co -r branch first-dir/a" \
-"${PROG} [a-z]*: warning: first-dir/a is not (any longer) pertinent"
+"${PROG} checkout: warning: first-dir/a is not (any longer) pertinent"
# Update the other copy, and make sure that a is removed.
cd ../1/first-dir
# "Entry Invalid" is a rather strange output here. Something like
# "Removed in Repository" would make more sense.
dotest newb-123j0 "${testcvs} status a" \
-"${PROG} [a-z]*: a is no longer in the repository
+"${PROG} status: a is no longer in the repository
===================================================================
File: a Status: Entry Invalid
@@ -8059,7 +9808,7 @@ File: a Status: Entry Invalid
Sticky Date: (none)
Sticky Options: (none)"
dotest newb-123j "${testcvs} -q update" \
-"${PROG} [a-z]*: a is no longer in the repository"
+"${PROG} update: a is no longer in the repository"
if test -f a; then
fail newb-123k
@@ -8084,8 +9833,8 @@ File: a Status: Entry Invalid
touch a
dotest conflicts-125 "${testcvs} add a" \
-"${PROG} [a-z]*: scheduling file .a. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .a. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest conflicts-126 "${testcvs} -q ci -m added" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v
done
@@ -8099,7 +9848,7 @@ done"
cd 2
dotest conflicts-126.5 "${testcvs} co -p first-dir" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} checkout: Updating first-dir
===================================================================
Checking out first-dir/a
RCS: ${CVSROOT_DIRNAME}/first-dir/a,v
@@ -8134,7 +9883,7 @@ done"
mkdir 3
cd 3
dotest conflicts-128.5 "${testcvs} co -p -l first-dir" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} checkout: Updating first-dir
===================================================================
Checking out first-dir/a
RCS: ${CVSROOT_DIRNAME}/first-dir/a,v
@@ -8149,8 +9898,8 @@ add a line"
cd 2/first-dir
echo add a conflicting line >>a
dotest_fail conflicts-129 "${testcvs} -q ci -m changed" \
-"${PROG}"' [a-z]*: Up-to-date check failed for `a'\''
-'"${PROG}"' \[[a-z]* aborted\]: correct above errors first!'
+"${PROG}"' commit: Up-to-date check failed for `a'\''
+'"${PROG}"' \[commit aborted\]: correct above errors first!'
mkdir dir1
mkdir sdir
dotest conflicts-status-0 "${testcvs} status a" \
@@ -8168,7 +9917,7 @@ retrieving revision 1\.1
retrieving revision 1\.2
Merging differences between 1\.1 and 1\.2 into a
rcsmerge: warning: conflicts during merge
-${PROG} [a-z]*: conflicts found in a
+${PROG} update: conflicts found in a
C a"
dotest conflicts-130 "${testcvs} -q update" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v
@@ -8176,7 +9925,7 @@ retrieving revision 1\.1
retrieving revision 1\.2
Merging differences between 1\.1 and 1\.2 into a
rcsmerge: warning: conflicts during merge
-${PROG} [a-z]*: conflicts found in a
+${PROG} update: conflicts found in a
C a
${QUESTION} dir1
${QUESTION} sdir" \
@@ -8187,7 +9936,7 @@ retrieving revision 1\.1
retrieving revision 1\.2
Merging differences between 1\.1 and 1\.2 into a
rcsmerge: warning: conflicts during merge
-${PROG} [a-z]*: conflicts found in a
+${PROG} update: conflicts found in a
C a"
rmdir dir1 sdir
@@ -8201,23 +9950,23 @@ File: a Status: File had conflicts on merge
Sticky Date: (none)
Sticky Options: (none)"
dotest_fail conflicts-131 "${testcvs} -q ci -m try" \
-"${PROG} [a-z]*: file .a. had a conflict and has not been modified
-${PROG} \[[a-z]* aborted\]: correct above errors first!"
+"${PROG} commit: file .a. had a conflict and has not been modified
+${PROG} \[commit aborted\]: correct above errors first!"
# Try to check in the file with the conflict markers in it.
# Make sure we detect any one of the three conflict markers
mv a aa
grep '^<<<<<<<' aa >a
dotest conflicts-status-2 "${testcvs} -nq ci -m try a" \
-"${PROG} [a-z]*: warning: file .a. seems to still contain conflict indicators"
+"${PROG} commit: warning: file .a. seems to still contain conflict indicators"
grep '^=======' aa >a
dotest conflicts-status-3 "${testcvs} -nq ci -m try a" \
-"${PROG} [a-z]*: warning: file .a. seems to still contain conflict indicators"
+"${PROG} commit: warning: file .a. seems to still contain conflict indicators"
grep '^>>>>>>>' aa >a
dotest conflicts-status-4 "${testcvs} -qn ci -m try a" \
-"${PROG} [a-z]*: warning: file .a. seems to still contain conflict indicators"
+"${PROG} commit: warning: file .a. seems to still contain conflict indicators"
mv aa a
echo lame attempt at resolving it >>a
@@ -8231,7 +9980,7 @@ File: a Status: File had conflicts on merge
Sticky Date: (none)
Sticky Options: (none)"
dotest conflicts-132 "${testcvs} -q ci -m try" \
-"${PROG} [a-z]*: warning: file .a. seems to still contain conflict indicators
+"${PROG} commit: warning: file .a. seems to still contain conflict indicators
Checking in a;
${CVSROOT_DIRNAME}/first-dir/a,v <-- a
new revision: 1\.3; previous revision: 1\.2
@@ -8350,9 +10099,9 @@ File: a Status: Up-to-date
touch a abc
dotest conflicts2-142a2 "${testcvs} add a abc" \
-"${PROG} [a-z]*: scheduling file .a. for addition
-${PROG} [a-z]*: scheduling file .abc. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .a. for addition
+${PROG} add: scheduling file .abc. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest conflicts2-142a3 "${testcvs} -q ci -m added" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v
done
@@ -8391,52 +10140,51 @@ done"
cd ../../2/first-dir
rm a
dotest conflicts2-142b3 "${testcvs} rm a" \
-"${PROG} [a-z]*: scheduling .a. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .a. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest_fail conflicts2-142b4 "${testcvs} -q update" \
-"${PROG} [a-z]*: conflict: removed a was modified by second party
+"${PROG} update: conflict: removed a was modified by second party
C a"
# Resolve the conflict by deciding not to remove the file
# after all.
- dotest conflicts2-142b5 "${testcvs} add a" "U a
-${PROG} [a-z]*: a, version 1\.1, resurrected"
- dotest conflicts2-142b6 "${testcvs} -q update" ''
+ dotest_sort conflicts2-142b5 "${testcvs} add a" "U a
+${PROG} add: a, version 1\.1, resurrected"
+ dotest conflicts2-142b5b1 "$testcvs status a" \
+"===================================================================
+File: a Status: Needs Patch
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/a,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest conflicts2-142b6 "${testcvs} -q update" 'U a'
# Now one level up.
cd ..
dotest conflicts2-142b7 "${testcvs} rm -f first-dir/a" \
-"${PROG} [a-z]*: scheduling .first-dir/a. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .first-dir/a. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
if $remote; then
# Haven't investigated this one.
- dotest_fail conflicts2-142b8 "${testcvs} add first-dir/a" \
+ dotest_fail conflicts2-142b8r "$testcvs add first-dir/a" \
"${PROG} add: in directory \.:
${PROG} \[add aborted\]: there is no version here; do '${PROG} checkout' first"
cd first-dir
else
- # The "nothing known" is a bug. Correct behavior is for a to get
- # created, as above. Cause is pretty obvious - add.c
- # calls update() without dealing with the fact we are chdir'd.
- # Also note that resurrecting 1.2 instead of 1.1 is also a
- # bug, I think (the same part of add.c has a comment which says
- # "XXX - bugs here; this really resurrect the head" which
- # presumably refers to this).
- # The fix for both is presumably to call RCS_checkout() or
- # something other than update().
dotest conflicts2-142b8 "${testcvs} add first-dir/a" \
-"${PROG} [a-z]*: nothing known about first-dir
-${PROG} [a-z]*: first-dir/a, version 1\.2, resurrected"
+"U first-dir/a
+${PROG} add: first-dir/a, version 1\.2, resurrected"
cd first-dir
# Now recover from the damage that the 142b8 test did.
dotest conflicts2-142b9 "${testcvs} rm -f a" \
-"${PROG} [a-z]*: scheduling .a. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .a. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
fi
- # As before, 1.2 instead of 1.1 is a bug.
- dotest conflicts2-142b10 "${testcvs} add a" "U a
-${PROG} [a-z]*: a, version 1\.2, resurrected"
+ dotest_sort conflicts2-142b10 "${testcvs} add a" "U a
+${PROG} add: a, version 1\.2, resurrected"
# As with conflicts2-142b6, check that things are normal again.
dotest conflicts2-142b11 "${testcvs} -q update" ''
cd ../..
@@ -8448,8 +10196,8 @@ ${PROG} [a-z]*: a, version 1\.2, resurrected"
cd 1/first-dir
rm abc
dotest conflicts2-142c0 "${testcvs} rm abc" \
-"${PROG} [a-z]*: scheduling .abc. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .abc. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest conflicts2-142c1 "${testcvs} -q ci -m remove-abc" \
"Removing abc;
${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc
@@ -8458,10 +10206,10 @@ done"
cd ../../2/first-dir
rm abc
dotest conflicts2-142c2 "${testcvs} rm abc" \
-"${PROG} [a-z]*: scheduling .abc. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .abc. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest conflicts2-142c3 "${testcvs} update" \
-"${PROG} [a-z]*: Updating \."
+"${PROG} update: Updating \."
cd ../..
# conflicts2-142d*: test that if one party adds a file, and another
@@ -8470,9 +10218,9 @@ ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
touch aa.c
echo 'contents unchanged' >same.c
dotest conflicts2-142d0 "${testcvs} add aa.c same.c" \
-"${PROG} [a-z]*: scheduling file .aa\.c. for addition
-${PROG} [a-z]*: scheduling file .same\.c. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .aa\.c. for addition
+${PROG} add: scheduling file .same\.c. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest conflicts2-142d1 "${testcvs} -q ci -m added" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa\.c,v
done
@@ -8511,7 +10259,7 @@ C aa\.c
U same\.c"
fi
dotest conflicts2-142d3 "${testcvs} -q status aa.c" \
-"${PROG} [a-z]*: move away aa\.c; it is in the way
+"${PROG} status: move away aa\.c; it is in the way
===================================================================
File: aa\.c Status: Unresolved Conflict
@@ -8524,7 +10272,7 @@ File: aa\.c Status: Unresolved Conflict
# means that we get to work in parallel if we choose, right? And
# then at commit time it would be a conflict.
dotest_fail conflicts2-142d4 "${testcvs} -q add aa.c" \
-"${PROG} [a-z]*: aa.c added independently by second party"
+"${PROG} add: aa.c added independently by second party"
# The user might want to see just what the conflict is.
# Don't bother, diff seems to kind of lose its mind, with or
@@ -8548,7 +10296,7 @@ File: aa\.c Status: Unresolved Conflict
cd ../..
- rm -r 1 2 ; rm -rf ${CVSROOT_DIRNAME}/first-dir
+ rm -r 1 2; rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
conflicts3)
@@ -8566,9 +10314,9 @@ File: aa\.c Status: Unresolved Conflict
cd ../1/first-dir
touch file1 file2
dotest conflicts3-4 "${testcvs} add file1 file2" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest conflicts3-5 "${testcvs} -q ci -m add-them" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -8596,9 +10344,9 @@ U file2"
# OK, now remove two files at once
dotest conflicts3-10 "${testcvs} rm -f file1 file2" \
-"${PROG} [a-z]*: scheduling .file1. for removal
-${PROG} [a-z]*: scheduling .file2. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove these files permanently"
+"${PROG} remove: scheduling .file1. for removal
+${PROG} remove: scheduling .file2. for removal
+${PROG} remove: use .${PROG} commit. to remove these files permanently"
dotest conflicts3-11 "${testcvs} -q ci -m remove-them" \
"Removing file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
@@ -8610,11 +10358,11 @@ new revision: delete; previous revision: 1\.1
done"
cd ../../1/first-dir
dotest conflicts3-12 "${testcvs} -n -q update" \
-"${PROG} [a-z]*: file1 is no longer in the repository
-${PROG} [a-z]*: file2 is no longer in the repository"
+"${PROG} update: file1 is no longer in the repository
+${PROG} update: file2 is no longer in the repository"
dotest conflicts3-13 "${testcvs} -q update" \
-"${PROG} [a-z]*: file1 is no longer in the repository
-${PROG} [a-z]*: file2 is no longer in the repository"
+"${PROG} update: file1 is no longer in the repository
+${PROG} update: file2 is no longer in the repository"
# OK, now add a directory to both working directories
# and see that CVS doesn't lose its mind.
@@ -8623,8 +10371,8 @@ ${PROG} [a-z]*: file2 is no longer in the repository"
"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository"
touch sdir/sfile
dotest conflicts3-14a "${testcvs} add sdir/sfile" \
-"${PROG} [a-z]*: scheduling file .sdir/sfile. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .sdir/sfile. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest conflicts3-14b "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/sfile,v
done
@@ -8652,15 +10400,15 @@ done"
else
dotest conflicts3-15 "${testcvs} -q update" \
"${QUESTION} sdir
-${PROG} [a-z]*: ignoring sdir (CVS/Repository missing)"
+${PROG} update: ignoring sdir (CVS/Repository missing)"
touch sdir/CVS/Repository
dotest conflicts3-16 "${testcvs} -q update" \
"${QUESTION} sdir
-${PROG} [a-z]*: ignoring sdir (CVS/Entries missing)"
+${PROG} update: ignoring sdir (CVS/Entries missing)"
cd ..
dotest conflicts3-16a "${testcvs} -q update first-dir" \
"${QUESTION} first-dir/sdir
-${PROG} [a-z]*: ignoring first-dir/sdir (CVS/Entries missing)"
+${PROG} update: ignoring first-dir/sdir (CVS/Entries missing)"
cd first-dir
fi
rm -r sdir
@@ -8713,8 +10461,8 @@ C sdir/sfile"
dotest conflicts3-24 "${testcvs} -q update -d sdir" "U sdir/sfile"
rm sdir/sfile
dotest conflicts3-25 "${testcvs} rm sdir/sfile" \
-"${PROG} [a-z]*: scheduling .sdir/sfile. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .sdir/sfile. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest conflicts3-26 "${testcvs} ci -m remove sdir/sfile" \
"Removing sdir/sfile;
${CVSROOT_DIRNAME}/first-dir/sdir/sfile,v <-- sfile
@@ -8741,8 +10489,8 @@ done"
cd first-dir
echo "The usual boring test text." > cleanme.txt
dotest clean-3 "${testcvs} add cleanme.txt" \
-"${PROG} [a-z]*: scheduling file .cleanme\.txt. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .cleanme\.txt. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest clean-4 "${testcvs} -q ci -m clean-3" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/cleanme\.txt,v
done
@@ -8800,7 +10548,7 @@ retrieving revision 1\.1
retrieving revision 1\.2
Merging differences between 1\.1 and 1\.2 into cleanme\.txt
rcsmerge: warning: conflicts during merge
-${PROG} [a-z]*: conflicts found in cleanme\.txt
+${PROG} update: conflicts found in cleanme\.txt
C cleanme\.txt"
dotest clean-18 "${testcvs} -q update -C" \
"(Locally modified cleanme\.txt moved to \.#cleanme\.txt\.1\.1)
@@ -8821,6 +10569,7 @@ fish"
# -a:
# error on incorrect placement: modules
# error combining with other options: modules2-a*
+ # infinite loops: modules148a1.1 - modules148a1.2
# use to specify a file more than once: modules3
# use with ! feature: modules4
# regular modules: modules, modules2, cvsadm
@@ -8855,7 +10604,7 @@ U CVSROOT/verifymsg'
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
rm -rf 1
@@ -8879,7 +10628,7 @@ U CVSROOT/verifymsg'
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
rm -rf 1
@@ -8906,7 +10655,7 @@ U CVSROOT/verifymsg'
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../..
rm -rf 1
rm -rf ${CVSROOT_DIRNAME}/somedir
@@ -8935,9 +10684,9 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
touch a b
dotest modules-144 "${testcvs} add a b" \
-"${PROG} [a-z]*: scheduling file .a. for addition
-${PROG} [a-z]*: scheduling file .b. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .a. for addition
+${PROG} add: scheduling file .b. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest modules-145 "${testcvs} ci -m added" \
"${PROG} [a-z]*: Examining .
@@ -8984,6 +10733,15 @@ aliasnested -a first-dir/subdir/ssdir
topfiles -a first-dir/file1 first-dir/file2
world -a .
statusmod -s Mungeable
+# Check for ability to block infinite loops.
+infinitealias -a infinitealias
+# Prior to 1.11.12 & 1.12.6, the infinite alias loop check didn't strip
+# slashes or work if a module called a module which then called itself
+# (A -> A was blocked, but not A -> B -> A or deeper).
+infinitealias2 -a infinitealias2/
+infinitealias3 -a infinitealias4/
+infinitealias4 -a aliasmodule infinitealias5
+infinitealias5 -a infinitealias3/
# Options must come before arguments. It is possible this should
# be relaxed at some point (though the result would be bizarre for
# -a); for now test the current behavior.
@@ -8994,7 +10752,7 @@ EOF
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
# The "statusmod" module contains an error; trying to use it
@@ -9005,6 +10763,11 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
aliasnested -a first-dir/subdir/ssdir
bogusalias first-dir/subdir/a -a
dirmodule first-dir/subdir
+infinitealias -a infinitealias
+infinitealias2 -a infinitealias2/
+infinitealias3 -a infinitealias4/
+infinitealias4 -a aliasmodule infinitealias5
+infinitealias5 -a infinitealias3/
namedmodule -d nameddir first-dir/subdir
realmodule first-dir/subdir a
statusmod -s Mungeable
@@ -9020,6 +10783,24 @@ dirmodule NONE first-dir/subdir
namedmodule NONE first-dir/subdir
realmodule NONE first-dir/subdir a'
+ # Check that infinite loops are avoided
+ dotest modules-148a1.1 "${testcvs} co infinitealias" \
+"$PROG checkout: module \`infinitealias' in modules file contains infinite loop" \
+"$PROG server: module \`infinitealias' in modules file contains infinite loop
+$PROG checkout: module \`infinitealias' in modules file contains infinite loop"
+ # Prior to 1.11.12 & 1.12.6, the inifinte alias loop check did not
+ # strip slashes.
+ dotest modules-148a1.2 "${testcvs} co infinitealias2" \
+"$PROG checkout: module \`infinitealias2' in modules file contains infinite loop" \
+"$PROG server: module \`infinitealias2' in modules file contains infinite loop
+$PROG checkout: module \`infinitealias2' in modules file contains infinite loop"
+ # Prior to 1.11.12 & 1.12.6, the inifinte alias loop check did not
+ # notice when A -> B -> A, it only noticed A -> A.
+ dotest modules-148a1.3 "${testcvs} co infinitealias3/" \
+"$PROG checkout: module \`infinitealias3' in modules file contains infinite loop" \
+"$PROG server: module \`infinitealias3' in modules file contains infinite loop
+$PROG checkout: module \`infinitealias3' in modules file contains infinite loop"
+
# Test that real modules check out to realmodule/a, not subdir/a.
dotest modules-149a1 "${testcvs} co realmodule" "U realmodule/a"
dotest modules-149a2 "test -d realmodule && test -f realmodule/a" ""
@@ -9030,9 +10811,9 @@ realmodule NONE first-dir/subdir a'
Are you sure you want to release (and delete) directory .realmodule.: "
dotest_fail modules-149b1 "${testcvs} co realmodule/a" \
-"${PROG}"' [a-z]*: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \
-"${PROG}"' [a-z]*: module `realmodule/a'\'' is a request for a file in a module which is not a directory
-'"${PROG}"' \[[a-z]* aborted\]: cannot expand modules'
+"${PROG}"' checkout: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \
+"${PROG}"' server: module `realmodule/a'\'' is a request for a file in a module which is not a directory
+'"${PROG}"' \[checkout aborted\]: cannot expand modules'
# Now test the ability to check out a single file from a directory
dotest modules-150c "${testcvs} co dirmodule/a" "U dirmodule/a"
@@ -9048,7 +10829,7 @@ Are you sure you want to release (and delete) directory .dirmodule.: "
# (Dec 95). Probably the exit status should be nonzero,
# however.
dotest modules-150g1 "${testcvs} co dirmodule/nonexist" \
-"${PROG} [a-z]*: warning: new-born dirmodule/nonexist has disappeared"
+"${PROG} checkout: warning: new-born dirmodule/nonexist has disappeared"
# We tolerate the creation of the dirmodule directory, since that
# is what CVS does, not because we view that as preferable to not
# creating it.
@@ -9082,7 +10863,7 @@ Are you sure you want to release (and delete) directory .nameddir.: "
mkdir 2
cd 2
dotest modules-155a0 "${testcvs} co aliasnested" \
-"${PROG} [a-z]*: Updating first-dir/subdir/ssdir"
+"${PROG} checkout: Updating first-dir/subdir/ssdir"
dotest modules-155a1 "test -d first-dir" ''
dotest modules-155a2 "test -d first-dir/subdir" ''
dotest modules-155a3 "test -d first-dir/subdir/ssdir" ''
@@ -9116,9 +10897,9 @@ U first-dir/subdir/b"
echo 'first revision' > file1
echo 'first revision' > file2
dotest modules-155c2 "${testcvs} add file1 file2" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add these files permanently'
+"${PROG}"' add: scheduling file `file1'\'' for addition
+'"${PROG}"' add: scheduling file `file2'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently'
dotest modules-155c3 "${testcvs} -q ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -9143,7 +10924,7 @@ U first-dir/file2"
# Make sure the right thing happens if we remove a file.
cd first-dir
dotest modules-155c6 "${testcvs} -q rm -f file1" \
-"${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest modules-155c7 "${testcvs} -q ci -m remove-it" \
"Removing file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
@@ -9152,7 +10933,7 @@ done"
cd ..
rm -r first-dir
dotest modules-155c8 "${testcvs} -q co topfiles" \
-"${PROG} [a-z]*: warning: first-dir/file1 is not (any longer) pertinent
+"${PROG} checkout: warning: first-dir/file1 is not (any longer) pertinent
U first-dir/file2"
cd ..
@@ -9174,8 +10955,8 @@ Directory ${CVSROOT_DIRNAME}/third-dir added to the repository"
cd third-dir
touch file3
dotest modules2-setup-3 "${testcvs} add file3" \
-"${PROG} [a-z]*: scheduling file .file3. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file3. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest modules2-setup-4 "${testcvs} -q ci -m add file3" \
"RCS file: ${CVSROOT_DIRNAME}/third-dir/file3,v
done
@@ -9207,7 +10988,7 @@ EOF
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
@@ -9258,22 +11039,22 @@ EOF
# Note that this message should say "Updating ampermodule/first-dir"
# I suspect. This is a long-standing behavior/bug....
dotest modules2-9 "${testcvs} co ampermodule" \
-"${PROG} [a-z]*: Updating first-dir
-${PROG} [a-z]*: Updating second-dir"
+"${PROG} checkout: Updating first-dir
+${PROG} checkout: Updating second-dir"
touch ampermodule/first-dir/amper1
cd ampermodule
dotest modules2-10 "${testcvs} add first-dir/amper1" \
-"${PROG} [a-z]*: scheduling file .first-dir/amper1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .first-dir/amper1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
cd ..
# As with the "Updating xxx" message, the "U first-dir/amper1"
# message (instead of "U ampermodule/first-dir/amper1") is
# rather fishy.
dotest modules2-12 "${testcvs} co ampermodule" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} checkout: Updating first-dir
A first-dir/amper1
-${PROG} [a-z]*: Updating second-dir"
+${PROG} checkout: Updating second-dir"
if $remote; then
dotest modules2-13 "${testcvs} -q ci -m add-it ampermodule" \
@@ -9304,7 +11085,7 @@ done"
mkdir 1; cd 1
dotest modules2-14 "${testcvs} co combmodule" \
"U combmodule/file3
-${PROG} [a-z]*: Updating first-dir
+${PROG} checkout: Updating first-dir
U first-dir/amper1"
dotest modules2-15 "test -f combmodule/file3" ""
dotest modules2-16 "test -f combmodule/first-dir/amper1" ""
@@ -9318,7 +11099,7 @@ U first-dir/amper1"
# third-dir, so CVS just acts as if there is nothing there
# to do.
dotest modules2-17 "${testcvs} update -d" \
-"${PROG} [a-z]*: Updating \."
+"${PROG} update: Updating \."
cd ..
dotest modules2-18 "${testcvs} -q co combmodule" \
@@ -9332,15 +11113,15 @@ U first-dir/amper1"
# "missing directory" error message.
mkdir 1; cd 1
dotest modules2-20 "${testcvs} co ampdirmod" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} checkout: Updating first-dir
U first-dir/amper1
-${PROG} [a-z]*: Updating second-dir"
+${PROG} checkout: Updating second-dir"
dotest modules2-21 "test -f newdir/first-dir/amper1" ""
dotest modules2-22 "test -d newdir/second-dir" ""
dotest_fail modules2-23 "${testcvs} co badmod" \
-"${PROG} [a-z]*: modules file missing directory for module badmod" \
-"${PROG} [a-z]*: modules file missing directory for module badmod
-${PROG} \[[a-z]* aborted\]: cannot expand modules"
+"${PROG} checkout: modules file missing directory for module badmod" \
+"${PROG} server: modules file missing directory for module badmod
+${PROG} \[checkout aborted\]: cannot expand modules"
cd ..
rm -r 1
@@ -9406,12 +11187,12 @@ ${PROG} \[[a-z]* aborted\]: cannot expand modules"
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
dotest_fail modules2-a1 "${testcvs} -q co aliasopt" \
-"${PROG} [a-z]*: -a cannot be specified in the modules file along with other options" \
-"${PROG} [a-z]*: -a cannot be specified in the modules file along with other options
-${PROG} \[[a-z]* aborted\]: cannot expand modules"
+"${PROG} checkout: -a cannot be specified in the modules file along with other options" \
+"${PROG} server: -a cannot be specified in the modules file along with other options
+${PROG} \[checkout aborted\]: cannot expand modules"
cd ..; rm -r 1
# Clean up.
@@ -9435,8 +11216,8 @@ ${PROG} \[[a-z]* aborted\]: cannot expand modules"
cd first-dir
echo file1 >file1
dotest modules3-2 "${testcvs} add file1" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG} add: scheduling file \`file1' for addition
+${PROG} add: use '${PROG} commit' to add this file permanently"
dotest modules3-3 "${testcvs} -q ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -9463,7 +11244,7 @@ EOF
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
dotest modules3-6 "${testcvs} -q co bigmod" ''
@@ -9480,18 +11261,18 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
# considering this is a documented technique and everything.
dotest modules3-7a \
"${testcvs} import -m add-dirs second-dir tag1 tag2" \
-"${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/second-dir/suba
-${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/second-dir/suba/subb
+"${PROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/suba
+${PROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/suba/subb
No conflicts created by this import" "
No conflicts created by this import"
cd ..; rm -r 1
mkdir 1; cd 1
dotest modules3-7b "${testcvs} co second-dir" \
-"${PROG} [a-z]*: Updating second-dir
-${PROG} [a-z]*: Updating second-dir/suba
-${PROG} [a-z]*: Updating second-dir/suba/subb" \
-"${PROG} server: Updating second-dir"
+"${PROG} checkout: Updating second-dir
+${PROG} checkout: Updating second-dir/suba
+${PROG} checkout: Updating second-dir/suba/subb" \
+"${PROG} checkout: Updating second-dir"
if $remote; then
cd second-dir
@@ -9508,8 +11289,8 @@ ${PROG} [a-z]*: Updating second-dir/suba/subb" \
cd second-dir/suba/subb
touch fileb
dotest modules3-7c "${testcvs} add fileb" \
-"${PROG} [a-z]*: scheduling file .fileb. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .fileb. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest modules3-7d "${testcvs} -q ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/second-dir/suba/subb/fileb,v
done
@@ -9612,13 +11393,13 @@ done"
echo file1 > file1
dotest modules4-4 "${testcvs} add file1" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file1'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
echo file2 > subdir/file2
dotest modules4-5 "${testcvs} add subdir/file2" \
-"${PROG}"' [a-z]*: scheduling file `subdir/file2'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${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" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
@@ -9649,7 +11430,7 @@ EOF
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
cd ..
@@ -9683,8 +11464,8 @@ U first-dir/subdir/file2"
rm -r 2
dotest modules4-12 "${testcvs} rtag tag some" \
-"${PROG} [a-z]*: Tagging first-dir
-${PROG} [a-z]*: Ignoring first-dir/subdir"
+"${PROG} rtag: Tagging first-dir
+${PROG} rtag: Ignoring first-dir/subdir"
cd 1/first-dir/subdir
dotest modules4-13 "${testcvs} log file2" "
@@ -9727,9 +11508,9 @@ add-it
"Directory ${CVSROOT_DIRNAME}/first-dir/subdir/ssdir added to the repository"
touch a b
dotest modules5-4 "${testcvs} add a b" \
-"${PROG} [a-z]*: scheduling file .a. for addition
-${PROG} [a-z]*: scheduling file .b. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .a. for addition
+${PROG} add: scheduling file .b. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest modules5-5 "${testcvs} ci -m added" \
"${PROG} [a-z]*: Examining .
@@ -9764,17 +11545,22 @@ U CVSROOT/verifymsg"
# FIXCVS: The sleep in the following script helps avoid out of
# order messages, but we really need to figure out how to fix
# cvs to prevent them in the first place.
- for i in checkin checkout update export tag; do
+ for i in checkout export tag; do
cat >> ${CVSROOT_DIRNAME}/$i.sh <<EOF
#! /bin/sh
sleep 1
echo "$i script invoked in \`pwd\`"
echo "args: \$@"
EOF
- chmod +x ${CVSROOT_DIRNAME}/$i.sh
+ # Cygwin doesn't set premissions correctly over the Samba share.
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod +x ${CVSROOT_DIRNAME}/$i.sh"
+ else
+ chmod +x ${CVSROOT_DIRNAME}/$i.sh
+ fi
done
- OPTS="-i ${CVSROOT_DIRNAME}/checkin.sh -o${CVSROOT_DIRNAME}/checkout.sh -u ${CVSROOT_DIRNAME}/update.sh -e ${CVSROOT_DIRNAME}/export.sh -t${CVSROOT_DIRNAME}/tag.sh"
+ OPTS="-o${CVSROOT_DIRNAME}/checkout.sh -e ${CVSROOT_DIRNAME}/export.sh -t${CVSROOT_DIRNAME}/tag.sh"
cat >CVSROOT/modules <<EOF
realmodule ${OPTS} first-dir/subdir a
dirmodule ${OPTS} first-dir/subdir
@@ -9787,7 +11573,7 @@ EOF
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
rm -rf first-dir
@@ -9796,13 +11582,13 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
if $remote; then
dotest modules5-8 "${testcvs} co realmodule" \
"U realmodule/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule..
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule..
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: realmodule"
else
dotest modules5-8 "${testcvs} co realmodule" \
"U realmodule/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule..
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule..
checkout script invoked in ${TESTDIR}/1
args: realmodule"
fi
@@ -9812,36 +11598,24 @@ args: realmodule"
dotest modules5-11 "${testcvs} -q co realmodule" \
"checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: realmodule"
- dotest modules5-12 "${testcvs} -q update" \
-"${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*/realmodule
-args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ dotest modules5-12 "${testcvs} -q update" ''
echo "change" >>realmodule/a
dotest modules5-13 "${testcvs} -q ci -m." \
"Checking in realmodule/a;
${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a
new revision: 1\.2; previous revision: 1\.1
-done
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkin\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-checkin script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*/realmodule
-args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+done"
else
dotest modules5-11 "${testcvs} -q co realmodule" \
"checkout script invoked in ${TESTDIR}/1
args: realmodule"
- dotest modules5-12 "${testcvs} -q update" \
-"${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TESTDIR}/1/realmodule
-args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ dotest modules5-12 "${testcvs} -q update" ''
echo "change" >>realmodule/a
dotest modules5-13 "${testcvs} -q ci -m." \
"Checking in realmodule/a;
${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a
new revision: 1\.2; previous revision: 1\.1
-done
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkin\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-checkin script invoked in ${TESTDIR}/1/realmodule
-args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+done"
fi
dotest modules5-14 "echo yes | ${testcvs} release -d realmodule" \
"You have \[0\] altered files in this repository\.
@@ -9865,21 +11639,21 @@ args: realmodule"
rm -r realmodule
dotest_fail modules5-17 "${testcvs} co realmodule/a" \
-"${PROG}"' [a-z]*: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \
-"${PROG}"' [a-z]*: module `realmodule/a'\'' is a request for a file in a module which is not a directory
-'"${PROG}"' \[[a-z]* aborted\]: cannot expand modules'
+"${PROG}"' checkout: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \
+"${PROG}"' server: module `realmodule/a'\'' is a request for a file in a module which is not a directory
+'"${PROG}"' \[checkout aborted\]: cannot expand modules'
# Now test the ability to check out a single file from a directory
if $remote; then
dotest modules5-18 "${testcvs} co dirmodule/a" \
"U dirmodule/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: dirmodule"
else
dotest modules5-18 "${testcvs} co dirmodule/a" \
"U dirmodule/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
checkout script invoked in ${TESTDIR}/1
args: dirmodule"
fi
@@ -9897,14 +11671,14 @@ Are you sure you want to release (and delete) directory .dirmodule.: "
# however.
if $remote; then
dotest modules5-22 "${testcvs} co dirmodule/nonexist" \
-"${PROG} [a-z]*: warning: new-born dirmodule/nonexist has disappeared
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
+"${PROG} checkout: warning: new-born dirmodule/nonexist has disappeared
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: dirmodule"
else
dotest modules5-22 "${testcvs} co dirmodule/nonexist" \
-"${PROG} [a-z]*: warning: new-born dirmodule/nonexist has disappeared
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
+"${PROG} checkout: warning: new-born dirmodule/nonexist has disappeared
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
checkout script invoked in ${TESTDIR}/1
args: dirmodule"
fi
@@ -9937,17 +11711,11 @@ args: nameddir"
if $remote; then
dotest modules5-26 "${testcvs} -q co namedmodule" \
"M nameddir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*/nameddir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: nameddir"
else
dotest modules5-26 "${testcvs} -q co namedmodule" \
"M nameddir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TESTDIR}/1/nameddir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir
checkout script invoked in ${TESTDIR}/1
args: nameddir"
fi
@@ -9956,17 +11724,11 @@ args: nameddir"
if $remote; then
dotest modules5-27 "${testcvs} -q co namedmodule" \
"U nameddir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*/nameddir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: nameddir"
else
dotest modules5-27 "${testcvs} -q co namedmodule" \
"U nameddir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TESTDIR}/1/nameddir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir
checkout script invoked in ${TESTDIR}/1
args: nameddir"
fi
@@ -9980,13 +11742,13 @@ Are you sure you want to release (and delete) directory .nameddir.: "
if $remote; then
dotest modules5-29 "${testcvs} co -d mydir realmodule" \
"U mydir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: mydir"
else
dotest modules5-29 "${testcvs} co -d mydir realmodule" \
"U mydir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
checkout script invoked in ${TESTDIR}/1
args: mydir"
fi
@@ -9996,36 +11758,24 @@ args: mydir"
dotest modules5-32 "${testcvs} -q co -d mydir realmodule" \
"checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: mydir"
- dotest modules5-33 "${testcvs} -q update" \
-"${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*/mydir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ dotest modules5-33 "${testcvs} -q update" ''
echo "change" >>mydir/a
dotest modules5-34 "${testcvs} -q ci -m." \
"Checking in mydir/a;
${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a
new revision: 1\.3; previous revision: 1\.2
-done
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkin\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-checkin script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*/mydir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+done"
else
dotest modules5-32 "${testcvs} -q co -d mydir realmodule" \
"checkout script invoked in ${TESTDIR}/1
args: mydir"
- dotest modules5-33 "${testcvs} -q update" \
-"${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TESTDIR}/1/mydir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ dotest modules5-33 "${testcvs} -q update" ''
echo "change" >>mydir/a
dotest modules5-34 "${testcvs} -q ci -m." \
"Checking in mydir/a;
${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a
new revision: 1\.3; previous revision: 1\.2
-done
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkin\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-checkin script invoked in ${TESTDIR}/1/mydir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+done"
fi
dotest modules5-35 "echo yes | ${testcvs} release -d mydir" \
"You have \[0\] altered files in this repository\.
@@ -10053,13 +11803,13 @@ args: mydir"
if $remote; then
dotest modules5-38 "${testcvs} co -d mydir dirmodule/a" \
"U mydir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: mydir"
else
dotest modules5-38 "${testcvs} co -d mydir dirmodule/a" \
"U mydir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
checkout script invoked in ${TESTDIR}/1
args: mydir"
fi
@@ -10077,14 +11827,14 @@ Are you sure you want to release (and delete) directory .mydir.: "
# however.
if $remote; then
dotest modules5-42 "${testcvs} co -d mydir dirmodule/nonexist" \
-"${PROG} [a-z]*: warning: new-born mydir/nonexist has disappeared
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+"${PROG} checkout: warning: new-born mydir/nonexist has disappeared
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: mydir"
else
dotest modules5-42 "${testcvs} co -d mydir dirmodule/nonexist" \
-"${PROG} [a-z]*: warning: new-born mydir/nonexist has disappeared
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+"${PROG} checkout: warning: new-born mydir/nonexist has disappeared
+${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
checkout script invoked in ${TESTDIR}/1
args: mydir"
fi
@@ -10116,17 +11866,11 @@ args: mydir"
if $remote; then
dotest modules5-47 "${testcvs} -q co -d mydir namedmodule" \
"M mydir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*/mydir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: mydir"
else
dotest modules5-47 "${testcvs} -q co -d mydir namedmodule" \
"M mydir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TESTDIR}/1/mydir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir
checkout script invoked in ${TESTDIR}/1
args: mydir"
fi
@@ -10135,17 +11879,11 @@ args: mydir"
if $remote; then
dotest modules5-48 "${testcvs} -q co -d mydir namedmodule" \
"U mydir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*/mydir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
args: mydir"
else
dotest modules5-48 "${testcvs} -q co -d mydir namedmodule" \
"U mydir/a
-${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in ${TESTDIR}/1/mydir
-args: ${CVSROOT_DIRNAME}/first-dir/subdir
checkout script invoked in ${TESTDIR}/1
args: mydir"
fi
@@ -10184,15 +11922,15 @@ Are you sure you want to release (and delete) directory .mydir.: "
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: [0-9.]*; previous revision: [0-9.]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
# Here's where CVS would report not being able to find `lename'
cd ..
dotest_fail modules6-1 "${testcvs} -q co badname" \
-"${PROG} [a-z]*: warning: NULL value for key .badname. at line 2 of .${CVSROOT_DIRNAME}/CVSROOT/modules.
-${PROG} [a-z]*: cannot find module .badname. - ignored" \
-"${PROG} [a-z]*: warning: NULL value for key .badname. at line 2 of .${CVSROOT_DIRNAME}/CVSROOT/modules.
-${PROG} [a-z]*: cannot find module .badname. - ignored
+"${PROG} checkout: warning: NULL value for key .badname. at line 2 of .${CVSROOT_DIRNAME}/CVSROOT/modules.
+${PROG} checkout: cannot find module .badname. - ignored" \
+"${PROG} server: warning: NULL value for key .badname. at line 2 of .${CVSROOT_DIRNAME}/CVSROOT/modules.
+${PROG} server: cannot find module .badname. - ignored
${PROG} \[checkout aborted\]: cannot expand modules"
# cleanup
@@ -10203,7 +11941,7 @@ ${PROG} \[checkout aborted\]: cannot expand modules"
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: [0-9.]*; previous revision: [0-9.]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../..
if $keep; then :; else
@@ -10211,30 +11949,160 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
fi
;;
- mkmodules-temp-file-removal)
+ 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
# creates while mkmodules is in the process of trying to check
# out the missing file.
mkdir 1; cd 1
- dotest mtfr-1 "${testcvs} -Q co CVSROOT" ''
+ dotest mkmodules-temp-file-removal-1 "${testcvs} -Q co CVSROOT" ''
cd CVSROOT
echo no-such-file >> checkoutlist
- dotest mtfr-2 "${testcvs} -Q ci -m. checkoutlist" \
+ dotest mkmodules-temp-file-removal-2 "${testcvs} -Q ci -m. checkoutlist" \
"Checking in checkoutlist;
$CVSROOT_DIRNAME/CVSROOT/checkoutlist,v <-- checkoutlist
new revision: 1\.2; previous revision: 1\.1
done
-$PROG [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
- dotest mtfr-3 "echo $CVSROOT_DIRNAME/CVSROOT/.#[0-9]*" \
+ dotest mkmodules-temp-file-removal-3 "echo $CVSROOT_DIRNAME/CVSROOT/.#[0-9]*" \
"$CVSROOT_DIRNAME/CVSROOT/\.#\[0-9\]\*"
+ # Versions 1.11.6 & 1.12.1 and earlier of CVS printed most of the
+ # white space included before error messages in checkoutlist.
+ echo "no-such-file Failed to update no-such-file." >checkoutlist
+ dotest mkmodules-error-message-1 "${testcvs} -Q ci -m. checkoutlist" \
+"Checking in checkoutlist;
+$CVSROOT_DIRNAME/CVSROOT/checkoutlist,v <-- checkoutlist
+new revision: 1\.3; previous revision: 1\.2
+done
+${PROG} commit: Rebuilding administrative file database
+${PROG} commit: Failed to update no-such-file\."
+
+ # Versions 1.11.6 & 1.12.1 and earlier of CVS used the error string
+ # from the checkoutlist file as the format string passed to error()'s
+ # printf. Check that this is no longer the case by verifying that
+ # printf format patterns remain unchanged.
+ echo "no-such-file Failed to update %s %lx times because %s happened %d times." >checkoutlist
+ dotest mkmodules-error-message-2 "${testcvs} -Q ci -m. checkoutlist" \
+"Checking in checkoutlist;
+$CVSROOT_DIRNAME/CVSROOT/checkoutlist,v <-- checkoutlist
+new revision: 1\.4; previous revision: 1\.3
+done
+${PROG} commit: Rebuilding administrative file database
+${PROG} commit: Failed to update %s %lx times because %s happened %d times\."
+
+ dotest mkmodules-cleanup-1 "${testcvs} -Q up -pr1.1 checkoutlist >checkoutlist"
+ dotest mkmodules-cleanup-2 "${testcvs} -Q ci -m. checkoutlist" \
+"Checking in checkoutlist;
+$CVSROOT_DIRNAME/CVSROOT/checkoutlist,v <-- checkoutlist
+new revision: 1\.5; previous revision: 1\.4
+done
+${PROG} commit: Rebuilding administrative file database"
+
cd ../..
rm -rf 1
;;
+ co-d)
+ # Some tests of various permutations of co-d when directories exist
+ # and checkouts lengthen.
+ #
+ # Interestingly enough, these same tests pass when the directory
+ # lengthening happens via the modules file. Go figure.
+ module=co-d
+ mkdir $module; cd $module
+ mkdir top; cd top
+ dotest co-d-init-1 "$testcvs -Q co -l ."
+ mkdir $module
+ dotest co-d-init-2 "$testcvs -Q add $module"
+ cd $module
+ echo content >file1
+ echo different content >file2
+ dotest co-d-init-3 "$testcvs -Q add file1 file2"
+ dotest co-d-init-4 "$testcvs -Q ci -madd-em" \
+"RCS file: $CVSROOT_DIRNAME/co-d/file1,v
+done
+Checking in file1;
+$CVSROOT_DIRNAME/co-d/file1,v <-- file1
+initial revision: 1\.1
+done
+RCS file: $CVSROOT_DIRNAME/co-d/file2,v
+done
+Checking in file2;
+$CVSROOT_DIRNAME/co-d/file2,v <-- file2
+initial revision: 1\.1
+done"
+ cd ../..
+
+ mkdir 2; cd 2
+ dotest co-d-1 "$testcvs -q co -d dir $module" \
+"U dir/file1
+U dir/file2"
+ dotest co-d-1.2 "cat dir/CVS/Repository" "$module"
+
+ # FIXCVS: This should work. Correct expected result:
+ #
+ #"U dir2/sdir/file1
+ #U dir2/sdir/file2"
+ dotest_fail co-d-2 "$testcvs -q co -d dir2/sdir $module" \
+"$PROG \[checkout aborted\]: could not change directory to requested checkout directory \`dir2': No such file or directory"
+ # FIXCVS:
+ # dotest co-d-2.2 "cat dir4/CVS/Repository" "CVSROOT/Emptydir"
+ # dotest co-d-2.3 "cat dir5/CVS/Repository" "$module"
+
+ mkdir dir3
+ dotest co-d-3 "$testcvs -q co -d dir3 $module" \
+"U dir3/file1
+U dir3/file2"
+ dotest co-d-3.2 "cat dir3/CVS/Repository" "$module"
+
+ if $remote; then
+ # FIXCVS: As for co-d-2.
+ mkdir dir4
+ dotest_fail co-d-4r "$testcvs -q co -d dir4/sdir $module" \
+"$PROG \[checkout aborted\]: could not change directory to requested checkout directory \`dir4': No such file or directory"
+
+ # FIXCVS: As for co-d-2.
+ mkdir dir5
+ mkdir dir5/sdir
+ dotest_fail co-d-5r "$testcvs -q co -d dir5/sdir $module" \
+"$PROG \[checkout aborted\]: could not change directory to requested checkout directory \`dir5': No such file or directory"
+ else
+ mkdir dir4
+ dotest co-d-4 "$testcvs -q co -d dir4/sdir $module" \
+"U dir4/sdir/file1
+U dir4/sdir/file2"
+ # CVS only creates administration directories for directories it
+ # creates, and the last portion of the path passed to -d
+ # regardless.
+ dotest_fail co-d-4.2 "test -d dir4/CVS"
+ dotest co-d-4.3 "cat dir4/sdir/CVS/Repository" "$module"
+
+ mkdir dir5
+ mkdir dir5/sdir
+ dotest co-d-5 "$testcvs -q co -d dir5/sdir $module" \
+"U dir5/sdir/file1
+U dir5/sdir/file2"
+ # CVS only creates administration directories for directories it
+ # creates, and the last portion of the path passed to -d
+ # regardless.
+ dotest_fail co-d-5.2 "test -d dir5/CVS"
+ dotest co-d-5.3 "cat dir5/sdir/CVS/Repository" "$module"
+ fi
+
+ # clean up
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ rm -rf $CVSROOT_DIRNAME/$module
+ rm -r $module
+ ;;
+
cvsadm)
# These test check the content of CVS' administrative
# files as they are checked out in various configurations.
@@ -10286,7 +12154,7 @@ $PROG [a-z]*: Rebuilding administrative file database"
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../..
rm -r 1
@@ -10326,9 +12194,9 @@ Checking in CVSROOT/modules;
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database" \
-"${PROG} [a-z]*: Examining .
-${PROG} [a-z]*: Examining CVSROOT"
+${PROG} commit: Rebuilding administrative file database" \
+"${PROG} commit: Examining .
+${PROG} commit: Examining CVSROOT"
rm -rf CVS CVSROOT;
# Create the various modules
@@ -10353,11 +12221,11 @@ Directory ${CVSROOT_DIRNAME}/mod2-2/sub2-2 added to the repository"
echo "file2" > mod2/sub2/file2
echo "file2-2" > mod2-2/sub2-2/file2-2
dotest cvsadm-2aa "${testcvs} add mod1/file1 mod1-2/file1-2 mod2/sub2/file2 mod2-2/sub2-2/file2-2" \
-"${PROG} [a-z]*: scheduling file .mod1/file1. for addition
-${PROG} [a-z]*: scheduling file .mod1-2/file1-2. for addition
-${PROG} [a-z]*: scheduling file .mod2/sub2/file2. for addition
-${PROG} [a-z]*: scheduling file .mod2-2/sub2-2/file2-2. for addition
-${PROG} [a-z]*: use '${PROG} commit' to add these files permanently"
+"${PROG} add: scheduling file .mod1/file1. for addition
+${PROG} add: scheduling file .mod1-2/file1-2. for addition
+${PROG} add: scheduling file .mod2/sub2/file2. for addition
+${PROG} add: scheduling file .mod2-2/sub2-2/file2-2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest cvsadm-2b "${testcvs} ci -m yup mod1 mod1-2 mod2 mod2-2" \
"${PROG} [a-z]*: Examining mod1
@@ -10404,35 +12272,35 @@ done"
# order.
dotest cvsadm-3 "${testcvs} co 1mod" \
-"${PROG} [a-z]*: Updating 1mod
+"${PROG} checkout: Updating 1mod
U 1mod/file1"
dotest cvsadm-3b "cat CVS/Repository" "\."
dotest cvsadm-3d "cat 1mod/CVS/Repository" "mod1"
rm -rf CVS 1mod
dotest cvsadm-4 "${testcvs} co 2mod" \
-"${PROG} [a-z]*: Updating 2mod
+"${PROG} checkout: Updating 2mod
U 2mod/file2"
dotest cvsadm-4b "cat CVS/Repository" "\."
dotest cvsadm-4d "cat 2mod/CVS/Repository" "mod2/sub2"
rm -rf CVS 2mod
dotest cvsadm-5 "${testcvs} co 1d1mod" \
-"${PROG} [a-z]*: Updating dir1d1
+"${PROG} checkout: Updating dir1d1
U dir1d1/file1"
dotest cvsadm-5b "cat CVS/Repository" "\."
dotest cvsadm-5d "cat dir1d1/CVS/Repository" "mod1"
rm -rf CVS dir1d1
dotest cvsadm-6 "${testcvs} co 1d2mod" \
-"${PROG} [a-z]*: Updating dir1d2
+"${PROG} checkout: Updating dir1d2
U dir1d2/file2"
dotest cvsadm-6b "cat CVS/Repository" "\."
dotest cvsadm-6d "cat dir1d2/CVS/Repository" "mod2/sub2"
rm -rf CVS dir1d2
dotest cvsadm-7 "${testcvs} co 2d1mod" \
-"${PROG} [a-z]*: Updating dir2d1/sub2d1
+"${PROG} checkout: Updating dir2d1/sub2d1
U dir2d1/sub2d1/file1"
dotest cvsadm-7b "cat CVS/Repository" "\."
dotest cvsadm-7d "cat dir2d1/CVS/Repository" "\."
@@ -10440,7 +12308,7 @@ U dir2d1/sub2d1/file1"
rm -rf CVS dir2d1
dotest cvsadm-8 "${testcvs} co 2d2mod" \
-"${PROG} [a-z]*: Updating dir2d2/sub2d2
+"${PROG} checkout: Updating dir2d2/sub2d2
U dir2d2/sub2d2/file2"
dotest cvsadm-8b "cat CVS/Repository" "\."
dotest cvsadm-8d "cat dir2d2/CVS/Repository" "mod2"
@@ -10455,9 +12323,9 @@ U dir2d2/sub2d2/file2"
### 1mod
dotest cvsadm-9 "${testcvs} co 1mod 1mod-2" \
-"${PROG} [a-z]*: Updating 1mod
+"${PROG} checkout: Updating 1mod
U 1mod/file1
-${PROG} [a-z]*: Updating 1mod-2
+${PROG} checkout: Updating 1mod-2
U 1mod-2/file1-2"
# the usual for the top level
dotest cvsadm-9b "cat CVS/Repository" "\."
@@ -10469,9 +12337,9 @@ U 1mod-2/file1-2"
# 1mod 2mod redmod bluemod
dotest cvsadm-10 "${testcvs} co 1mod 2mod" \
-"${PROG} [a-z]*: Updating 1mod
+"${PROG} checkout: Updating 1mod
U 1mod/file1
-${PROG} [a-z]*: Updating 2mod
+${PROG} checkout: Updating 2mod
U 2mod/file2"
# the usual for the top level
dotest cvsadm-10b "cat CVS/Repository" "\."
@@ -10482,9 +12350,9 @@ U 2mod/file2"
rm -rf CVS 1mod 2mod
dotest cvsadm-11 "${testcvs} co 1mod 1d1mod" \
-"${PROG} [a-z]*: Updating 1mod
+"${PROG} checkout: Updating 1mod
U 1mod/file1
-${PROG} [a-z]*: Updating dir1d1
+${PROG} checkout: Updating dir1d1
U dir1d1/file1"
# the usual for the top level
dotest cvsadm-11b "cat CVS/Repository" "\."
@@ -10495,9 +12363,9 @@ U dir1d1/file1"
rm -rf CVS 1mod dir1d1
dotest cvsadm-12 "${testcvs} co 1mod 1d2mod" \
-"${PROG} [a-z]*: Updating 1mod
+"${PROG} checkout: Updating 1mod
U 1mod/file1
-${PROG} [a-z]*: Updating dir1d2
+${PROG} checkout: Updating dir1d2
U dir1d2/file2"
# the usual for the top level
dotest cvsadm-12b "cat CVS/Repository" "\."
@@ -10508,9 +12376,9 @@ U dir1d2/file2"
rm -rf CVS 1mod dir1d2
dotest cvsadm-13 "${testcvs} co 1mod 2d1mod" \
-"${PROG} [a-z]*: Updating 1mod
+"${PROG} checkout: Updating 1mod
U 1mod/file1
-${PROG} [a-z]*: Updating dir2d1/sub2d1
+${PROG} checkout: Updating dir2d1/sub2d1
U dir2d1/sub2d1/file1"
# the usual for the top level
dotest cvsadm-13b "cat CVS/Repository" "\."
@@ -10522,9 +12390,9 @@ U dir2d1/sub2d1/file1"
rm -rf CVS 1mod dir2d1
dotest cvsadm-14 "${testcvs} co 1mod 2d2mod" \
-"${PROG} [a-z]*: Updating 1mod
+"${PROG} checkout: Updating 1mod
U 1mod/file1
-${PROG} [a-z]*: Updating dir2d2/sub2d2
+${PROG} checkout: Updating dir2d2/sub2d2
U dir2d2/sub2d2/file2"
# the usual for the top level
dotest cvsadm-14b "cat CVS/Repository" "\."
@@ -10539,9 +12407,9 @@ U dir2d2/sub2d2/file2"
### 2mod
dotest cvsadm-15 "${testcvs} co 2mod 2mod-2" \
-"${PROG} [a-z]*: Updating 2mod
+"${PROG} checkout: Updating 2mod
U 2mod/file2
-${PROG} [a-z]*: Updating 2mod-2
+${PROG} checkout: Updating 2mod-2
U 2mod-2/file2-2"
# the usual for the top level
dotest cvsadm-15b "cat CVS/Repository" "\."
@@ -10553,9 +12421,9 @@ U 2mod-2/file2-2"
dotest cvsadm-16 "${testcvs} co 2mod 1d1mod" \
-"${PROG} [a-z]*: Updating 2mod
+"${PROG} checkout: Updating 2mod
U 2mod/file2
-${PROG} [a-z]*: Updating dir1d1
+${PROG} checkout: Updating dir1d1
U dir1d1/file1"
# the usual for the top level
dotest cvsadm-16b "cat CVS/Repository" "\."
@@ -10566,9 +12434,9 @@ U dir1d1/file1"
rm -rf CVS 2mod dir1d1
dotest cvsadm-17 "${testcvs} co 2mod 1d2mod" \
-"${PROG} [a-z]*: Updating 2mod
+"${PROG} checkout: Updating 2mod
U 2mod/file2
-${PROG} [a-z]*: Updating dir1d2
+${PROG} checkout: Updating dir1d2
U dir1d2/file2"
# the usual for the top level
dotest cvsadm-17b "cat CVS/Repository" "\."
@@ -10579,9 +12447,9 @@ U dir1d2/file2"
rm -rf CVS 2mod dir1d2
dotest cvsadm-18 "${testcvs} co 2mod 2d1mod" \
-"${PROG} [a-z]*: Updating 2mod
+"${PROG} checkout: Updating 2mod
U 2mod/file2
-${PROG} [a-z]*: Updating dir2d1/sub2d1
+${PROG} checkout: Updating dir2d1/sub2d1
U dir2d1/sub2d1/file1"
# the usual for the top level
dotest cvsadm-18b "cat CVS/Repository" "\."
@@ -10593,9 +12461,9 @@ U dir2d1/sub2d1/file1"
rm -rf CVS 2mod dir2d1
dotest cvsadm-19 "${testcvs} co 2mod 2d2mod" \
-"${PROG} [a-z]*: Updating 2mod
+"${PROG} checkout: Updating 2mod
U 2mod/file2
-${PROG} [a-z]*: Updating dir2d2/sub2d2
+${PROG} checkout: Updating dir2d2/sub2d2
U dir2d2/sub2d2/file2"
# the usual for the top level
dotest cvsadm-19b "cat CVS/Repository" "\."
@@ -10610,9 +12478,9 @@ U dir2d2/sub2d2/file2"
### 1d1mod
dotest cvsadm-20 "${testcvs} co 1d1mod 1d1mod-2" \
-"${PROG} [a-z]*: Updating dir1d1
+"${PROG} checkout: Updating dir1d1
U dir1d1/file1
-${PROG} [a-z]*: Updating dir1d1-2
+${PROG} checkout: Updating dir1d1-2
U dir1d1-2/file1-2"
# the usual for the top level
dotest cvsadm-20b "cat CVS/Repository" "\."
@@ -10623,9 +12491,9 @@ U dir1d1-2/file1-2"
rm -rf CVS dir1d1 dir1d1-2
dotest cvsadm-21 "${testcvs} co 1d1mod 1d2mod" \
-"${PROG} [a-z]*: Updating dir1d1
+"${PROG} checkout: Updating dir1d1
U dir1d1/file1
-${PROG} [a-z]*: Updating dir1d2
+${PROG} checkout: Updating dir1d2
U dir1d2/file2"
# the usual for the top level
dotest cvsadm-21b "cat CVS/Repository" "\."
@@ -10636,9 +12504,9 @@ U dir1d2/file2"
rm -rf CVS dir1d1 dir1d2
dotest cvsadm-22 "${testcvs} co 1d1mod 2d1mod" \
-"${PROG} [a-z]*: Updating dir1d1
+"${PROG} checkout: Updating dir1d1
U dir1d1/file1
-${PROG} [a-z]*: Updating dir2d1/sub2d1
+${PROG} checkout: Updating dir2d1/sub2d1
U dir2d1/sub2d1/file1"
# the usual for the top level
dotest cvsadm-22b "cat CVS/Repository" "\."
@@ -10650,9 +12518,9 @@ U dir2d1/sub2d1/file1"
rm -rf CVS dir1d1 dir2d1
dotest cvsadm-23 "${testcvs} co 1d1mod 2d2mod" \
-"${PROG} [a-z]*: Updating dir1d1
+"${PROG} checkout: Updating dir1d1
U dir1d1/file1
-${PROG} [a-z]*: Updating dir2d2/sub2d2
+${PROG} checkout: Updating dir2d2/sub2d2
U dir2d2/sub2d2/file2"
# the usual for the top level
dotest cvsadm-23b "cat CVS/Repository" "\."
@@ -10667,9 +12535,9 @@ U dir2d2/sub2d2/file2"
### 1d2mod
dotest cvsadm-24 "${testcvs} co 1d2mod 1d2mod-2" \
-"${PROG} [a-z]*: Updating dir1d2
+"${PROG} checkout: Updating dir1d2
U dir1d2/file2
-${PROG} [a-z]*: Updating dir1d2-2
+${PROG} checkout: Updating dir1d2-2
U dir1d2-2/file2-2"
# the usual for the top level
dotest cvsadm-24b "cat CVS/Repository" "\."
@@ -10680,9 +12548,9 @@ U dir1d2-2/file2-2"
rm -rf CVS dir1d2 dir1d2-2
dotest cvsadm-25 "${testcvs} co 1d2mod 2d1mod" \
-"${PROG} [a-z]*: Updating dir1d2
+"${PROG} checkout: Updating dir1d2
U dir1d2/file2
-${PROG} [a-z]*: Updating dir2d1/sub2d1
+${PROG} checkout: Updating dir2d1/sub2d1
U dir2d1/sub2d1/file1"
# the usual for the top level
dotest cvsadm-25b "cat CVS/Repository" "\."
@@ -10694,9 +12562,9 @@ U dir2d1/sub2d1/file1"
rm -rf CVS dir1d2 dir2d1
dotest cvsadm-26 "${testcvs} co 1d2mod 2d2mod" \
-"${PROG} [a-z]*: Updating dir1d2
+"${PROG} checkout: Updating dir1d2
U dir1d2/file2
-${PROG} [a-z]*: Updating dir2d2/sub2d2
+${PROG} checkout: Updating dir2d2/sub2d2
U dir2d2/sub2d2/file2"
# the usual for the top level
dotest cvsadm-26b "cat CVS/Repository" "\."
@@ -10711,9 +12579,9 @@ U dir2d2/sub2d2/file2"
# 2d1mod
dotest cvsadm-27 "${testcvs} co 2d1mod 2d1mod-2" \
-"${PROG} [a-z]*: Updating dir2d1/sub2d1
+"${PROG} checkout: Updating dir2d1/sub2d1
U dir2d1/sub2d1/file1
-${PROG} [a-z]*: Updating dir2d1-2/sub2d1-2
+${PROG} checkout: Updating dir2d1-2/sub2d1-2
U dir2d1-2/sub2d1-2/file1-2"
# the usual for the top level
dotest cvsadm-27b "cat CVS/Repository" "\."
@@ -10726,9 +12594,9 @@ U dir2d1-2/sub2d1-2/file1-2"
rm -rf CVS dir2d1 dir2d1-2
dotest cvsadm-28 "${testcvs} co 2d1mod 2d2mod" \
-"${PROG} [a-z]*: Updating dir2d1/sub2d1
+"${PROG} checkout: Updating dir2d1/sub2d1
U dir2d1/sub2d1/file1
-${PROG} [a-z]*: Updating dir2d2/sub2d2
+${PROG} checkout: Updating dir2d2/sub2d2
U dir2d2/sub2d2/file2"
# the usual for the top level
dotest cvsadm-28b "cat CVS/Repository" "\."
@@ -10744,9 +12612,9 @@ U dir2d2/sub2d2/file2"
# 2d2mod
dotest cvsadm-29 "${testcvs} co 2d2mod 2d2mod-2" \
-"${PROG} [a-z]*: Updating dir2d2/sub2d2
+"${PROG} checkout: Updating dir2d2/sub2d2
U dir2d2/sub2d2/file2
-${PROG} [a-z]*: Updating dir2d2-2/sub2d2-2
+${PROG} checkout: Updating dir2d2-2/sub2d2-2
U dir2d2-2/sub2d2-2/file2-2"
# the usual for the top level
dotest cvsadm-29b "cat CVS/Repository" "\."
@@ -10765,42 +12633,42 @@ U dir2d2-2/sub2d2-2/file2-2"
##################################################
dotest cvsadm-1d3 "${testcvs} co -d dir 1mod" \
-"${PROG} [a-z]*: Updating dir
+"${PROG} checkout: Updating dir
U dir/file1"
dotest cvsadm-1d3b "cat CVS/Repository" "\."
dotest cvsadm-1d3d "cat dir/CVS/Repository" "mod1"
rm -rf CVS dir
dotest cvsadm-1d4 "${testcvs} co -d dir 2mod" \
-"${PROG} [a-z]*: Updating dir
+"${PROG} checkout: Updating dir
U dir/file2"
dotest cvsadm-1d4b "cat CVS/Repository" "\."
dotest cvsadm-1d4d "cat dir/CVS/Repository" "mod2/sub2"
rm -rf CVS dir
dotest cvsadm-1d5 "${testcvs} co -d dir 1d1mod" \
-"${PROG} [a-z]*: Updating dir
+"${PROG} checkout: Updating dir
U dir/file1"
dotest cvsadm-1d5b "cat CVS/Repository" "\."
dotest cvsadm-1d5d "cat dir/CVS/Repository" "mod1"
rm -rf CVS dir
dotest cvsadm-1d6 "${testcvs} co -d dir 1d2mod" \
-"${PROG} [a-z]*: Updating dir
+"${PROG} checkout: Updating dir
U dir/file2"
dotest cvsadm-1d6b "cat CVS/Repository" "\."
dotest cvsadm-1d6d "cat dir/CVS/Repository" "mod2/sub2"
rm -rf CVS dir
dotest cvsadm-1d7 "${testcvs} co -d dir 2d1mod" \
-"${PROG} [a-z]*: Updating dir
+"${PROG} checkout: Updating dir
U dir/file1"
dotest cvsadm-1d7b "cat CVS/Repository" "\."
dotest cvsadm-1d7d "cat dir/CVS/Repository" "mod1"
rm -rf CVS dir
dotest cvsadm-1d8 "${testcvs} co -d dir 2d2mod" \
-"${PROG} [a-z]*: Updating dir
+"${PROG} checkout: Updating dir
U dir/file2"
dotest cvsadm-1d8b "cat CVS/Repository" "\."
dotest cvsadm-1d8d "cat dir/CVS/Repository" "mod2/sub2"
@@ -10813,9 +12681,9 @@ U dir/file2"
### 1mod
dotest cvsadm-1d9 "${testcvs} co -d dir 1mod 1mod-2" \
-"${PROG} [a-z]*: Updating dir/1mod
+"${PROG} checkout: Updating dir/1mod
U dir/1mod/file1
-${PROG} [a-z]*: Updating dir/1mod-2
+${PROG} checkout: Updating dir/1mod-2
U dir/1mod-2/file1-2"
# the usual for the top level
dotest cvsadm-1d9b "cat CVS/Repository" "\."
@@ -10829,9 +12697,9 @@ U dir/1mod-2/file1-2"
# 1mod 2mod redmod bluemod
dotest cvsadm-1d10 "${testcvs} co -d dir 1mod 2mod" \
-"${PROG} [a-z]*: Updating dir/1mod
+"${PROG} checkout: Updating dir/1mod
U dir/1mod/file1
-${PROG} [a-z]*: Updating dir/2mod
+${PROG} checkout: Updating dir/2mod
U dir/2mod/file2"
dotest cvsadm-1d10b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10843,9 +12711,9 @@ U dir/2mod/file2"
rm -rf CVS dir
dotest cvsadm-1d11 "${testcvs} co -d dir 1mod 1d1mod" \
-"${PROG} [a-z]*: Updating dir/1mod
+"${PROG} checkout: Updating dir/1mod
U dir/1mod/file1
-${PROG} [a-z]*: Updating dir/dir1d1
+${PROG} checkout: Updating dir/dir1d1
U dir/dir1d1/file1"
dotest cvsadm-1d11b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10857,9 +12725,9 @@ U dir/dir1d1/file1"
rm -rf CVS dir
dotest cvsadm-1d12 "${testcvs} co -d dir 1mod 1d2mod" \
-"${PROG} [a-z]*: Updating dir/1mod
+"${PROG} checkout: Updating dir/1mod
U dir/1mod/file1
-${PROG} [a-z]*: Updating dir/dir1d2
+${PROG} checkout: Updating dir/dir1d2
U dir/dir1d2/file2"
dotest cvsadm-1d12b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10871,9 +12739,9 @@ U dir/dir1d2/file2"
rm -rf CVS dir
dotest cvsadm-1d13 "${testcvs} co -d dir 1mod 2d1mod" \
-"${PROG} [a-z]*: Updating dir/1mod
+"${PROG} checkout: Updating dir/1mod
U dir/1mod/file1
-${PROG} [a-z]*: Updating dir/dir2d1/sub2d1
+${PROG} checkout: Updating dir/dir2d1/sub2d1
U dir/dir2d1/sub2d1/file1"
dotest cvsadm-1d13b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10886,9 +12754,9 @@ U dir/dir2d1/sub2d1/file1"
rm -rf CVS dir
dotest cvsadm-1d14 "${testcvs} co -d dir 1mod 2d2mod" \
-"${PROG} [a-z]*: Updating dir/1mod
+"${PROG} checkout: Updating dir/1mod
U dir/1mod/file1
-${PROG} [a-z]*: Updating dir/dir2d2/sub2d2
+${PROG} checkout: Updating dir/dir2d2/sub2d2
U dir/dir2d2/sub2d2/file2"
dotest cvsadm-1d14b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10904,9 +12772,9 @@ U dir/dir2d2/sub2d2/file2"
### 2mod
dotest cvsadm-1d15 "${testcvs} co -d dir 2mod 2mod-2" \
-"${PROG} [a-z]*: Updating dir/2mod
+"${PROG} checkout: Updating dir/2mod
U dir/2mod/file2
-${PROG} [a-z]*: Updating dir/2mod-2
+${PROG} checkout: Updating dir/2mod-2
U dir/2mod-2/file2-2"
dotest cvsadm-1d15b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10918,9 +12786,9 @@ U dir/2mod-2/file2-2"
rm -rf CVS dir
dotest cvsadm-1d16 "${testcvs} co -d dir 2mod 1d1mod" \
-"${PROG} [a-z]*: Updating dir/2mod
+"${PROG} checkout: Updating dir/2mod
U dir/2mod/file2
-${PROG} [a-z]*: Updating dir/dir1d1
+${PROG} checkout: Updating dir/dir1d1
U dir/dir1d1/file1"
dotest cvsadm-1d16b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10932,9 +12800,9 @@ U dir/dir1d1/file1"
rm -rf CVS dir
dotest cvsadm-1d17 "${testcvs} co -d dir 2mod 1d2mod" \
-"${PROG} [a-z]*: Updating dir/2mod
+"${PROG} checkout: Updating dir/2mod
U dir/2mod/file2
-${PROG} [a-z]*: Updating dir/dir1d2
+${PROG} checkout: Updating dir/dir1d2
U dir/dir1d2/file2"
dotest cvsadm-1d17b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10946,9 +12814,9 @@ U dir/dir1d2/file2"
rm -rf CVS dir
dotest cvsadm-1d18 "${testcvs} co -d dir 2mod 2d1mod" \
-"${PROG} [a-z]*: Updating dir/2mod
+"${PROG} checkout: Updating dir/2mod
U dir/2mod/file2
-${PROG} [a-z]*: Updating dir/dir2d1/sub2d1
+${PROG} checkout: Updating dir/dir2d1/sub2d1
U dir/dir2d1/sub2d1/file1"
dotest cvsadm-1d18b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10961,9 +12829,9 @@ U dir/dir2d1/sub2d1/file1"
rm -rf CVS dir
dotest cvsadm-1d19 "${testcvs} co -d dir 2mod 2d2mod" \
-"${PROG} [a-z]*: Updating dir/2mod
+"${PROG} checkout: Updating dir/2mod
U dir/2mod/file2
-${PROG} [a-z]*: Updating dir/dir2d2/sub2d2
+${PROG} checkout: Updating dir/dir2d2/sub2d2
U dir/dir2d2/sub2d2/file2"
dotest cvsadm-1d19b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10979,9 +12847,9 @@ U dir/dir2d2/sub2d2/file2"
### 1d1mod
dotest cvsadm-1d20 "${testcvs} co -d dir 1d1mod 1d1mod-2" \
-"${PROG} [a-z]*: Updating dir/dir1d1
+"${PROG} checkout: Updating dir/dir1d1
U dir/dir1d1/file1
-${PROG} [a-z]*: Updating dir/dir1d1-2
+${PROG} checkout: Updating dir/dir1d1-2
U dir/dir1d1-2/file1-2"
dotest cvsadm-1d20b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -10993,9 +12861,9 @@ U dir/dir1d1-2/file1-2"
rm -rf CVS dir
dotest cvsadm-1d21 "${testcvs} co -d dir 1d1mod 1d2mod" \
-"${PROG} [a-z]*: Updating dir/dir1d1
+"${PROG} checkout: Updating dir/dir1d1
U dir/dir1d1/file1
-${PROG} [a-z]*: Updating dir/dir1d2
+${PROG} checkout: Updating dir/dir1d2
U dir/dir1d2/file2"
dotest cvsadm-1d21b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -11007,9 +12875,9 @@ U dir/dir1d2/file2"
rm -rf CVS dir
dotest cvsadm-1d22 "${testcvs} co -d dir 1d1mod 2d1mod" \
-"${PROG} [a-z]*: Updating dir/dir1d1
+"${PROG} checkout: Updating dir/dir1d1
U dir/dir1d1/file1
-${PROG} [a-z]*: Updating dir/dir2d1/sub2d1
+${PROG} checkout: Updating dir/dir2d1/sub2d1
U dir/dir2d1/sub2d1/file1"
dotest cvsadm-1d22b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -11022,9 +12890,9 @@ U dir/dir2d1/sub2d1/file1"
rm -rf CVS dir
dotest cvsadm-1d23 "${testcvs} co -d dir 1d1mod 2d2mod" \
-"${PROG} [a-z]*: Updating dir/dir1d1
+"${PROG} checkout: Updating dir/dir1d1
U dir/dir1d1/file1
-${PROG} [a-z]*: Updating dir/dir2d2/sub2d2
+${PROG} checkout: Updating dir/dir2d2/sub2d2
U dir/dir2d2/sub2d2/file2"
dotest cvsadm-1d23b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -11040,9 +12908,9 @@ U dir/dir2d2/sub2d2/file2"
### 1d2mod
dotest cvsadm-1d24 "${testcvs} co -d dir 1d2mod 1d2mod-2" \
-"${PROG} [a-z]*: Updating dir/dir1d2
+"${PROG} checkout: Updating dir/dir1d2
U dir/dir1d2/file2
-${PROG} [a-z]*: Updating dir/dir1d2-2
+${PROG} checkout: Updating dir/dir1d2-2
U dir/dir1d2-2/file2-2"
dotest cvsadm-1d24b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -11054,9 +12922,9 @@ U dir/dir1d2-2/file2-2"
rm -rf CVS dir
dotest cvsadm-1d25 "${testcvs} co -d dir 1d2mod 2d1mod" \
-"${PROG} [a-z]*: Updating dir/dir1d2
+"${PROG} checkout: Updating dir/dir1d2
U dir/dir1d2/file2
-${PROG} [a-z]*: Updating dir/dir2d1/sub2d1
+${PROG} checkout: Updating dir/dir2d1/sub2d1
U dir/dir2d1/sub2d1/file1"
dotest cvsadm-1d25b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -11069,9 +12937,9 @@ U dir/dir2d1/sub2d1/file1"
rm -rf CVS dir
dotest cvsadm-1d26 "${testcvs} co -d dir 1d2mod 2d2mod" \
-"${PROG} [a-z]*: Updating dir/dir1d2
+"${PROG} checkout: Updating dir/dir1d2
U dir/dir1d2/file2
-${PROG} [a-z]*: Updating dir/dir2d2/sub2d2
+${PROG} checkout: Updating dir/dir2d2/sub2d2
U dir/dir2d2/sub2d2/file2"
dotest cvsadm-1d26b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -11087,9 +12955,9 @@ U dir/dir2d2/sub2d2/file2"
# 2d1mod
dotest cvsadm-1d27 "${testcvs} co -d dir 2d1mod 2d1mod-2" \
-"${PROG} [a-z]*: Updating dir/dir2d1/sub2d1
+"${PROG} checkout: Updating dir/dir2d1/sub2d1
U dir/dir2d1/sub2d1/file1
-${PROG} [a-z]*: Updating dir/dir2d1-2/sub2d1-2
+${PROG} checkout: Updating dir/dir2d1-2/sub2d1-2
U dir/dir2d1-2/sub2d1-2/file1-2"
dotest cvsadm-1d27b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -11104,9 +12972,9 @@ U dir/dir2d1-2/sub2d1-2/file1-2"
rm -rf CVS dir
dotest cvsadm-1d28 "${testcvs} co -d dir 2d1mod 2d2mod" \
-"${PROG} [a-z]*: Updating dir/dir2d1/sub2d1
+"${PROG} checkout: Updating dir/dir2d1/sub2d1
U dir/dir2d1/sub2d1/file1
-${PROG} [a-z]*: Updating dir/dir2d2/sub2d2
+${PROG} checkout: Updating dir/dir2d2/sub2d2
U dir/dir2d2/sub2d2/file2"
dotest cvsadm-1d28b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -11123,9 +12991,9 @@ U dir/dir2d2/sub2d2/file2"
# 2d2mod
dotest cvsadm-1d29 "${testcvs} co -d dir 2d2mod 2d2mod-2" \
-"${PROG} [a-z]*: Updating dir/dir2d2/sub2d2
+"${PROG} checkout: Updating dir/dir2d2/sub2d2
U dir/dir2d2/sub2d2/file2
-${PROG} [a-z]*: Updating dir/dir2d2-2/sub2d2-2
+${PROG} checkout: Updating dir/dir2d2-2/sub2d2-2
U dir/dir2d2-2/sub2d2-2/file2-2"
dotest cvsadm-1d29b "cat CVS/Repository" "\."
# the usual for the dir level
@@ -11153,7 +13021,7 @@ U dir/dir2d2-2/sub2d2-2/file2-2"
mkdir dir
dotest cvsadm-2d3 "${testcvs} co -d dir/dir2 1mod" \
-"${PROG} [a-z]*: Updating dir/dir2
+"${PROG} checkout: Updating dir/dir2
U dir/dir2/file1"
dotest cvsadm-2d3b "cat CVS/Repository" "\."
dotest_fail cvsadm-2d3d "test -f dir/CVS/Repository" ""
@@ -11162,7 +13030,7 @@ U dir/dir2/file1"
mkdir dir
dotest cvsadm-2d4 "${testcvs} co -d dir/dir2 2mod" \
-"${PROG} [a-z]*: Updating dir/dir2
+"${PROG} checkout: Updating dir/dir2
U dir/dir2/file2"
dotest cvsadm-2d4b "cat CVS/Repository" "\."
dotest cvsadm-2d4f "cat dir/dir2/CVS/Repository" "mod2/sub2"
@@ -11170,7 +13038,7 @@ U dir/dir2/file2"
mkdir dir
dotest cvsadm-2d5 "${testcvs} co -d dir/dir2 1d1mod" \
-"${PROG} [a-z]*: Updating dir/dir2
+"${PROG} checkout: Updating dir/dir2
U dir/dir2/file1"
dotest cvsadm-2d5b "cat CVS/Repository" "\."
dotest cvsadm-2d5f "cat dir/dir2/CVS/Repository" "mod1"
@@ -11178,7 +13046,7 @@ U dir/dir2/file1"
mkdir dir
dotest cvsadm-2d6 "${testcvs} co -d dir/dir2 1d2mod" \
-"${PROG} [a-z]*: Updating dir/dir2
+"${PROG} checkout: Updating dir/dir2
U dir/dir2/file2"
dotest cvsadm-2d6b "cat CVS/Repository" "\."
dotest cvsadm-2d6f "cat dir/dir2/CVS/Repository" "mod2/sub2"
@@ -11186,7 +13054,7 @@ U dir/dir2/file2"
mkdir dir
dotest cvsadm-2d7 "${testcvs} co -d dir/dir2 2d1mod" \
-"${PROG} [a-z]*: Updating dir/dir2
+"${PROG} checkout: Updating dir/dir2
U dir/dir2/file1"
dotest cvsadm-2d7b "cat CVS/Repository" "\."
dotest cvsadm-2d7f "cat dir/dir2/CVS/Repository" "mod1"
@@ -11194,7 +13062,7 @@ U dir/dir2/file1"
mkdir dir
dotest cvsadm-2d8 "${testcvs} co -d dir/dir2 2d2mod" \
-"${PROG} [a-z]*: Updating dir/dir2
+"${PROG} checkout: Updating dir/dir2
U dir/dir2/file2"
dotest cvsadm-2d8b "cat CVS/Repository" "\."
dotest cvsadm-2d8f "cat dir/dir2/CVS/Repository" "mod2/sub2"
@@ -11206,35 +13074,35 @@ U dir/dir2/file2"
##################################################
dotest cvsadm-N3 "${testcvs} co -N 1mod" \
-"${PROG} [a-z]*: Updating 1mod
+"${PROG} checkout: Updating 1mod
U 1mod/file1"
dotest cvsadm-N3b "cat CVS/Repository" "\."
dotest cvsadm-N3d "cat 1mod/CVS/Repository" "mod1"
rm -rf CVS 1mod
dotest cvsadm-N4 "${testcvs} co -N 2mod" \
-"${PROG} [a-z]*: Updating 2mod
+"${PROG} checkout: Updating 2mod
U 2mod/file2"
dotest cvsadm-N4b "cat CVS/Repository" "\."
dotest cvsadm-N4d "cat 2mod/CVS/Repository" "mod2/sub2"
rm -rf CVS 2mod
dotest cvsadm-N5 "${testcvs} co -N 1d1mod" \
-"${PROG} [a-z]*: Updating dir1d1
+"${PROG} checkout: Updating dir1d1
U dir1d1/file1"
dotest cvsadm-N5b "cat CVS/Repository" "\."
dotest cvsadm-N5d "cat dir1d1/CVS/Repository" "mod1"
rm -rf CVS dir1d1
dotest cvsadm-N6 "${testcvs} co -N 1d2mod" \
-"${PROG} [a-z]*: Updating dir1d2
+"${PROG} checkout: Updating dir1d2
U dir1d2/file2"
dotest cvsadm-N6b "cat CVS/Repository" "\."
dotest cvsadm-N6d "cat dir1d2/CVS/Repository" "mod2/sub2"
rm -rf CVS dir1d2
dotest cvsadm-N7 "${testcvs} co -N 2d1mod" \
-"${PROG} [a-z]*: Updating dir2d1/sub2d1
+"${PROG} checkout: Updating dir2d1/sub2d1
U dir2d1/sub2d1/file1"
dotest cvsadm-N7b "cat CVS/Repository" "\."
dotest cvsadm-N7d "cat dir2d1/CVS/Repository" "\."
@@ -11242,7 +13110,7 @@ U dir2d1/sub2d1/file1"
rm -rf CVS dir2d1
dotest cvsadm-N8 "${testcvs} co -N 2d2mod" \
-"${PROG} [a-z]*: Updating dir2d2/sub2d2
+"${PROG} checkout: Updating dir2d2/sub2d2
U dir2d2/sub2d2/file2"
dotest cvsadm-N8b "cat CVS/Repository" "\."
dotest cvsadm-N8d "cat dir2d2/CVS/Repository" "mod2"
@@ -11252,7 +13120,7 @@ U dir2d2/sub2d2/file2"
## the ones in one-deep directories
dotest cvsadm-N1d3 "${testcvs} co -N -d dir 1mod" \
-"${PROG} [a-z]*: Updating dir/1mod
+"${PROG} checkout: Updating dir/1mod
U dir/1mod/file1"
dotest cvsadm-N1d3b "cat CVS/Repository" "\."
dotest cvsadm-N1d3d "cat dir/CVS/Repository" "\."
@@ -11260,7 +13128,7 @@ U dir/1mod/file1"
rm -rf CVS dir
dotest cvsadm-N1d4 "${testcvs} co -N -d dir 2mod" \
-"${PROG} [a-z]*: Updating dir/2mod
+"${PROG} checkout: Updating dir/2mod
U dir/2mod/file2"
dotest cvsadm-N1d4b "cat CVS/Repository" "\."
dotest cvsadm-N1d4d "cat dir/CVS/Repository" "mod2"
@@ -11268,7 +13136,7 @@ U dir/2mod/file2"
rm -rf CVS dir
dotest cvsadm-N1d5 "${testcvs} co -N -d dir 1d1mod" \
-"${PROG} [a-z]*: Updating dir/dir1d1
+"${PROG} checkout: Updating dir/dir1d1
U dir/dir1d1/file1"
dotest cvsadm-N1d5b "cat CVS/Repository" "\."
dotest cvsadm-N1d5d "cat dir/CVS/Repository" "\."
@@ -11276,7 +13144,7 @@ U dir/dir1d1/file1"
rm -rf CVS dir
dotest cvsadm-N1d6 "${testcvs} co -N -d dir 1d2mod" \
-"${PROG} [a-z]*: Updating dir/dir1d2
+"${PROG} checkout: Updating dir/dir1d2
U dir/dir1d2/file2"
dotest cvsadm-N1d6b "cat CVS/Repository" "\."
dotest cvsadm-N1d6d "cat dir/CVS/Repository" "mod2"
@@ -11284,7 +13152,7 @@ U dir/dir1d2/file2"
rm -rf CVS dir
dotest cvsadm-N1d7 "${testcvs} co -N -d dir 2d1mod" \
-"${PROG} [a-z]*: Updating dir/dir2d1/sub2d1
+"${PROG} checkout: Updating dir/dir2d1/sub2d1
U dir/dir2d1/sub2d1/file1"
dotest cvsadm-N1d7b "cat CVS/Repository" "\."
dotest cvsadm-N1d7d "cat dir/CVS/Repository" "CVSROOT/Emptydir"
@@ -11293,7 +13161,7 @@ U dir/dir2d1/sub2d1/file1"
rm -rf CVS dir
dotest cvsadm-N1d8 "${testcvs} co -N -d dir 2d2mod" \
-"${PROG} [a-z]*: Updating dir/dir2d2/sub2d2
+"${PROG} checkout: Updating dir/dir2d2/sub2d2
U dir/dir2d2/sub2d2/file2"
dotest cvsadm-N1d8b "cat CVS/Repository" "\."
dotest cvsadm-N1d8d "cat dir/CVS/Repository" "\."
@@ -11306,7 +13174,7 @@ U dir/dir2d2/sub2d2/file2"
mkdir dir
dotest cvsadm-N2d3 "${testcvs} co -N -d dir/dir2 1mod" \
-"${PROG} [a-z]*: Updating dir/dir2/1mod
+"${PROG} checkout: Updating dir/dir2/1mod
U dir/dir2/1mod/file1"
dotest cvsadm-N2d3b "cat CVS/Repository" "\."
dotest cvsadm-N2d3f "cat dir/dir2/CVS/Repository" "\."
@@ -11315,7 +13183,7 @@ U dir/dir2/1mod/file1"
mkdir dir
dotest cvsadm-N2d4 "${testcvs} co -N -d dir/dir2 2mod" \
-"${PROG} [a-z]*: Updating dir/dir2/2mod
+"${PROG} checkout: Updating dir/dir2/2mod
U dir/dir2/2mod/file2"
dotest cvsadm-N2d4b "cat CVS/Repository" "\."
dotest cvsadm-N2d4f "cat dir/dir2/CVS/Repository" "mod2"
@@ -11324,7 +13192,7 @@ U dir/dir2/2mod/file2"
mkdir dir
dotest cvsadm-N2d5 "${testcvs} co -N -d dir/dir2 1d1mod" \
-"${PROG} [a-z]*: Updating dir/dir2/dir1d1
+"${PROG} checkout: Updating dir/dir2/dir1d1
U dir/dir2/dir1d1/file1"
dotest cvsadm-N2d5b "cat CVS/Repository" "\."
dotest cvsadm-N2d5f "cat dir/dir2/CVS/Repository" "\."
@@ -11333,7 +13201,7 @@ U dir/dir2/dir1d1/file1"
mkdir dir
dotest cvsadm-N2d6 "${testcvs} co -N -d dir/dir2 1d2mod" \
-"${PROG} [a-z]*: Updating dir/dir2/dir1d2
+"${PROG} checkout: Updating dir/dir2/dir1d2
U dir/dir2/dir1d2/file2"
dotest cvsadm-N2d6b "cat CVS/Repository" "\."
dotest cvsadm-N2d6f "cat dir/dir2/CVS/Repository" "mod2"
@@ -11342,7 +13210,7 @@ U dir/dir2/dir1d2/file2"
mkdir dir
dotest cvsadm-N2d7 "${testcvs} co -N -d dir/dir2 2d1mod" \
-"${PROG} [a-z]*: Updating dir/dir2/dir2d1/sub2d1
+"${PROG} checkout: Updating dir/dir2/dir2d1/sub2d1
U dir/dir2/dir2d1/sub2d1/file1"
dotest cvsadm-N2d7b "cat CVS/Repository" "\."
dotest cvsadm-N2d7f "cat dir/dir2/CVS/Repository" "CVSROOT/Emptydir"
@@ -11353,7 +13221,7 @@ U dir/dir2/dir2d1/sub2d1/file1"
mkdir dir
dotest cvsadm-N2d8 "${testcvs} co -N -d dir/dir2 2d2mod" \
-"${PROG} [a-z]*: Updating dir/dir2/dir2d2/sub2d2
+"${PROG} checkout: Updating dir/dir2/dir2d2/sub2d2
U dir/dir2/dir2d2/sub2d2/file2"
dotest cvsadm-N2d8b "cat CVS/Repository" "\."
dotest cvsadm-N2d8f "cat dir/dir2/CVS/Repository" "\."
@@ -11377,7 +13245,7 @@ U dir/dir2/dir2d2/sub2d2/file2"
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
rm -rf CVSROOT CVS
@@ -11414,25 +13282,25 @@ Checking in CVSROOT/modules;
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database" \
-"${PROG} [a-z]*: Examining CVSROOT"
+${PROG} commit: Rebuilding administrative file database" \
+"${PROG} commit: Examining CVSROOT"
rm -rf CVS CVSROOT
mkdir ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/moda
# Populate. Not sure we really need to do this.
dotest emptydir-3 "${testcvs} -q co -l ." ""
dotest emptydir-3a "${testcvs} co mod1 moda" \
-"${PROG} [a-z]*: Updating mod1
-${PROG} [a-z]*: Updating moda"
+"${PROG} checkout: Updating mod1
+${PROG} checkout: Updating moda"
echo "file1" > mod1/file1
mkdir moda/modasub
dotest emptydir-3b "${testcvs} add moda/modasub" \
"Directory ${CVSROOT_DIRNAME}/moda/modasub added to the repository"
echo "filea" > moda/modasub/filea
dotest emptydir-4 "${testcvs} add mod1/file1 moda/modasub/filea" \
-"${PROG} [a-z]*: scheduling file .mod1/file1. for addition
-${PROG} [a-z]*: scheduling file .moda/modasub/filea. for addition
-${PROG} [a-z]*: use '${PROG} commit' to add these files permanently"
+"${PROG} add: scheduling file .mod1/file1. for addition
+${PROG} add: scheduling file .moda/modasub/filea. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest emptydir-5 "${testcvs} -q ci -m yup" \
"RCS file: ${CVSROOT_DIRNAME}/mod1/file1,v
done
@@ -11450,7 +13318,7 @@ done"
# End Populate.
dotest emptydir-6 "${testcvs} co 2d1mod" \
-"${PROG} [a-z]*: Updating dir2d1/sub/sub2d1
+"${PROG} checkout: Updating dir2d1/sub/sub2d1
U dir2d1/sub/sub2d1/file1"
cd dir2d1
touch emptyfile
@@ -11459,7 +13327,7 @@ U dir2d1/sub/sub2d1/file1"
# the working directory doesn't correspond to anything in
# the repository.
dotest_fail emptydir-7 "${testcvs} add emptyfile" \
-"${PROG} \[[a-z]* aborted\]: cannot add to ${CVSROOT_DIRNAME}/CVSROOT/Emptydir"
+"${PROG} \[add aborted\]: cannot add to ${CVSROOT_DIRNAME}/CVSROOT/Emptydir"
mkdir emptydir
dotest_fail emptydir-8 "${testcvs} add emptydir" \
"${PROG} \[[a-z]* aborted\]: cannot add to ${CVSROOT_DIRNAME}/CVSROOT/Emptydir"
@@ -11489,13 +13357,29 @@ U dir2d1/sub/sub2d1/file1"
# test.
dotest emptydir-13 "cat dir2d1/CVS/Repository" "moda"
dotest_fail emptydir-14 "${testcvs} co comb" \
-"${PROG} [a-z]*: existing repository ${CVSROOT_DIRNAME}/moda/modasub does not match ${TESTDIR}/cvsroot/mod1
-${PROG} [a-z]*: ignoring module 2d1modb
-${PROG} [a-z]*: Updating dir2d1/suba"
+"${PROG} checkout: existing repository ${CVSROOT_DIRNAME}/moda/modasub does not match ${CVSROOT_DIRNAME}/mod1
+${PROG} checkout: ignoring module 2d1modb
+${PROG} checkout: Updating dir2d1/suba"
dotest emptydir-15 "cat dir2d1/CVS/Repository" "moda"
cd ..
- rm -r 1 2
+ # Test the effect of a non-cvs directory already existing with the
+ # same name as one in the modules file.
+ mkdir 3; cd 3
+ mkdir dir2d1
+ dotest emptydir-16 "${testcvs} co 2d1mod" \
+"${PROG} checkout: Updating dir2d1/sub/sub2d1
+U dir2d1/sub/sub2d1/file1"
+ dotest emptydir-17 "test -d dir2d1/CVS"
+
+ # clean up
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ cd ..
+ rm -r 1 2 3
rm -rf ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/moda
# I guess for the moment the convention is going to be
# that we don't need to remove ${CVSROOT_DIRNAME}/CVSROOT/Emptydir
@@ -11513,21 +13397,21 @@ ${PROG} [a-z]*: Updating dir2d1/suba"
# Create a few modules to use
mkdir ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/mod2
dotest abspath-1a "${testcvs} co mod1 mod2" \
-"${PROG} [a-z]*: Updating mod1
-${PROG} [a-z]*: Updating mod2"
+"${PROG} checkout: Updating mod1
+${PROG} checkout: Updating mod2"
# Populate the module
echo "file1" > mod1/file1
echo "file2" > mod2/file2
cd mod1
dotest abspath-1ba "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use '${PROG} commit' to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
cd ..
cd mod2
dotest abspath-1bb "${testcvs} add file2" \
-"${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use '${PROG} commit' to add this file permanently"
+"${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
cd ..
dotest abspath-1c "${testcvs} ci -m yup mod1 mod2" \
@@ -11552,13 +13436,13 @@ done"
# Try checking out the module in a local directory
if $remote; then
dotest_fail abspath-2a "${testcvs} co -d ${TESTDIR}/1 mod1" \
-"${PROG} \[server aborted\]: absolute pathname .${TESTDIR}/1. illegal for server"
+"${PROG} \[checkout aborted\]: absolute pathname .${TESTDIR}/1. illegal for server"
dotest abspath-2a-try2 "${testcvs} co -d 1 mod1" \
-"${PROG} [a-z]*: Updating 1
+"${PROG} checkout: Updating 1
U 1/file1"
else
dotest abspath-2a "${testcvs} co -d ${TESTDIR}/1 mod1" \
-"${PROG} [a-z]*: Updating ${TESTDIR}/1
+"${PROG} checkout: Updating ${TESTDIR}/1
U ${TESTDIR}/1/file1"
fi # remote workaround
@@ -11590,16 +13474,16 @@ U ${TESTDIR}/1/file1"
# a bug, it should only need to exist on the client side.
# See also cvsadm-2d3.
dotest_fail abspath-3a "${testcvs} co -d 1/2 mod1" \
-"${PROG} \[server aborted\]: could not change directory to requested checkout directory .1.: No such file or directory"
+"${PROG} \[checkout aborted\]: could not change directory to requested checkout directory .1.: No such file or directory"
cd 1
dotest abspath-3a-try2 "${testcvs} co -d 2 mod1" \
-"${PROG} [a-z]*: Updating 2
+"${PROG} checkout: Updating 2
U 2/file1"
cd ..
rm -rf 1/CVS
else
dotest abspath-3a "${testcvs} co -d ${TESTDIR}/1/2 mod1" \
-"${PROG} [a-z]*: Updating ${TESTDIR}/1/2
+"${PROG} checkout: Updating ${TESTDIR}/1/2
U ${TESTDIR}/1/2/file1"
fi # remote workaround
dotest abspath-3b "cat ${TESTDIR}/1/2/CVS/Repository" "mod1"
@@ -11616,13 +13500,9 @@ U ${TESTDIR}/1/2/file1"
# Now try someplace where we don't have permission.
mkdir ${TESTDIR}/barf
chmod -w ${TESTDIR}/barf
- if $remote; then
dotest_fail abspath-4r "${testcvs} co -d ${TESTDIR}/barf/sub mod1" \
-"${PROG} \[server aborted\]: absolute pathname .${TESTDIR}/barf/sub. illegal for server"
- else
- dotest_fail abspath-4 "${testcvs} co -d ${TESTDIR}/barf/sub mod1" \
-"${PROG} \[[a-z]* aborted\]: cannot make directory sub: No such file or directory"
- fi
+"${PROG} \[checkout aborted\]: absolute pathname .${TESTDIR}/barf/sub. illegal for server" \
+"${PROG} \[checkout aborted\]: cannot make directory sub: Permission denied"
chmod +w ${TESTDIR}/barf
rmdir ${TESTDIR}/barf
# Done. Nothing to clean up.
@@ -11631,15 +13511,15 @@ U ${TESTDIR}/1/2/file1"
# Try checking out two modules into the same directory.
if $remote; then
dotest abspath-5ar "${testcvs} co -d 1 mod1 mod2" \
-"${PROG} [a-z]*: Updating 1/mod1
+"${PROG} checkout: Updating 1/mod1
U 1/mod1/file1
-${PROG} [a-z]*: Updating 1/mod2
+${PROG} checkout: Updating 1/mod2
U 1/mod2/file2"
else
dotest abspath-5a "${testcvs} co -d ${TESTDIR}/1 mod1 mod2" \
-"${PROG} [a-z]*: Updating ${TESTDIR}/1/mod1
+"${PROG} checkout: Updating ${TESTDIR}/1/mod1
U ${TESTDIR}/1/mod1/file1
-${PROG} [a-z]*: Updating ${TESTDIR}/1/mod2
+${PROG} checkout: Updating ${TESTDIR}/1/mod2
U ${TESTDIR}/1/mod2/file2"
fi # end remote workaround
dotest abspath-5b "cat ${TESTDIR}/1/CVS/Repository" "\."
@@ -11652,21 +13532,21 @@ U ${TESTDIR}/1/mod2/file2"
# Try checking out the top-level module.
if $remote; then
dotest abspath-6ar "${testcvs} co -d 1 ." \
-"${PROG} [a-z]*: Updating 1
-${PROG} [a-z]*: Updating 1/CVSROOT
+"${PROG} checkout: Updating 1
+${PROG} checkout: Updating 1/CVSROOT
${DOTSTAR}
-${PROG} [a-z]*: Updating 1/mod1
+${PROG} checkout: Updating 1/mod1
U 1/mod1/file1
-${PROG} [a-z]*: Updating 1/mod2
+${PROG} checkout: Updating 1/mod2
U 1/mod2/file2"
else
dotest abspath-6a "${testcvs} co -d ${TESTDIR}/1 ." \
-"${PROG} [a-z]*: Updating ${TESTDIR}/1
-${PROG} [a-z]*: Updating ${TESTDIR}/1/CVSROOT
+"${PROG} checkout: Updating ${TESTDIR}/1
+${PROG} checkout: Updating ${TESTDIR}/1/CVSROOT
${DOTSTAR}
-${PROG} [a-z]*: Updating ${TESTDIR}/1/mod1
+${PROG} checkout: Updating ${TESTDIR}/1/mod1
U ${TESTDIR}/1/mod1/file1
-${PROG} [a-z]*: Updating ${TESTDIR}/1/mod2
+${PROG} checkout: Updating ${TESTDIR}/1/mod2
U ${TESTDIR}/1/mod2/file2"
fi # end of remote workaround
dotest abspath-6b "cat ${TESTDIR}/1/CVS/Repository" "\."
@@ -11682,8 +13562,8 @@ U ${TESTDIR}/1/mod2/file2"
cd 1
if $remote; then
dotest_fail abspath-7ar "${testcvs} -q co -d ../2 mod2" \
-"${PROG} server: protocol error: .\.\./2. contains more leading \.\.
-${PROG} \[server aborted\]: than the 0 which Max-dotdot specified"
+"${PROG} checkout: protocol error: .\.\./2. contains more leading \.\.
+${PROG} \[checkout aborted\]: than the 0 which Max-dotdot specified"
cd ..
dotest abspath-7a-try2r "${testcvs} -q co -d 2 mod2" \
"U 2/file2"
@@ -11718,17 +13598,28 @@ ${PROG} \[server aborted\]: than the 0 which Max-dotdot specified"
;;
+
+
+ abspath2)
+ # More absolute path checks. The following used to attempt to create
+ # directories in /:
+ #
+ # $ cvs -d:fork:/cvsroot co /foo
+ # 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" \
+"$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)"
+ ;;
+
+
+
toplevel)
# test the feature that cvs creates a CVS subdir also for
# the toplevel directory
- # Some test, somewhere, is creating Emptydir. That test
- # should, perhaps, clean up for itself, but I don't know which
- # one it is (cvsadm, emptydir, &c).
- # (On the other hand, should CVS care whether there is an
- # Emptydir? That would seem a bit odd).
- rm -rf ${CVSROOT_DIRNAME}/CVSROOT/Emptydir
-
# First set the TopLevelAdmin setting.
mkdir 1; cd 1
dotest toplevel-1a "${testcvs} -q co CVSROOT/config" \
@@ -11740,7 +13631,7 @@ ${PROG} \[server aborted\]: than the 0 which Max-dotdot specified"
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../..
rm -r 1
@@ -11754,8 +13645,8 @@ Directory ${CVSROOT_DIRNAME}/second-dir added to the repository"
touch file1
dotest toplevel-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest toplevel-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/top-dir/file1,v
done
@@ -11768,8 +13659,8 @@ done"
cd second-dir
touch file2
dotest toplevel-3s "${testcvs} add file2" \
-"${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest toplevel-4s "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/second-dir/file2,v
done
@@ -11781,20 +13672,20 @@ done"
cd ../..
rm -r 1; mkdir 1; cd 1
dotest toplevel-5 "${testcvs} co top-dir" \
-"${PROG} [a-z]*: Updating top-dir
+"${PROG} checkout: Updating top-dir
U top-dir/file1"
dotest toplevel-6 "${testcvs} update top-dir" \
-"${PROG} [a-z]*: Updating top-dir"
+"${PROG} update: Updating top-dir"
dotest toplevel-7 "${testcvs} update" \
-"${PROG} [a-z]*: Updating \.
-${PROG} [a-z]*: Updating top-dir"
+"${PROG} update: Updating \.
+${PROG} update: Updating top-dir"
dotest toplevel-8 "${testcvs} update -d top-dir" \
-"${PROG} [a-z]*: Updating top-dir"
+"${PROG} update: Updating top-dir"
# There is some sentiment that
- # "${PROG} [a-z]*: Updating \.
- # ${PROG} [a-z]*: Updating top-dir"
+ # "${PROG} update: Updating \.
+ # ${PROG} update: Updating top-dir"
# is correct but it isn't clear why that would be correct instead
# of the remote CVS behavior (which also updates CVSROOT).
#
@@ -11804,15 +13695,15 @@ ${PROG} [a-z]*: Updating top-dir"
# be present or absent depending on whether we ran the "ignore"
# test or not.
dotest toplevel-9 "${testcvs} update -d" \
-"${PROG} [a-z]*: Updating \.
-${PROG} [a-z]*: Updating CVSROOT
+"${PROG} update: Updating \.
+${PROG} update: Updating CVSROOT
${DOTSTAR}
-${PROG} [a-z]*: Updating top-dir"
+${PROG} update: Updating top-dir"
cd ..
rm -r 1; mkdir 1; cd 1
dotest toplevel-10 "${testcvs} co top-dir" \
-"${PROG} [a-z]*: Updating top-dir
+"${PROG} checkout: Updating top-dir
U top-dir/file1"
# This tests more or less the same thing, in a particularly
@@ -11826,17 +13717,22 @@ U top-dir/file1"
# directory itself was created with 1.9 or older).
rm -r CVS
# Now set the permissions so we can't recreate it.
- chmod -w ../1
+ if test -n "$remotehost"; then
+ # Cygwin again.
+ $CVS_RSH $remotehost "chmod -w $TESTDIR/1"
+ else
+ chmod -w ../1
+ fi
# Now see whether CVS has trouble because it can't create CVS.
# First string is for local, second is for remote.
dotest toplevel-12 "${testcvs} co top-dir" \
-"${PROG} [a-z]*: warning: cannot make directory CVS in \.: Permission denied
-${PROG} [a-z]*: Updating top-dir" \
-"${PROG} [a-z]*: warning: cannot make directory CVS in \.: Permission denied
-${PROG} [a-z]*: warning: cannot make directory CVS in \.: Permission denied
-${PROG} [a-z]*: in directory \.:
-${PROG} [a-z]*: cannot open CVS/Entries for reading: No such file or directory
-${PROG} [a-z]*: Updating top-dir"
+"${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"
chmod +w ../1
@@ -11849,7 +13745,7 @@ ${PROG} [a-z]*: Updating top-dir"
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../..
rm -r 1
@@ -11870,7 +13766,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../..
rm -r 1
@@ -11885,8 +13781,8 @@ Directory ${CVSROOT_DIRNAME}/second-dir added to the repository"
touch file1
dotest toplevel2-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest toplevel2-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/top-dir/file1,v
done
@@ -11899,8 +13795,8 @@ done"
cd second-dir
touch file2
dotest toplevel2-3s "${testcvs} add file2" \
-"${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest toplevel2-4s "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/second-dir/file2,v
done
@@ -11912,24 +13808,24 @@ done"
cd ../..
rm -r 1; mkdir 1; cd 1
dotest toplevel2-5 "${testcvs} co top-dir" \
-"${PROG} [a-z]*: Updating top-dir
+"${PROG} checkout: Updating top-dir
U top-dir/file1"
dotest toplevel2-6 "${testcvs} update top-dir" \
-"${PROG} [a-z]*: Updating top-dir"
+"${PROG} update: Updating top-dir"
dotest toplevel2-7 "${testcvs} update" \
-"${PROG} [a-z]*: Updating top-dir"
+"${PROG} update: Updating top-dir"
dotest toplevel2-8 "${testcvs} update -d top-dir" \
-"${PROG} [a-z]*: Updating top-dir"
+"${PROG} update: Updating top-dir"
# Contrast this with toplevel-9, which has TopLevelAdmin=yes.
dotest toplevel2-9 "${testcvs} update -d" \
-"${PROG} [a-z]*: Updating top-dir"
+"${PROG} update: Updating top-dir"
cd ..
rm -r 1; mkdir 1; cd 1
dotest toplevel2-10 "${testcvs} co top-dir" \
-"${PROG} [a-z]*: Updating top-dir
+"${PROG} checkout: Updating top-dir
U top-dir/file1"
# This tests more or less the same thing, in a particularly
# "real life" example. With TopLevelAdmin=yes, this command
@@ -11945,19 +13841,72 @@ U top-dir/file1"
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../..
rm -r 1
rm -rf ${CVSROOT_DIRNAME}/top-dir ${CVSROOT_DIRNAME}/second-dir
;;
+
+
+ top-level)
+ # FIXCVS:
+ # This test confirms a bug that exists in the r* commands currently
+ # when run against the top-level project.
+ #
+ # The assertion failure is something like:
+ # do_recursion: Assertion \`strstr (repository, \"/\./\") == ((void \*)0)' failed\..*"
+ dotest_fail top-level-1 "$testcvs rlog ." \
+"${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}"
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+ ;;
+
+
+
checkout_repository)
- dotest_fail check_repository-1 "${testcvs} co -d ${CVSROOT_DIRNAME} CVSROOT" \
-"${PROG} \[checkout aborted\]: Cannot check out files into the repository itself"
+ dotest_fail checkout_repository-1 \
+"${testcvs} co -d ${CVSROOT_DIRNAME} CVSROOT" \
+"${PROG} \[checkout aborted\]: Cannot check out files into the repository itself" \
+"${PROG} \[checkout aborted\]: absolute pathname \`${CVSROOT_DIRNAME}' illegal for server"
+
+ # The behavior of the client/server test below should be correct.
+ # The CVS client currently has no way of knowing that the client and
+ # server are the same machine and thus skips the $CVSROOT checks.
+ # I think checking for this case in CVS would be bloat since this
+ # should be a fairly rare occurance.
cd ${CVSROOT_DIRNAME}
- dotest_fail check_repository-2 "${testcvs} co CVSROOT" \
-"${PROG} \[checkout aborted\]: Cannot check out files into the repository itself"
- dotest check_repository-3 "${testcvs} co -p CVSROOT/modules >/dev/null" \
+ dotest_fail checkout_repository-2 "${testcvs} co CVSROOT" \
+"${PROG} \[checkout aborted\]: Cannot check out files into the repository itself" \
+"${PROG} checkout: Updating CVSROOT
+${PROG} checkout: move away CVSROOT/checkoutlist; it is in the way
+C CVSROOT/checkoutlist
+${PROG} checkout: move away CVSROOT/commitinfo; it is in the way
+C CVSROOT/commitinfo
+${PROG} checkout: move away CVSROOT/config; it is in the way
+C CVSROOT/config
+${PROG} checkout: move away CVSROOT/cvswrappers; it is in the way
+C CVSROOT/cvswrappers
+${PROG} checkout: move away CVSROOT/editinfo; it is in the way
+C CVSROOT/editinfo
+${PROG} checkout: move away CVSROOT/loginfo; it is in the way
+C CVSROOT/loginfo
+${PROG} checkout: move away CVSROOT/modules; it is in the way
+C CVSROOT/modules
+${PROG} checkout: move away CVSROOT/notify; it is in the way
+C CVSROOT/notify
+${PROG} checkout: move away CVSROOT/rcsinfo; it is in the way
+C CVSROOT/rcsinfo
+${PROG} checkout: move away CVSROOT/taginfo; it is in the way
+C CVSROOT/taginfo
+${PROG} checkout: move away CVSROOT/verifymsg; it is in the way
+C CVSROOT/verifymsg"
+
+ dotest checkout_repository-3 \
+"${testcvs} co -p CVSROOT/modules >/dev/null" \
"===================================================================
Checking out CVSROOT/modules
RCS: ${CVSROOT_DIRNAME}/CVSROOT/modules,v
@@ -12045,9 +13994,9 @@ EOF
cd first-dir
touch file1 file2
dotest editor-3 "${testcvs} add file1 file2" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest editor-4 "${testcvs} -e ${TESTDIR}/editme -q ci" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -12245,6 +14194,97 @@ Log message unchanged or not specified
a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs
Action: (continue) ${PROG} \[[a-z]* aborted\]: aborted by user"
+ # Test CVS's response to a log message that is zero bytes
+ # in length. This caused core dumps in cvs 1.11.5 on Solaris
+ # hosts.
+ cd ..
+ dotest editor-emptylog-continue-1 "${testcvs} -q co CVSROOT/loginfo" \
+"U CVSROOT/loginfo"
+
+ cd CVSROOT
+ echo 'DEFAULT (echo Start-Log;cat;echo End-Log) >> \$CVSROOT/CVSROOT/commitlog' > loginfo
+ dotest editor-emptylog-continue-2 "${testcvs} commit -m add loginfo" \
+"Checking in loginfo;
+${CVSROOT_DIRNAME}/CVSROOT/loginfo,v <-- loginfo
+new revision: 1\.2; previous revision: 1\.1
+done
+${PROG} commit: Rebuilding administrative file database"
+
+ cd ../first-dir
+ cat >${TESTDIR}/editme <<EOF
+#!${TESTSHELL}
+sleep 1
+cp /dev/null \$1
+exit 1
+EOF
+ chmod +x ${TESTDIR}/editme
+ dotest editor-emptylog-continue-3 "echo c |${testcvs} -e ${TESTDIR}/editme ci -f file1" \
+"${PROG} [a-z]*: warning: editor session failed
+
+Log message unchanged or not specified
+a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs
+Action: (continue) Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+new revision: 1\.2; previous revision: 1\.1
+done"
+ # The loginfo Log message should be an empty line and not "(null)"
+ # which is what some fprintf() implementations do with "%s"
+ # format and a NULL pointer...
+ if $remote; then
+ dotest editor-emptylog-continue-4r \
+"cat ${CVSROOT_DIRNAME}/CVSROOT/commitlog" \
+"Start-Log
+Update of ${CVSROOT_DIRNAME}/first-dir
+In directory ${hostname}:${TMPDIR}/cvs-serv[0-9a-z]*
+
+Modified Files:
+ file1
+Log Message:
+
+End-Log"
+ else
+ dotest editor-emptylog-continue-4 \
+"cat ${CVSROOT_DIRNAME}/CVSROOT/commitlog" \
+"Start-Log
+Update of ${CVSROOT_DIRNAME}/first-dir
+In directory ${hostname}:${TESTDIR}/1/first-dir
+
+Modified Files:
+ file1
+Log Message:
+
+End-Log"
+ fi
+ # There should have an empty log message at this point
+ dotest editor-emptylog-continue-5 "${testcvs} log -N -r1.2 file1" \
+"
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+Working file: file1
+head: 1\.2
+branch:
+locks: strict
+access list:
+keyword substitution: kv
+total revisions: 3; selected revisions: 1
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: +0 -0
+\*\*\* empty log message \*\*\*
+============================================================================="
+
+ # clean up
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ # restore the default loginfo script
+ rm -f ${CVSROOT_DIRNAME}/CVSROOT/loginfo,v \
+ ${CVSROOT_DIRNAME}/CVSROOT/loginfo \
+ ${CVSROOT_DIRNAME}/CVSROOT/commitlog
+ dotest editor-emptylog-continue-cleanup-1 "${testcvs} init" ''
+
cd ../..
rm -r 1
rm ${TESTDIR}/editme
@@ -12295,11 +14335,20 @@ Action: (continue) ${PROG} \[[a-z]* aborted\]: aborted by user"
fi
cd ../../2/1dir
- dotest 168 "${testcvs} -q update" \
-"${PROG} [a-z]*: foo is no longer in the repository
+ # The second case in the local and remote versions of errmsg1-168
+ # below happens on Cygwin under Windows, where write privileges
+ # aren't enforced properly.
+ if $remote; then
+ dotest errmsg1-168r "${testcvs} -q update" \
+"${PROG} update: foo is no longer in the repository
+${PROG} update: unable to remove \./foo: Permission denied" \
+"${PROG} update: foo is no longer in the repository"
+ else
+ dotest errmsg1-168 "${testcvs} -q update" \
+"${PROG} update: foo is no longer in the repository
${PROG} update: unable to remove foo: Permission denied" \
-"${PROG} [a-z]*: foo is no longer in the repository
-${PROG} update: unable to remove \./foo: Permission denied"
+"${PROG} update: foo is no longer in the repository"
+ fi
cd ..
chmod u+w 1dir
@@ -12332,9 +14381,9 @@ ${PROG} update: unable to remove \./foo: Permission denied"
# special file" message fits this pattern, at
# least currently.
dotest_fail errmsg2-4 "${testcvs} add CVS file1" \
-"${PROG} [a-z]*: cannot add special file .CVS.; skipping
-${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: cannot add special file .CVS.; skipping
+${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
# I'm not sure these tests completely convey the various strange
# behaviors that CVS had before it specially checked for "." and
# "..". Suffice it to say that these are unlikely to work right
@@ -12370,9 +14419,9 @@ ${PROG} \[[a-z]* aborted\]: correct above errors first!"
touch file10
mkdir sdir10
dotest errmsg2-10 "${testcvs} add file10 sdir10" \
-"${PROG} [a-z]*: scheduling file .file10. for addition
+"${PROG} add: scheduling file .file10. for addition
Directory ${CVSROOT_DIRNAME}/first-dir/sdir10 added to the repository
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest errmsg2-11 "${testcvs} -q ci -m add-file10" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file10,v
done
@@ -12394,12 +14443,12 @@ done"
touch first-dir/sdir10/ssdir/ssfile
dotest errmsg2-14 \
"${testcvs} add first-dir/sdir10/ssdir/ssfile" \
-"${PROG} [a-z]*: scheduling file .first-dir/sdir10/ssdir/ssfile. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .first-dir/sdir10/ssdir/ssfile. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
touch first-dir/file15
dotest errmsg2-15 "${testcvs} add first-dir/file15" \
-"${PROG} [a-z]*: scheduling file .first-dir/file15. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .first-dir/file15. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
# Now the case where we try to give it a directory which is not
# under CVS control.
@@ -12410,9 +14459,9 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
# message (e.g. the one from local CVS). But at least it is an
# error message.
dotest_fail errmsg2-16 "${testcvs} add bogus-dir/file16" \
-"${PROG} [a-z]*: in directory bogus-dir:
-${PROG} \[[a-z]* aborted\]: there is no version here; do .${PROG} checkout. first" \
-"${PROG} [a-z]*: cannot open CVS/Entries for reading: No such file or directory
+"${PROG} add: in directory bogus-dir:
+${PROG} \[add aborted\]: there is no version here; do .${PROG} checkout. first" \
+"${PROG} add: cannot open CVS/Entries for reading: No such file or directory
${PROG} \[add aborted\]: no repository"
rm -r bogus-dir
@@ -12439,9 +14488,9 @@ done"
if $remote; then :; else
cd ${CVSROOT_DIRNAME}
dotest_fail errmsg2-20 "${testcvs} import -mtest . A B" \
-"${PROG} \[[a-z]* aborted\]: attempt to import the repository"
+"${PROG} \[import aborted\]: attempt to import the repository"
dotest_fail errmsg2-21 "${testcvs} import -mtest first-dir A B" \
-"${PROG} \[[a-z]* aborted\]: attempt to import the repository"
+"${PROG} \[import aborted\]: attempt to import the repository"
fi
cd ..
@@ -12470,12 +14519,12 @@ done"
# to test some other messages
touch file1
dotest adderrmsg-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
# add it twice
dotest_fail adderrmsg-4 "${testcvs} add file1" \
-"${PROG} [a-z]*: file1 has already been entered"
+"${PROG} add: file1 has already been entered"
dotest_fail adderrmsg-5 "${testcvs} -q add file1" ""
dotest adderrmsg-6 "${testcvs} -q ci -madd" \
@@ -12488,7 +14537,7 @@ done"
# file in Entries & repository
dotest_fail adderrmsg-7 "${testcvs} add file1" \
-"${PROG} [a-z]*: file1 already exists, with version number 1\.1"
+"${PROG} add: file1 already exists, with version number 1\.1"
dotest_fail adderrmsg-8 "${testcvs} -q add file1" ""
# clean up
@@ -12499,141 +14548,120 @@ done"
fi
;;
+ opterrmsg)
+ # Test some option parsing error messages
+
+ # No init is necessary since these error messages are printed b4
+ # CVS looks for a sandbox or repository
+
+ # -z used to accept non-numeric arguments. This bit someone who
+ # attempted `cvs -z -n up' when the -n was read as the argument to
+ # -z.
+ dotest_fail opterrmsg-1 "${testcvs} -z -n up" \
+"${PROG}: gzip compression level must be between 0 and 9"
+
+ # Some general -z checks
+ dotest_fail opterrmsg-2 "${testcvs} -z -1 up" \
+"${PROG}: gzip compression level must be between 0 and 9"
+ dotest_fail opterrmsg-3 "${testcvs} -z10 up" \
+"${PROG}: gzip compression level must be between 0 and 9"
+ ;;
+
devcom)
mkdir ${CVSROOT_DIRNAME}/first-dir
mkdir 1
cd 1
- if ${testcvs} -q co first-dir >>${LOGFILE} ; then
- pass 169
- else
- fail 169
- fi
+ dotest devcom-1 "${testcvs} -q co first-dir"
cd first-dir
echo abb >abb
- if ${testcvs} add abb 2>>${LOGFILE}; then
- pass 170
- else
- fail 170
- fi
- if ${testcvs} ci -m added >>${LOGFILE} 2>&1; then
- pass 171
- else
- fail 171
- fi
- dotest_fail 171a0 "${testcvs} watch" "Usage${DOTSTAR}"
- if ${testcvs} watch on; then
- pass 172
- else
- fail 172
- fi
+ dotest devcom-2 "${testcvs} add abb" \
+"$PROG add: scheduling file \`abb' for addition
+$PROG add: use '$PROG commit' to add this file permanently"
+
+ dotest devcom-3 "${testcvs} -q ci -m added" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/abb,v
+done
+Checking in abb;
+${CVSROOT_DIRNAME}/first-dir/abb,v <-- abb
+initial revision: 1\.1
+done"
+
+ dotest_fail devcom-4 "${testcvs} watch" "Usage${DOTSTAR}"
+
+ dotest devcom-5 "${testcvs} watch on"
+
echo abc >abc
- if ${testcvs} add abc 2>>${LOGFILE}; then
- pass 173
- else
- fail 173
- fi
- if ${testcvs} ci -m added >>${LOGFILE} 2>&1; then
- pass 174
- else
- fail 174
- fi
+ dotest devcom-6 "${testcvs} add abc" \
+"$PROG add: scheduling file \`abc' for addition
+$PROG add: use '$PROG commit' to add this file permanently"
+
+ dotest devcom-7 "${testcvs} -q ci -m added" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
+done
+Checking in abc;
+${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc
+initial revision: 1\.1
+done"
cd ../..
mkdir 2
cd 2
- if ${testcvs} -q co first-dir >>${LOGFILE}; then
- pass 175
- else
- fail 175
- fi
+ dotest devcom-8 "${testcvs} -q co first-dir" \
+"U first-dir/abb
+U first-dir/abc"
+
cd first-dir
- if test -w abb; then
- fail 176
- else
- pass 176
- fi
- if test -w abc; then
- fail 177
- else
- pass 177
- fi
+ dotest_fail devcom-9 "test -w abb"
+ dotest_fail devcom-9 "test -w abc"
- dotest devcom-178 "${testcvs} editors" ""
+ dotest devcom-10 "${testcvs} editors" ""
- if ${testcvs} edit abb; then
- pass 179
- else
- fail 179
- fi
+ dotest devcom-11 "${testcvs} edit abb"
# Here we test for the traditional ISO C ctime() date format.
# We assume the C locale; I guess that works provided we set
# LC_ALL at the start of this script but whether these
# strings should vary based on locale does not strike me as
# self-evident.
- dotest devcom-180 "${testcvs} editors" \
+ dotest devcom-12 "${testcvs} editors" \
"abb ${username} [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] GMT [-a-zA-Z_.0-9]* ${TESTDIR}/2/first-dir"
echo aaaa >>abb
- if ${testcvs} ci -m modify abb >>${LOGFILE} 2>&1; then
- pass 182
- else
- fail 182
- fi
+ dotest devcom-13 "${testcvs} ci -m modify abb" \
+"Checking in abb;
+${CVSROOT_DIRNAME}/first-dir/abb,v <-- abb
+new revision: 1\.2; previous revision: 1\.1
+done"
+
# Unedit of a file not being edited should be a noop.
- dotest 182.5 "${testcvs} unedit abb" ''
+ dotest devcom-14 "${testcvs} unedit abb" ''
- dotest devcom-183 "${testcvs} editors" ""
+ dotest devcom-15 "${testcvs} editors" ""
- if test -w abb; then
- fail 185
- else
- pass 185
- fi
+ dotest_fail devcom-16 "test -w abb"
+
+ dotest devcom-17 "${testcvs} edit abc"
- if ${testcvs} edit abc; then
- pass 186a1
- else
- fail 186a1
- fi
# Unedit of an unmodified file.
- if ${testcvs} unedit abc; then
- pass 186a2
- else
- fail 186a2
- fi
- if ${testcvs} edit abc; then
- pass 186a3
- else
- fail 186a3
- fi
+ dotest devcom-18 "${testcvs} unedit abc"
+ dotest devcom-19 "${testcvs} edit abc"
+
echo changedabc >abc
# Try to unedit a modified file; cvs should ask for confirmation
- if (echo no | ${testcvs} unedit abc) >>${LOGFILE}; then
- pass 186a4
- else
- fail 186a4
- fi
- if echo changedabc | cmp - abc; then
- pass 186a5
- else
- fail 186a5
- fi
+ dotest devcom-20 "echo no | ${testcvs} unedit abc" \
+"abc has been modified; revert changes? "
+
+ dotest devcom-21 "echo changedabc | cmp - abc"
+
# OK, now confirm the unedit
- if (echo yes | ${testcvs} unedit abc) >>${LOGFILE}; then
- pass 186a6
- else
- fail 186a6
- fi
- if echo abc | cmp - abc; then
- pass 186a7
- else
- fail 186a7
- fi
+ dotest devcom-22 "echo yes | ${testcvs} unedit abc" \
+"abc has been modified; revert changes? "
+
+ dotest devcom-23 "echo abc | cmp - abc"
- dotest devcom-a0 "${testcvs} watchers" ''
+ dotest devcom-24 "${testcvs} watchers" ''
# FIXME: This probably should be an error message instead
# of silently succeeding and printing nothing.
@@ -12863,20 +14891,27 @@ G@#..!@#=&"
# Now test disconnected "cvs edit" and the format of the
# CVS/Notify file.
if $remote; then
- CVS_SERVER_SAVED=${CVS_SERVER}
+ CVS_SERVER_save=${CVS_SERVER}
CVS_SERVER=${TESTDIR}/cvs-none; export CVS_SERVER
- # The ${DOTSTAR} matches the exact exec error message
- # (which varies) and either "end of file from server"
- # (if the process doing the exec exits before the parent
- # gets around to sending data to it) or "broken pipe" (if it
- # is the other way around).
- dotest_fail devcom3-9ar "${testcvs} edit w1" \
-"${PROG} \[edit aborted\]: cannot exec ${TESTDIR}/cvs-none: ${DOTSTAR}"
+ # The ${DOTSTAR} below matches the exact CVS server error message,
+ # which in :fork: mode is:
+ # "$PROG \[edit aborted\]: cannot exec $TESTDIR/cvs-none: ${DOTSTAR}",
+ # but which is:
+ # "bash2: line 1: $TESTDIR/cvs-none: No such file or directory"
+ # when testing across an :ext:/ssh link to my Linux 2.4 box.
+ #
+ # I can't even test for the second part of the error message,
+ # from the client, which varies more consistently, usually either
+ # "end of file from server" (if the process doing the exec exits
+ # before the parent gets around to sending data to it) or
+ # "received broken pipe signal" (if it is the other way around),
+ # since HP-UX fails to output it.
+ dotest_fail devcom3-9ar "${testcvs} edit w1 2>/dev/null"
dotest devcom3-9br "test -w w1" ""
dotest devcom3-9cr "cat CVS/Notify" \
"Ew1 [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] GMT [-a-zA-Z_.0-9]* ${TESTDIR}/1/first-dir EUC"
- CVS_SERVER=${CVS_SERVER_SAVED}; export CVS_SERVER
+ CVS_SERVER=${CVS_SERVER_save}; export CVS_SERVER
dotest devcom3-9dr "${testcvs} -q update" ""
dotest_fail devcom3-9er "test -f CVS/Notify" ""
dotest devcom3-9fr "${testcvs} watchers w1" \
@@ -12895,7 +14930,7 @@ G@#..!@#=&"
${CVSROOT_DIRNAME}/first-dir/CVS/fileattr
mkdir 2; cd 2
dotest_fail devcom3-10 "${testcvs} -Q co ." \
-"${PROG} \[[a-z]* aborted\]: file attribute database corruption: tab missing in ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr"
+"${PROG} \[checkout aborted\]: file attribute database corruption: tab missing in ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr"
cd ..
# Use -f because of the readonly files.
@@ -12916,8 +14951,8 @@ G@#..!@#=&"
# This is just like the 173 test
touch file1
dotest watch4-2 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest watch4-3 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -12932,8 +14967,8 @@ done"
cd subdir
touch sfile
dotest watch4-5 "${testcvs} add sfile" \
-"${PROG} [a-z]*: scheduling file .sfile. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .sfile. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest watch4-6 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v
done
@@ -12968,7 +15003,7 @@ retrieving revision 1\.1
retrieving revision 1\.2
Merging differences between 1\.1 and 1\.2 into file1
rcsmerge: warning: conflicts during merge
-${PROG} [a-z]*: conflicts found in file1
+${PROG} update: conflicts found in file1
C file1"
if (echo yes | ${testcvs} unedit file1) >>${LOGFILE}; then
pass watch4-14
@@ -13022,8 +15057,8 @@ C file1"
# This is just like the 173 test
touch file1
dotest watch5-2 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest watch5-3 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -13085,13 +15120,9 @@ ${PROG} unedit: run update to complete the unedit"
dotest unedit-without-baserev-5 "cat CVS/Entries" \
"/$file/1\.1\.1\.1/${DOTSTAR}"
- if $remote; then
- dotest unedit-without-baserev-6r "${testcvs} -q update" "U m"
- else
- dotest unedit-without-baserev-6 "${testcvs} -q update" \
+ dotest unedit-without-baserev-6 "${testcvs} -q update" \
"${PROG} update: warning: m was lost
U m"
- fi
# OK, those were the easy cases. Now tackle the hard one
# (the reason that CVS/Baserev was invented rather than just
@@ -13123,19 +15154,15 @@ retrieving revision 1\.1\.1\.1
retrieving revision 1\.2
Merging differences between 1\.1\.1\.1 and 1\.2 into m
rcsmerge: warning: conflicts during merge
-${PROG} [a-z]*: conflicts found in m
+${PROG} update: conflicts found in m
C m"
rm CVS/Baserev
- echo yes | dotest unedit-without-baserev-14 "${testcvs} unedit m" \
+ dotest unedit-without-baserev-14 "echo yes | ${testcvs} unedit m" \
"m has been modified; revert changes${QUESTION} ${PROG} unedit: m not mentioned in CVS/Baserev
${PROG} unedit: run update to complete the unedit"
- if $remote; then
- dotest unedit-without-baserev-15r "${testcvs} -q update" "U m"
- else
- dotest unedit-without-baserev-15 "${testcvs} -q update" \
+ dotest unedit-without-baserev-15 "${testcvs} -q update" \
"${PROG} update: warning: m was lost
U m"
- fi
# The following tests are kind of degenerate compared with
# watch4-16 through watch4-18 but might as well make sure that
# nothing seriously wrong has happened to the working directory.
@@ -13159,8 +15186,9 @@ U m"
dotest ignore-1 "${testcvs} -q co CVSROOT" "U CVSROOT/${DOTSTAR}"
cd CVSROOT
echo rootig.c >cvsignore
- dotest ignore-2 "${testcvs} add cvsignore" "${PROG}"' [a-z]*: scheduling file `cvsignore'"'"' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+ dotest ignore-2 "${testcvs} add cvsignore" \
+"${PROG}"' add: scheduling file `cvsignore'"'"' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
# As of Jan 96, local CVS prints "Examining ." and remote doesn't.
# Accept either.
@@ -13172,7 +15200,7 @@ Checking in cvsignore;
${CVSROOT_DIRNAME}/CVSROOT/cvsignore,v <-- cvsignore
initial revision: 1\.1
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
if echo "yes" | ${testcvs} release -d CVSROOT >>${LOGFILE} ; then
@@ -13302,7 +15330,7 @@ Are you sure you want to release (and delete) directory .second-dir': "
cd setup
echo file1 >file1
dotest ignore-on-branch-setup-2 "$testcvs -q add file1" \
-"$PROG [a-z]*: use .$PROG commit. to add this file permanently"
+"${PROG} add: use .${PROG} commit. to add this file permanently"
dotest ignore-on-branch-setup-3 "$testcvs -q ci -mfile1 file1" \
"RCS file: $CVSROOT_DIRNAME/ignore-on-branch/file1,v
done
@@ -13313,7 +15341,7 @@ done"
dotest ignore-on-branch-setup-4 "$testcvs -q tag -b branch" 'T file1'
echo file2 >file2
dotest ignore-on-branch-setup-5 "$testcvs -q add file2" \
-"$PROG [a-z]*: use .$PROG commit. to add this file permanently"
+"${PROG} add: use .${PROG} commit. to add this file permanently"
dotest ignore-on-branch-setup-6 "$testcvs -q ci -mtrunk file2" \
"RCS file: $CVSROOT_DIRNAME/ignore-on-branch/file2,v
done
@@ -13344,14 +15372,14 @@ T file1'
dotest ignore-on-branch-3 "$testcvs -q tag -b branch2" 'T file1'
fi
dotest ignore-on-branch-4 "$testcvs -q add file2" \
-"$PROG [a-z]*: use .$PROG commit. to add this file permanently"
+"${PROG} add: use .${PROG} commit. to add this file permanently"
dotest ignore-on-branch-5 "$testcvs -q ci -mbranch file2" \
"Checking in file2;
$CVSROOT_DIRNAME/ignore-on-branch/file2,v <-- file2
new revision: 1\.1\.2\.1; previous revision: 1\.1
done"
dotest ignore-on-branch-6 "$testcvs -q up -rbranch2" \
-"$PROG [a-z]*: file2 is no longer in the repository"
+"${PROG} update: file2 is no longer in the repository"
dotest ignore-on-branch-7 "$testcvs -q up -jbranch" 'U file2'
cd ../..
@@ -13379,8 +15407,8 @@ done"
cd first-dir
cp ../binfile.dat binfile
dotest binfiles-2 "${testcvs} add -kb binfile" \
-"${PROG}"' [a-z]*: scheduling file `binfile'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `binfile'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest binfiles-3 "${testcvs} -q ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v
done
@@ -13448,9 +15476,9 @@ done"
echo 'edits in dir 2' >binfile
dotest binfiles-con1 "${testcvs} -q update" \
"U binfile
-${PROG} [a-z]*: nonmergeable file needs merge
-${PROG} [a-z]*: revision 1\.3 from repository is now in binfile
-${PROG} [a-z]*: file from working directory is now in \.#binfile\.1\.2
+${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 binfiles-con2 "cmp binfile ../../1/binfile.dat" ''
dotest binfiles-con3 "cat .#binfile.1.2" 'edits in dir 2'
@@ -13539,7 +15567,7 @@ File: binfile Status: Up-to-date
# Do sticky options work when used with 'cvs update'?
echo "Not a binary file." > nibfile
dotest binfiles-sticky1 "${testcvs} -q add nibfile" \
-"${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: use .${PROG} commit. to add this file permanently"
dotest binfiles-sticky2 "${testcvs} -q ci -m add-it nibfile" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/nibfile,v
done
@@ -13658,10 +15686,10 @@ total revisions: 1
cp ../binfile brmod-wdmod
dotest binfiles2-1a \
"${testcvs} add -kb brmod brmod-trmod brmod-wdmod" \
-"${PROG} [a-z]*: scheduling file .brmod. for addition
-${PROG} [a-z]*: scheduling file .brmod-trmod. for addition
-${PROG} [a-z]*: scheduling file .brmod-wdmod. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .brmod. for addition
+${PROG} add: scheduling file .brmod-trmod. for addition
+${PROG} add: scheduling file .brmod-wdmod. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest binfiles2-1b "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod,v
done
@@ -13687,8 +15715,8 @@ T brmod-wdmod'
dotest binfiles2-3 "${testcvs} -q update -r br" ''
cp ../binfile binfile.dat
dotest binfiles2-4 "${testcvs} add -kb binfile.dat" \
-"${PROG} [a-z]*: scheduling file .binfile\.dat. for addition on branch .br.
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .binfile\.dat. for addition on branch .br.
+${PROG} add: use .${PROG} commit. to add this file permanently"
cp ../binfile2 brmod
cp ../binfile2 brmod-trmod
cp ../binfile2 brmod-wdmod
@@ -13712,7 +15740,7 @@ ${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod
new revision: 1\.1\.2\.1; previous revision: 1\.1
done"
dotest binfiles2-6 "${testcvs} -q update -A" \
-"${PROG} [a-z]*: binfile\.dat is no longer in the repository
+"${PROG} update: binfile\.dat is no longer in the repository
[UP] brmod
[UP] brmod-trmod
[UP] brmod-wdmod"
@@ -13729,14 +15757,14 @@ done"
dotest binfiles2-8 "${testcvs} -q update -j br" \
"U binfile\.dat
U brmod
-${PROG} [a-z]*: nonmergeable file needs merge
-${PROG} [a-z]*: revision 1.1.2.1 from repository is now in brmod-trmod
-${PROG} [a-z]*: file from working directory is now in .#brmod-trmod.1.2
+${PROG} update: nonmergeable file needs merge
+${PROG} update: revision 1.1.2.1 from repository is now in brmod-trmod
+${PROG} update: file from working directory is now in .#brmod-trmod.1.2
C brmod-trmod
M brmod-wdmod
-${PROG} [a-z]*: nonmergeable file needs merge
-${PROG} [a-z]*: revision 1.1.2.1 from repository is now in brmod-wdmod
-${PROG} [a-z]*: file from working directory is now in .#brmod-wdmod.1.1
+${PROG} update: nonmergeable file needs merge
+${PROG} update: revision 1.1.2.1 from repository is now in brmod-wdmod
+${PROG} update: file from working directory is now in .#brmod-wdmod.1.1
C brmod-wdmod"
dotest binfiles2-9 "cmp ../binfile binfile.dat"
@@ -13768,8 +15796,8 @@ done"
dotest_fail binfiles2-o1 "${testcvs} -q admin -o :1.2 brmod-trmod" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v
deleting revision 1\.2
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v: can't remove branch point 1\.1
-${PROG} [a-z]*: RCS file for .brmod-trmod. not modified\."
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v: can't remove branch point 1\.1
+${PROG} admin: RCS file for .brmod-trmod. not modified\."
dotest binfiles2-o2 "${testcvs} -q admin -o 1.1.2.1: brmod-trmod" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v
deleting revision 1\.1\.2\.1
@@ -13812,8 +15840,8 @@ checkin
cd first-dir
echo hello >file1
dotest binfiles3-2 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest binfiles3-3 "${testcvs} -q ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -13823,8 +15851,8 @@ initial revision: 1\.1
done"
rm file1
dotest binfiles3-4 "${testcvs} rm file1" \
-"${PROG} [a-z]*: scheduling .file1. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file1. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest binfiles3-5 "${testcvs} -q ci -m remove-it" \
"Removing file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
@@ -13832,8 +15860,8 @@ new revision: delete; previous revision: 1\.1
done"
cp ../binfile.dat file1
dotest binfiles3-6 "${testcvs} add -kb file1" \
-"${PROG} [a-z]*: re-adding file file1 (in place of dead revision 1\.2)
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: Re-adding file .file1. (in place of dead revision 1\.2)\.
+${PROG} add: use .${PROG} commit. to add this file permanently"
# The idea behind this test is to make sure that the file
# gets opened in binary mode to send to "cvs ci".
dotest binfiles3-6a "cat CVS/Entries" \
@@ -13844,7 +15872,7 @@ D"
# in checkaddfile()); should also test the case in which
# we are changing it from one non-default value to another.
dotest binfiles3-7 "${testcvs} -q ci -m readd-it" \
-"${PROG} [a-z]*: changing keyword expansion mode to -kb
+"${PROG} commit: changing keyword expansion mode to -kb
Checking in file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.3; previous revision: 1\.2
@@ -13926,11 +15954,11 @@ done"
echo "* -m 'COPY'" >.cvswrappers
dotest mcopy-1a \
"${testcvs} add .cvswrappers brmod brmod-trmod brmod-wdmod" \
-"${PROG} [a-z]*: scheduling file .\.cvswrappers. for addition
-${PROG} [a-z]*: scheduling file .brmod. for addition
-${PROG} [a-z]*: scheduling file .brmod-trmod. for addition
-${PROG} [a-z]*: scheduling file .brmod-wdmod. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .\.cvswrappers. for addition
+${PROG} add: scheduling file .brmod. for addition
+${PROG} add: scheduling file .brmod-trmod. for addition
+${PROG} add: scheduling file .brmod-wdmod. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest mcopy-1b "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/\.cvswrappers,v
done
@@ -14003,14 +16031,14 @@ done"
dotest mcopy-8 "${testcvs} -q update -j br" \
"U brmod
-${PROG} [a-z]*: nonmergeable file needs merge
-${PROG} [a-z]*: revision 1.1.2.1 from repository is now in brmod-trmod
-${PROG} [a-z]*: file from working directory is now in .#brmod-trmod.1.2
+${PROG} update: nonmergeable file needs merge
+${PROG} update: revision 1.1.2.1 from repository is now in brmod-trmod
+${PROG} update: file from working directory is now in .#brmod-trmod.1.2
C brmod-trmod
M brmod-wdmod
-${PROG} [a-z]*: nonmergeable file needs merge
-${PROG} [a-z]*: revision 1.1.2.1 from repository is now in brmod-wdmod
-${PROG} [a-z]*: file from working directory is now in .#brmod-wdmod.1.1
+${PROG} update: nonmergeable file needs merge
+${PROG} update: revision 1.1.2.1 from repository is now in brmod-wdmod
+${PROG} update: file from working directory is now in .#brmod-wdmod.1.1
C brmod-wdmod"
dotest mcopy-9 "cat brmod brmod-trmod brmod-wdmod" \
@@ -14258,11 +16286,11 @@ File: foo\.exe Status: Up-to-date
${CVSROOT_DIRNAME}/CVSROOT/cvswrappers,v <-- cvswrappers
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
# Avoid environmental interference
- CVSWRAPPERS_SAVED=${CVSWRAPPERS}
+ CVSWRAPPERS_save=${CVSWRAPPERS}
unset CVSWRAPPERS
# Do the import
@@ -14285,9 +16313,9 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
echo .cvsignore >>.cvsignore
touch file1.newbin file1.txt
dotest binwrap3-2c "${testcvs} add file1.newbin file1.txt" \
-"${PROG} [a-z]*: scheduling file .file1\.newbin. for addition
-${PROG} [a-z]*: scheduling file .file1\.txt. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .file1\.newbin. for addition
+${PROG} add: scheduling file .file1\.txt. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest binwrap3-2d "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/binwrap3/sub2/file1\.newbin,v
done
@@ -14408,7 +16436,7 @@ done"
cd ..
rm -r wnt
rm -rf ${CVSROOT_DIRNAME}/binwrap3
- CVSWRAPPERS=${CVSWRAPPERS_SAVED}
+ CVSWRAPPERS=${CVSWRAPPERS_save}
;;
mwrap)
@@ -14441,7 +16469,7 @@ done"
${CVSROOT_DIRNAME}/CVSROOT/cvswrappers,v <-- cvswrappers
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
mkdir m1; cd m1
dotest mwrap-1 "${testcvs} -q co -l ." ''
@@ -14451,8 +16479,8 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
cd first-dir
touch aa
dotest mwrap-3 "${testcvs} add aa" \
-"${PROG} [a-z]*: scheduling file .aa. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .aa. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest mwrap-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v
done
@@ -14478,24 +16506,24 @@ done"
# 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" \
-"${PROG} [a-z]*: nonmergeable file needs merge
-${PROG} [a-z]*: revision 1\.2 from repository is now in aa
-${PROG} [a-z]*: file from working directory is now in \.#aa\.1\.1
+"${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} [a-z]*: nonmergeable file needs merge
-${PROG} [a-z]*: revision 1\.2 from repository is now in aa
-${PROG} [a-z]*: file from working directory is now in \.#aa\.1\.1
+${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} [a-z]*: nonmergeable file needs merge
-${PROG} [a-z]*: revision 1\.2 from repository is now in aa
-${PROG} [a-z]*: file from working directory is now in \.#aa\.1\.1
+${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"
dotest mwrap-9 "cat aa" "changed in m2"
dotest mwrap-10 "cat .#aa.1.1" "changed in m1"
@@ -14507,7 +16535,7 @@ C aa"
${CVSROOT_DIRNAME}/CVSROOT/cvswrappers,v <-- cvswrappers
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
rm -r CVSROOT
rm -r m1 m2
@@ -14548,15 +16576,15 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
# work to create a loginfo file if you didn't create one
# with "cvs init".
: dotest info-2 "${testcvs} add loginfo" \
-"${PROG}"' [a-z]*: scheduling file `loginfo'"'"' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `loginfo'"'"' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest info-3 "${testcvs} -q ci -m new-loginfo" \
"Checking in loginfo;
${CVSROOT_DIRNAME}/CVSROOT/loginfo,v <-- loginfo
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
mkdir ${CVSROOT_DIRNAME}/first-dir
@@ -14564,8 +16592,8 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
cd first-dir
touch file1
dotest info-6 "${testcvs} add file1" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file1'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
echo "cvs -s OTHER=not-this -s MYENV=env-" >>$HOME/.cvsrc
dotest info-6a "${testcvs} -q -s OTHER=value ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
@@ -14574,14 +16602,14 @@ Checking in file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
initial revision: 1\.1
done
-${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}"
+${PROG} commit: loginfo:1: no such user variable \${=ZEE}"
echo line0 >>file1
dotest info-6b "${testcvs} -q -sOTHER=foo ci -m mod-it" \
"Checking in file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.2; previous revision: 1\.1
done
-${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}"
+${PROG} commit: loginfo:1: no such user variable \${=ZEE}"
echo line1 >>file1
dotest info-7 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \
"Checking in file1;
@@ -14590,7 +16618,8 @@ new revision: 1\.3; previous revision: 1\.2
done"
cd ..
dotest info-9 "cat $TESTDIR/testlog" "xenv-valueyz=${username}=${CVSROOT_DIRNAME}="
- dotest info-10 "cat $TESTDIR/testlog2" 'first-dir file1,NONE,1.1
+ dotest info-10 "cat $TESTDIR/testlog2" \
+'first-dir file1,NONE,1.1
first-dir 1.1
first-dir file1
first-dir NONEAX
@@ -14613,14 +16642,14 @@ first-dir file1ux'
${CVSROOT_DIRNAME}/CVSROOT/loginfo,v <-- loginfo
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
# Now test verifymsg
cat >${TESTDIR}/vscript <<EOF
#!${TESTSHELL}
-if head -1 < \$1 | grep '^BugId:[ ]*[0-9][0-9]*$' > /dev/null; then
+if sed 1q < \$1 | grep '^BugId:[ ]*[0-9][0-9]*$' > /dev/null; then
exit 0
-elif head -1 < \$1 | grep '^BugId:[ ]*new$' > /dev/null; then
+elif sed 1q < \$1 | grep '^BugId:[ ]*new$' > /dev/null; then
echo A new bugid was found. >> \$1
exit 0
else
@@ -14643,22 +16672,29 @@ else
exit 0
fi
EOF
- chmod +x ${TESTDIR}/vscript*
+ # Grumble, grumble, mumble, search for "Cygwin".
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod +x ${TESTDIR}/vscript*"
+ else
+ chmod +x ${TESTDIR}/vscript*
+ fi
echo "^first-dir/yet-another\\(/\\|\$\\) ${TESTDIR}/vscript2" >>verifymsg
echo "^first-dir\\(/\\|\$\\) ${TESTDIR}/vscript" >>verifymsg
+ echo "^missing-script\$ ${TESTDIR}/bogus" >>verifymsg
+ echo "^missing-var\$ ${TESTDIR}/vscript \${=Bogus}" >>verifymsg
# first test the directory independant verifymsg
dotest info-v1 "${testcvs} -q ci -m add-verification" \
"Checking in verifymsg;
${CVSROOT_DIRNAME}/CVSROOT/verifymsg,v <-- verifymsg
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../first-dir
echo line2 >>file1
dotest_fail info-v2 "${testcvs} -q ci -m bogus" \
"No BugId found\.
-${PROG} \[[a-z]* aborted\]: Message verification failed"
+${PROG} \[commit aborted\]: Message verification failed"
cat >${TESTDIR}/comment.tmp <<EOF
BugId: 42
@@ -14678,7 +16714,7 @@ done"
dotest_fail info-v4 \
"${testcvs} import -m bogus first-dir/another x y" \
"No BugId found\.
-${PROG} \[[a-z]* aborted\]: Message verification failed"
+${PROG} \[import aborted\]: Message verification failed"
# now verify that directory dependent verifymsgs work
dotest info-v5 \
@@ -14706,7 +16742,7 @@ No conflicts created by this import"
dotest_fail info-v6r \
"${testcvs} import -m bogus first-dir/yet-another/and-another x y" \
"${CVSROOT_DIRNAME}/first-dir/yet-another/and-another
-${PROG} \[[a-z]* aborted\]: Message verification failed"
+${PROG} \[import aborted\]: Message verification failed"
else
dotest info-v6 \
"${testcvs} import -m bogus first-dir/yet-another/and-another x y" \
@@ -14715,6 +16751,21 @@ N first-dir/yet-another/and-another/file2
No conflicts created by this import"
fi
+
+ # check that errors invoking the script cause verification failure
+ #
+ # The second text below occurs on Cygwin, where I assume execvp
+ # does not return to let CVS print the error message when its
+ # argument does not exist.
+ dotest_fail info-v7 "${testcvs} import -m bogus missing-script x y" \
+"${PROG} import: cannot exec ${TESTDIR}/bogus: No such file or directory
+${PROG} \[import aborted\]: Message verification failed" \
+"${PROG} \[import aborted\]: Message verification failed"
+
+ dotest_fail info-v8 "${testcvs} import -m bogus missing-var x y" \
+"${PROG} import: verifymsg:25: no such user variable \${=Bogus}
+${PROG} \[import aborted\]: Message verification failed"
+
rm file2
cd ..
rmdir another-dir
@@ -14726,7 +16777,7 @@ No conflicts created by this import"
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../first-dir
echo line3 >>file1
cat >${TESTDIR}/comment.tmp <<EOF
@@ -14754,7 +16805,7 @@ A new bugid was found.
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../first-dir
echo line4 >>file1
cat >${TESTDIR}/comment.tmp <<EOF
@@ -14782,7 +16833,7 @@ A new bugid was found.
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../first-dir
echo line5 >>file1
cat >${TESTDIR}/comment.tmp <<EOF
@@ -14799,12 +16850,12 @@ done"
BugId: new
See what happens next.
============================================================================="
- cd ..
- cd CVSROOT
- echo '# do nothing' >verifymsg
+ cd ../CVSROOT
+ echo 'DEFAULT false' >verifymsg
+ echo 'DEFAULT true' >>verifymsg
echo '# defaults' >config
- dotest info-cleanup-verifymsg "${testcvs} -q ci -m nuke-verifymsg" \
+ dotest info-multdef "${testcvs} -q ci -m multdef" \
"Checking in config;
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
@@ -14813,7 +16864,17 @@ Checking in verifymsg;
${CVSROOT_DIRNAME}/CVSROOT/verifymsg,v <-- verifymsg
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
+
+ cd ../CVSROOT
+ echo '# do nothing' >verifymsg
+ dotest info-cleanup-verifymsg "${testcvs} -q ci -m nuke-verifymsg" \
+"${PROG} commit: Multiple .DEFAULT. lines (1 and 2) in verifymsg file
+Checking in verifymsg;
+${CVSROOT_DIRNAME}/CVSROOT/verifymsg,v <-- verifymsg
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
rm ${TESTDIR}/vscript*
cd ..
@@ -14855,14 +16916,19 @@ else
exit 0
fi
EOF
- chmod +x ${TESTDIR}/1/loggit
+ # #^@&!^@ Cygwin.
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod +x ${TESTDIR}/1/loggit"
+ else
+ chmod +x ${TESTDIR}/1/loggit
+ fi
echo "ALL ${TESTDIR}/1/loggit" >taginfo
dotest taginfo-2 "${testcvs} -q ci -m check-in-taginfo" \
"Checking in taginfo;
${CVSROOT_DIRNAME}/CVSROOT/taginfo,v <-- taginfo
new revision: 1\.2; previous revision: 1\.1
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
# taginfo-3 used to rely on the top-level CVS directory
@@ -14875,8 +16941,8 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
cd first-dir
echo first >file1
dotest taginfo-4 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest taginfo-5 "${testcvs} -q ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -14896,8 +16962,8 @@ done"
dotest taginfo-10 "${testcvs} -q tag -F -c brtag" "T file1"
dotest_fail taginfo-11 "${testcvs} -q tag rejectme" \
-"${PROG} [a-z]*: Pre-tag check failed
-${PROG} \[[a-z]* aborted\]: correct the above errors first!"
+"${PROG} tag: Pre-tag check failed
+${PROG} \[tag aborted\]: correct the above errors first!"
# When we are using taginfo to allow/disallow, it would be
# convenient to be able to use "cvs -n tag" to test whether
@@ -14948,7 +17014,7 @@ tag1 del ${CVSROOT_DIRNAME}/first-dir"
${CVSROOT_DIRNAME}/CVSROOT/taginfo,v <-- taginfo
new revision: 1\.3; previous revision: 1\.2
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..
cd ..
rm -r 1
@@ -14974,7 +17040,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
echo 'BogusOption=yes' >config
dotest config-4 "${testcvs} -q ci -m change-to-bogus-opt" \
"${PROG} [a-z]*: syntax error in ${CVSROOT_DIRNAME}/CVSROOT/config: line 'bogus line' is missing '='
@@ -14982,7 +17048,7 @@ Checking in config;
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
echo '# No config is a good config' > config
dotest config-5 "${testcvs} -q ci -m change-to-comment" \
"${PROG} [a-z]*: ${CVSROOT_DIRNAME}/CVSROOT/config: unrecognized keyword 'BogusOption'
@@ -14990,7 +17056,7 @@ Checking in config;
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
dotest config-6 "${testcvs} -q update" ''
cd ..
@@ -15015,8 +17081,8 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
echo '$''Name$' > file1
echo '1' >> file1
dotest serverpatch-2 "${testcvs} add file1" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file1'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest serverpatch-3 "${testcvs} -q commit -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
@@ -15054,10 +17120,11 @@ done"
cd ../../2/first-dir
dotest serverpatch-8 "${testcvs} -q update" \
'U file1' \
-'P file1
-'"${PROG}"' [a-z]*: checksum failure after patch to ./file1; will refetch
-'"${PROG}"' [a-z]*: refetching unpatchable files
-U file1'
+"P file1
+${PROG} update: checksum failure after patch to \./file1; will refetch
+${PROG} client: refetching unpatchable files
+${PROG} update: warning: file1 was lost
+U file1"
cd ../..
rm -r 1 2
@@ -15086,9 +17153,9 @@ U file1'
echo 'first revision' > file1
echo 'first revision' > file2
dotest log-2 "${testcvs} add file1 file2" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
# While we're at it, check multi-line comments, input from file,
# and trailing whitespace trimming
@@ -15143,7 +17210,7 @@ done"
dotest log-7 "${testcvs} -q update -r branch" \
"[UP] file1
-${PROG} [a-z]*: file2 is no longer in the repository"
+${PROG} update: file2 is no longer in the repository"
echo 'first branch revision' > file1
dotest log-8 "${testcvs} -q ci -m1b file1" \
@@ -15264,7 +17331,7 @@ ${log_trailer}"
# In the error message, HEAD is a file name, not a tag name (which
# might be confusing itself).
dotest_fail log-14b "${testcvs} log -r HEAD file1" \
-"${PROG} [a-z]*: nothing known about HEAD
+"${PROG} log: nothing known about HEAD
${log_header1}
${log_tags1}
${log_keyword}
@@ -15495,7 +17562,7 @@ ${log_rev3}
${log_trailer}"
dotest_fail log-r14b "${testcvs} rlog -r HEAD first-dir/file1" \
-"${PROG} [a-z]*: cannot find module .HEAD. - ignored
+"${PROG} rlog: cannot find module .HEAD. - ignored
${rlog_header1}
${log_tags1}
${log_keyword}
@@ -15667,7 +17734,7 @@ ${log_trailer}"
"[UP] file1
U file2"
dotest log-d1 "${testcvs} -q rm -f file1" \
-"${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: use .${PROG} commit. to remove this file permanently"
dotest log-d2 "${testcvs} -q ci -m4" \
"Removing file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
@@ -15737,7 +17804,7 @@ description:
${log_rev2b}
${log_rev1b}
${log_trailer}
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
${log_header2}
${log_tags2}
${log_keyword}
@@ -15751,7 +17818,7 @@ ${log_keyword}
total revisions: 6
description:
${log_trailer}
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
${log_header2}
${log_tags2}
${log_keyword}
@@ -15765,14 +17832,14 @@ ${log_keyword}
total revisions: 6; selected revisions: 2
description:
${log_trailer}
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
dotest log-d4c "${testcvs} -q log -h -rbranch" \
"${log_header1}
${log_tags1}
${log_keyword}
total revisions: 6
${log_trailer}
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
${log_header2}
${log_tags2}
${log_keyword}
@@ -15784,13 +17851,13 @@ ${log_tags1}
${log_keyword}
total revisions: 6; selected revisions: 2
${log_trailer}
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
dotest log-d4e "${testcvs} -q log -R -rbranch" \
"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
${CVSROOT_DIRNAME}/first-dir/file2,v"
dotest log-d4f "${testcvs} -q log -R -S -rbranch" \
"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
dotest log-rd4 "${testcvs} -q rlog -rbranch first-dir" \
"${rlog_header1}
${log_tags1}
@@ -15800,7 +17867,7 @@ description:
${log_rev2b}
${log_rev1b}
${log_trailer}
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
${rlog_header2}
${log_tags2}
${log_keyword}
@@ -15814,7 +17881,7 @@ ${log_keyword}
total revisions: 6
description:
${log_trailer}
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
${rlog_header2}
${log_tags2}
${log_keyword}
@@ -15828,14 +17895,14 @@ ${log_keyword}
total revisions: 6; selected revisions: 2
description:
${log_trailer}
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
dotest log-rd4c "${testcvs} -q rlog -h -rbranch first-dir" \
"${rlog_header1}
${log_tags1}
${log_keyword}
total revisions: 6
${log_trailer}
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
${rlog_header2}
${log_tags2}
${log_keyword}
@@ -15847,13 +17914,13 @@ ${log_tags1}
${log_keyword}
total revisions: 6; selected revisions: 2
${log_trailer}
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
dotest log-rd4e "${testcvs} -q rlog -R -rbranch first-dir" \
"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
${CVSROOT_DIRNAME}/first-dir/file2,v"
dotest log-rd4f "${testcvs} -q rlog -R -S -rbranch first-dir" \
"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
-${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
dotest log-d5 "${testcvs} log -r1.2.2.1:1.2.2.2 file1" \
"${log_header1}
${log_tags1}
@@ -15921,8 +17988,8 @@ ${log_rev3}
${log_rev2}
${log_trailer}"
dotest log-d8 "${testcvs} -q log -rtag1:tag2" \
-"${PROG} [a-z]*: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
-${PROG} [a-z]*: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+"${PROG} log: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${PROG} log: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
${log_header1}
${log_tags1}
${log_keyword}
@@ -15938,8 +18005,8 @@ ${log_rev3}
${log_rev22}
${log_trailer}"
dotest log-d8a "${testcvs} -q log -rtag1:tag2 -S" \
-"${PROG} [a-z]*: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
-${PROG} [a-z]*: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+"${PROG} log: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${PROG} log: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
${log_header2}
${log_tags2}
${log_keyword}
@@ -15949,8 +18016,8 @@ ${log_rev3}
${log_rev22}
${log_trailer}"
dotest log-rd8 "${testcvs} -q rlog -rtag1:tag2 first-dir" \
-"${PROG} [a-z]*: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
-${PROG} [a-z]*: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+"${PROG} rlog: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${PROG} rlog: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
${rlog_header1}
${log_tags1}
${log_keyword}
@@ -15966,8 +18033,8 @@ ${log_rev3}
${log_rev22}
${log_trailer}"
dotest log-rd8a "${testcvs} -q rlog -rtag1:tag2 -S first-dir" \
-"${PROG} [a-z]*: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
-${PROG} [a-z]*: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+"${PROG} rlog: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${PROG} rlog: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
${rlog_header2}
${log_tags2}
${log_keyword}
@@ -15979,7 +18046,7 @@ ${log_trailer}"
dotest log-d99 "${testcvs} -q up -rbranch" \
"[UP] file1
-${PROG} [a-z]*: file2 is no longer in the repository"
+${PROG} update: file2 is no longer in the repository"
# Now test outdating revisions
@@ -16034,8 +18101,8 @@ ${log_trailer}"
cd first-dir
echo 'first revision' > file1
dotest log2-2 "${testcvs} add -m file1-is-for-testing file1" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+"${PROG}"' add: scheduling file `file1'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
dotest log2-3 "${testcvs} -q commit -m 1" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -16151,8 +18218,8 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
cd first-dir
echo hi >file1
dotest logopt-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest logopt-4 "${testcvs} -q ci -m add file1" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -16163,20 +18230,20 @@ done"
cd ..
dotest logopt-5 "${testcvs} log -R -d 2038-01-01" \
-"${PROG} [a-z]*: Logging \.
-${PROG} [a-z]*: Logging first-dir
+"${PROG} log: Logging \.
+${PROG} log: Logging first-dir
${CVSROOT_DIRNAME}/first-dir/file1,v"
dotest logopt-6 "${testcvs} log -d 2038-01-01 -R" \
-"${PROG} [a-z]*: Logging \.
-${PROG} [a-z]*: Logging first-dir
+"${PROG} log: Logging \.
+${PROG} log: Logging first-dir
${CVSROOT_DIRNAME}/first-dir/file1,v"
dotest logopt-6a "${testcvs} log -Rd 2038-01-01" \
-"${PROG} [a-z]*: Logging \.
-${PROG} [a-z]*: Logging first-dir
+"${PROG} log: Logging \.
+${PROG} log: Logging first-dir
${CVSROOT_DIRNAME}/first-dir/file1,v"
dotest logopt-7 "${testcvs} log -s Exp -R" \
-"${PROG} [a-z]*: Logging \.
-${PROG} [a-z]*: Logging first-dir
+"${PROG} log: Logging \.
+${PROG} log: Logging first-dir
${CVSROOT_DIRNAME}/first-dir/file1,v"
cd ..
@@ -16203,8 +18270,8 @@ ancestral
file
EOF
dotest ann-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest ann-4 "${testcvs} -q ci -m add file1" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -16314,7 +18381,7 @@ Annotations for file1
1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): and some
1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): branched content"
dotest_fail ann-14 "${testcvs} ann -r bill-clintons-chastity file1" \
-"${PROG} \[[a-z]* aborted\]: no such tag bill-clintons-chastity"
+"${PROG} \[annotate aborted\]: no such tag bill-clintons-chastity"
# Now get rid of the working directory and test rannotate
@@ -16365,7 +18432,7 @@ Annotations for first-dir/file1
1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): and some
1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): branched content"
dotest_fail ann-r14 "${testcvs} rann -r bill-clintons-chastity first-dir/file1" \
-"${PROG} \[[a-z]* aborted\]: no such tag bill-clintons-chastity"
+"${PROG} \[rannotate aborted\]: no such tag bill-clintons-chastity"
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
@@ -16387,8 +18454,8 @@ Annotations for first-dir/file1
echo '$Id''$' > $file
dotest ann-id-3 "$testcvs add $file" \
-"${PROG} [a-z]*: scheduling file .$file. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .$file. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest ann-id-4 "$testcvs -Q ci -m . $file" \
"RCS file: ${CVSROOT_DIRNAME}/$module/$file,v
done
@@ -16422,6 +18489,8 @@ Annotations for $file
# Various tests relating to creating repositories, operating
# on repositories created with old versions of CVS, etc.
+ CVS_SERVER_save=$CVS_SERVER
+
# Because this test is all about -d options and such, it
# at least to some extent needs to be different for remote vs.
# local.
@@ -16444,13 +18513,28 @@ Annotations for $file
# with our own CVS_RSH rather than worrying about a system one
# would do the trick.
+ # Make sure server ignores real ${HOME}/.cvsrc:
+ cat >$TESTDIR/cvs-setHome <<EOF
+#!/bin/sh
+HOME=$HOME
+export HOME
+exec $CVS_SERVER_save "\$@"
+EOF
+ chmod a+x $TESTDIR/cvs-setHome
+
# Note that we set CVS_SERVER at the beginning.
- CREREPOS_ROOT=:ext:`hostname`:${TESTDIR}/crerepos
+ 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-rsh} $host -n 'echo hi'`" != "xhi"; then
- echo "ERROR: cannot test remote CVS, because \`${CVS_RSH-rsh} $host' fails." >&2
+ 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
@@ -16459,26 +18543,26 @@ Annotations for $file
# First, if the repository doesn't exist at all...
dotest_fail crerepos-1 \
"${testcvs} -d ${TESTDIR}/crerepos co cvs-sanity" \
-"${PROG} \[[a-z]* aborted\]: ${TESTDIR}/crerepos/CVSROOT: .*"
+"${PROG} \[checkout aborted\]: ${TESTDIR}/crerepos/CVSROOT: .*"
mkdir crerepos
# The repository exists but CVSROOT doesn't.
dotest_fail crerepos-2 \
"${testcvs} -d ${TESTDIR}/crerepos co cvs-sanity" \
-"${PROG} \[[a-z]* aborted\]: ${TESTDIR}/crerepos/CVSROOT: .*"
+"${PROG} \[checkout aborted\]: ${TESTDIR}/crerepos/CVSROOT: .*"
mkdir crerepos/CVSROOT
# Checkout of nonexistent module
dotest_fail crerepos-3 \
"${testcvs} -d ${TESTDIR}/crerepos co cvs-sanity" \
-"${PROG} [a-z]*: cannot find module .cvs-sanity. - ignored"
+"${PROG} checkout: cannot find module .cvs-sanity. - ignored"
# Now test that CVS works correctly without a modules file
# or any of that other stuff. In particular, it *must*
# function if administrative files added to CVS recently (since
# CVS 1.3) do not exist, because the repository might have
# been created with an old version of CVS.
- mkdir tmp; cd tmp
+ mkdir 1; cd 1
dotest crerepos-4 \
"${testcvs} -q -d ${TESTDIR}/crerepos co CVSROOT" \
''
@@ -16490,8 +18574,8 @@ ${testcvs} -d ${TESTDIR}/crerepos release -d CVSROOT >>${LOGFILE}; then
fi
rm -rf CVS
cd ..
- # The directory tmp should be empty
- dotest crerepos-6 "rmdir tmp" ''
+ # The directory 1 should be empty
+ dotest crerepos-6 "rmdir 1"
CREREPOS_ROOT=${TESTDIR}/crerepos
@@ -16531,16 +18615,16 @@ ${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 \[[a-z]* aborted\]: end of file from server (consult above messages if any)" \
-"$PROG \[[a-z]* aborted\]: received broken pipe signal"
+"${PROG} \[checkout aborted\]: end of file from server (consult above messages if any)" \
+"${PROG} \[checkout aborted\]: received broken pipe signal"
cd ..
rm -r 1
mkdir 1; cd 1
dotest_fail crerepos-6b "${testcvs} -d crerepos init" \
-"${PROG} [a-z]*: CVSROOT must be an absolute pathname (not .crerepos.)
-${PROG} [a-z]*: when using local access method\.
-${PROG} \[[a-z]* aborted\]: Bad CVSROOT: .crerepos.\."
+"${PROG} init: CVSROOT must be an absolute pathname (not .crerepos.)
+${PROG} init: when using local access method\.
+${PROG} \[init aborted\]: Bad CVSROOT: .crerepos.\."
cd ..
rm -r 1
fi # end of tests to be skipped for remote
@@ -16561,8 +18645,8 @@ ${PROG} \[[a-z]* aborted\]: Bad CVSROOT: .crerepos.\."
cd first-dir
touch file1
dotest crerepos-10 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest crerepos-11 "${testcvs} -q ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -16581,8 +18665,8 @@ done"
cd crerepos-dir
touch cfile
dotest crerepos-14 "${testcvs} add cfile" \
-"${PROG} [a-z]*: scheduling file .cfile. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .cfile. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest crerepos-15 "${testcvs} -q ci -m add-it" \
"RCS file: ${TESTDIR}/crerepos/crerepos-dir/cfile,v
done
@@ -16595,26 +18679,31 @@ done"
mkdir 1; cd 1
dotest crerepos-16 "${testcvs} co first-dir" \
-"${PROG} [a-z]*: Updating first-dir
+"${PROG} checkout: Updating first-dir
U first-dir/file1"
dotest crerepos-17 "${testcvs} -d ${CREREPOS_ROOT} co crerepos-dir" \
-"${PROG} [a-z]*: Updating crerepos-dir
+"${PROG} checkout: Updating crerepos-dir
U crerepos-dir/cfile"
dotest crerepos-18 "${testcvs} update" \
-"${PROG} [a-z]*: Updating first-dir
-${PROG} [a-z]*: Updating crerepos-dir"
+"${PROG} update: Updating first-dir
+${PROG} update: Updating crerepos-dir"
cd ..
+ CVS_SERVER=$CVS_SERVER_save; export CVS_SERVER
+
if $keep; then
echo Keeping ${TESTDIR} and exiting due to --keep
exit 0
fi
+ rm -f $TESTDIR/cvs-setHome
rm -r 1
rm -rf ${CVSROOT_DIRNAME}/first-dir ${TESTDIR}/crerepos
;;
+
+
rcs)
# Test ability to import an RCS file. Note that this format
# is fixed--files written by RCS5, and other software which
@@ -17200,14 +19289,14 @@ EOF
# question one way or the other (it has a grammar but almost
# nothing about lexical analysis).
dotest_fail rcs3-1 "${testcvs} -q co first-dir" \
-"${PROG} \[[a-z]* aborted\]: EOF while looking for value in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v"
+"${PROG} \[checkout aborted\]: EOF while looking for value in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v"
cat <<EOF >${CVSROOT_DIRNAME}/first-dir/file1,v
head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02
; author jeremiah ;state ; branches; next;desc @@1.1log@@text@head@
EOF
# Whitespace issues, likewise.
dotest_fail rcs3-2 "${testcvs} -q co first-dir" \
-"${PROG} \[[a-z]* aborted\]: unexpected '.x6c' reading revision number in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v"
+"${PROG} \[checkout aborted\]: unexpected '.x6c' reading revision number in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v"
cat <<EOF >${CVSROOT_DIRNAME}/first-dir/file1,v
head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02
; author jeremiah ;state ; branches; next;desc @@1.1 log@@text@head@
@@ -17215,7 +19304,7 @@ EOF
# Charming array of different messages for similar
# whitespace issues (depending on where the whitespace is).
dotest_fail rcs3-3 "${testcvs} -q co first-dir" \
-"${PROG} \[[a-z]* aborted\]: EOF while looking for value in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v"
+"${PROG} \[checkout aborted\]: EOF while looking for value in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v"
cat <<EOF >${CVSROOT_DIRNAME}/first-dir/file1,v
head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02
; author jeremiah ;state ; branches; next;desc @@1.1 log @@text @head@
@@ -17240,13 +19329,102 @@ EOF
${AWK} </dev/null 'BEGIN { printf "@%c", 10 }' | ${TR} '@' '\000' \
>>${CVSROOT_DIRNAME}/first-dir/file1,v
dotest_fail rcs3-7 "${testcvs} log -s nostate file1" \
-"${PROG} \[[a-z]* aborted\]: unexpected '.x0' reading revision number in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v"
+"${PROG} \[log aborted\]: unexpected '.x0' reading revision number in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v"
cd ../..
rm -r 1
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ rcs4)
+ # Fix a bug that shows up when checking out files by date with the
+ # "-D date" command line option. There is code in the original to
+ # handle a special case. If the date search finds revision 1.1 it
+ # is supposed to check whether revision 1.1.1.1 has the same date
+ # stamp, which would indicate that the file was originally brought
+ # in with "cvs import". In that case it is supposed to return the
+ # vendor branch version 1.1.1.1.
+ #
+ # However, there is a bug in the code. It actually compares
+ # the date of revision 1.1 for equality with the date given
+ # on the command line -- clearly wrong. This commit fixes
+ # the coding bug.
+ #
+ # There is an additional bug which is _not_ fixed yet.
+ # The date comparison should not be a strict
+ # equality test. It should allow a fudge factor of, say, 2-3
+ # seconds. Old versions of CVS created the two revisions
+ # with two separate invocations of the RCS "ci" command. We
+ # have many old files in the tree in which the dates of
+ # revisions 1.1 and 1.1.1.1 differ by 1 second.
+
+ mkdir rcs4
+ cd rcs4
+
+ mkdir imp-dir
+ cd imp-dir
+ echo 'OpenMunger sources' >file1
+
+ # choose a time in the past to demonstrate the problem
+ TZ=GMT touch -t 200012010123 file1
+
+ dotest_sort rcs4-1 \
+"${testcvs} import -d -m add rcs4-dir openmunger openmunger-1_0" \
+'
+
+N rcs4-dir/file1
+No conflicts created by this import'
+ echo 'OpenMunger sources release 1.1 extras' >>file1
+ TZ=GMT touch -t 200112011234 file1
+ dotest_sort rcs4-2 \
+"${testcvs} import -d -m add rcs4-dir openmunger openmunger-1_1" \
+'
+
+No conflicts created by this import
+U rcs4-dir/file1'
+ cd ..
+ # Next checkout the new module
+ dotest rcs4-3 \
+"${testcvs} -q co rcs4-dir" \
+'U rcs4-dir/file1'
+ cd rcs4-dir
+ echo 'local change' >> file1
+
+ # commit a local change
+ dotest rcs4-4 \
+"${testcvs} -q commit -m hack file1" \
+"Checking in file1;
+${CVSROOT_DIRNAME}/rcs4-dir/file1,v <-- file1
+new revision: 1\.2; previous revision: 1\.1
+done"
+ # now see if we get version 1.1 or 1.1.1.1 when we ask for
+ # a checkout by time... it really should be 1.1.1.1 as
+ # that was indeed the version that was visible at the target
+ # time.
+ dotest rcs4-5 \
+"${testcvs} -q update -D 'October 1, 2001 UTC' file1" \
+'[UP] file1'
+ dotest rcs4-6 \
+"${testcvs} -q status file1" \
+'===================================================================
+File: file1 Status: Up-to-date
+
+ Working revision: 1\.1\.1\.1.*
+ Repository revision: 1\.1\.1\.1 '${CVSROOT_DIRNAME}'/rcs4-dir/file1,v
+ Sticky Tag: (none)
+ Sticky Date: 2001\.10\.01\.00\.00\.00
+ Sticky Options: (none)'
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ rm -r rcs4
+ rm -rf ${CVSROOT_DIRNAME}/rcs4-dir
+ ;;
+
lockfiles)
# Tests of CVS lock files.
# TODO-maybe: Add a test where we arrange for a loginfo
@@ -17272,15 +19450,20 @@ EOF
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../first-dir/sdir/ssdir
# The error message appears twice because Lock_Cleanup only
# stops recursing after the first attempt.
dotest_fail lockfiles-5 "${testcvs} -q update" \
-"${PROG} \[[a-z]* aborted\]: cannot stat ${TESTDIR}/locks: No such file or directory
-${PROG} \[[a-z]* aborted\]: cannot stat ${TESTDIR}/locks: No such file or directory"
+"${PROG} \[update aborted\]: cannot stat ${TESTDIR}/locks: No such file or directory
+${PROG} \[update aborted\]: cannot stat ${TESTDIR}/locks: No such file or directory"
mkdir ${TESTDIR}/locks
- chmod u=rwx,g=r,o= ${TESTDIR}/locks
+ # Grumble, mumble. Cygwin.
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod u=rwx,g=r,o= ${TESTDIR}/locks"
+ else
+ chmod u=rwx,g=r,o= ${TESTDIR}/locks
+ fi
umask 0077
CVSUMASK=0077; export CVSUMASK
dotest lockfiles-6 "${testcvs} -q update" ""
@@ -17293,10 +19476,19 @@ ${PROG} \[[a-z]* aborted\]: cannot stat ${TESTDIR}/locks: No such file or direct
# inherit the permissions from the parent directory. CVSUMASK
# isn't right, because typically the reason for LockDir is to
# use a different set of permissions.
- dotest lockfiles-7a "ls -ld ${TESTDIR}/locks/first-dir" \
-"drwxr----- .*first-dir"
- dotest lockfiles-7b "ls -ld ${TESTDIR}/locks/first-dir/sdir/ssdir" \
-"drwxr----- .*first-dir/sdir/ssdir"
+ #
+ # Bah! Cygwin!
+ if test -n "$remotehost"; then
+ dotest lockfiles-7a "$CVS_RSH $remotehost 'ls -ld ${TESTDIR}/locks/first-dir'" \
+"drwxr-----.*first-dir"
+ dotest lockfiles-7b "$CVS_RSH $remotehost 'ls -ld ${TESTDIR}/locks/first-dir/sdir/ssdir'" \
+"drwxr-----.*first-dir/sdir/ssdir"
+ else
+ dotest lockfiles-7a "ls -ld ${TESTDIR}/locks/first-dir" \
+"drwxr-----.*first-dir"
+ dotest lockfiles-7b "ls -ld ${TESTDIR}/locks/first-dir/sdir/ssdir" \
+"drwxr-----.*first-dir/sdir/ssdir"
+ fi
cd ../../..
dotest lockfiles-8 "${testcvs} -q update" ""
@@ -17309,7 +19501,7 @@ ${PROG} \[[a-z]* aborted\]: cannot stat ${TESTDIR}/locks: No such file or direct
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../..
# Perhaps should restore the umask and CVSUMASK to what they
# were before. But the other tests "should" not care about them...
@@ -17353,7 +19545,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
"Directory ${CVSROOT_DIRNAME}/first-dir/dir added to the repository"
touch file1 dir/file2
dotest backuprecover-4 "${testcvs} -q add file1 dir/file2" \
-"${PROG} [a-z]*: use '${PROG} commit' to add these files permanently"
+"${PROG} add: use .${PROG} commit. to add these files permanently"
dotest backuprecover-5 "${testcvs} -q ci -mtest" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -17417,7 +19609,7 @@ new revision: 1\.3; previous revision: 1\.2
done"
# Save a backup copy
- cp -r ${CVSROOT_DIRNAME}/first-dir ${TESTDIR}/cvsroot/backup
+ cp -r ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/backup
# Simulate developer 3
cd ../..
@@ -17488,16 +19680,16 @@ done"
# Slag the original and restore it a few revisions back
rm -rf ${CVSROOT_DIRNAME}/first-dir
- mv ${CVSROOT_DIRNAME}/backup ${TESTDIR}/cvsroot/first-dir
+ mv ${CVSROOT_DIRNAME}/backup ${CVSROOT_DIRNAME}/first-dir
# Have developer 1 try an update and lose some data
#
# Feel free to imagine the horrific scream of despair
cd ../../1/first-dir
dotest backuprecover-15 "${testcvs} update" \
-"${PROG} [a-z]*: Updating .
+"${PROG} update: Updating .
U file1
-${PROG} [a-z]*: Updating dir
+${PROG} update: Updating dir
U dir/file2"
# Developer 3 tries the same thing (he has an office)
@@ -17505,8 +19697,8 @@ U dir/file2"
# uncommitted changes
cd ../../3/first-dir
dotest_fail backuprecover-16 "${testcvs} update" \
-"${PROG} [a-z]*: Updating \.
-${PROG} \[[a-z]* aborted\]: could not find desired version 1\.6 in ${CVSROOT_DIRNAME}/first-dir/file1,v"
+"${PROG} update: Updating \.
+${PROG} \[update aborted\]: could not find desired version 1\.6 in ${CVSROOT_DIRNAME}/first-dir/file1,v"
# create our workspace fixin' script
cd ../..
@@ -17552,21 +19744,21 @@ done"
# and we should get a conflict on developer 4's stuff
cd ../../4/first-dir
dotest backuprecover-20 "${testcvs} update" \
-"${PROG} [a-z]*: Updating \.
+"${PROG} update: Updating \.
RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
retrieving revision 1\.3
retrieving revision 1\.4
Merging differences between 1\.3 and 1\.4 into file1
rcsmerge: warning: conflicts during merge
-${PROG} [a-z]*: conflicts found in file1
+${PROG} update: conflicts found in file1
C file1
-${PROG} [a-z]*: Updating dir
+${PROG} update: Updating dir
RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/file2,v
retrieving revision 1\.3
retrieving revision 1\.4
Merging differences between 1\.3 and 1\.4 into file2
rcsmerge: warning: conflicts during merge
-${PROG} [a-z]*: conflicts found in dir/file2
+${PROG} update: conflicts found in dir/file2
C dir/file2"
sed -e \
"/^<<<<<<</,/^=======/d
@@ -17722,8 +19914,8 @@ O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= <remote>/\*"
done
done
dotest big-2 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest big-3 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -17779,8 +19971,8 @@ done"
cd first-dir
touch aa
dotest modes-3 "${testcvs} add aa" \
-"${PROG} [a-z]*: scheduling file .aa. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .aa. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest modes-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v
done
@@ -17788,8 +19980,14 @@ Checking in aa;
${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa
initial revision: 1\.1
done"
- dotest modes-5 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \
+ # Yawn. Cygwin.
+ if test -n "$remotehost"; then
+ dotest modes-5remotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \
"-r--r--r-- .*"
+ else
+ dotest modes-5 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \
+"-r--r--r-- .*"
+ fi
# Test for whether we can set the execute bit.
chmod +x aa
@@ -17802,19 +20000,38 @@ done"
# If CVS let us update the execute bit, it would be set here.
# But it doesn't, and as far as I know that is longstanding
# CVS behavior.
- dotest modes-7 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \
+ #
+ # Yeah, yeah. Search for "Cygwin".
+ if test -n "$remotehost"; then
+ dotest modes-7remotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \
"-r--r--r-- .*"
+ else
+ dotest modes-7 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \
+"-r--r--r-- .*"
+ fi
# OK, now manually change the modes and see what happens.
- chmod g=r,o= ${CVSROOT_DIRNAME}/first-dir/aa,v
+ #
+ # Cygwin, already.
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod g=r,o= ${CVSROOT_DIRNAME}/first-dir/aa,v"
+ else
+ chmod g=r,o= ${CVSROOT_DIRNAME}/first-dir/aa,v
+ fi
echo second line >>aa
dotest modes-7a "${testcvs} -q ci -m set-execute-bit" \
"Checking in aa;
${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa
new revision: 1\.3; previous revision: 1\.2
done"
- dotest modes-7b "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \
+ # Cygwin.
+ if test -n "$remotehost"; then
+ dotest modes-7bremotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \
+"-r--r----- .*"
+ else
+ dotest modes-7b "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \
"-r--r----- .*"
+ fi
CVSUMASK=007
export CVSUMASK
@@ -17822,8 +20039,8 @@ done"
# Might as well test the execute bit too.
chmod +x ab
dotest modes-8 "${testcvs} add ab" \
-"${PROG} [a-z]*: scheduling file .ab. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .ab. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest modes-9 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/ab,v
done
@@ -17835,8 +20052,13 @@ done"
# The problem here is that the CVSUMASK environment variable
# needs to be set on the server (e.g. .bashrc). This is, of
# course, bogus, but that is the way it is currently.
- dotest modes-10r "ls -l ${CVSROOT_DIRNAME}/first-dir/ab,v" \
+ if test -n "$remotehost"; then
+ dotest modes-10remotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/ab,v'" \
+"-r--r--r--.*"
+ else
+ dotest modes-10r "ls -l ${CVSROOT_DIRNAME}/first-dir/ab,v" \
"-r-xr-x---.*" "-r-xr-xr-x.*"
+ fi
else
dotest modes-10 "ls -l ${CVSROOT_DIRNAME}/first-dir/ab,v" \
"-r-xr-x---.*"
@@ -17849,8 +20071,8 @@ T ab'
dotest modes-12 "${testcvs} -q update -r br" ''
touch ac
dotest modes-13 "${testcvs} add ac" \
-"${PROG} [a-z]*: scheduling file .ac. for addition on branch .br.
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .ac. for addition on branch .br.
+${PROG} add: use .${PROG} commit. to add this file permanently"
# Not sure it really makes sense to refer to a "previous revision"
# when we are just now adding the file; as far as I know
# that is longstanding CVS behavior, for what it's worth.
@@ -17868,9 +20090,15 @@ done"
# first match is for the :ext: method (where the CVSUMASK
# won't be set), while the second is for the :fork: method
# (where it will be).
- dotest modes-15r \
+ if test -n "$remotehost"; then
+ dotest modes-15r \
+"$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v'" \
+"-r--r--r--.*"
+ else
+ dotest modes-15r \
"ls -l ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v" \
"-r--r--r--.*" "-r--r-----.*"
+ fi
else
dotest modes-15 \
"ls -l ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v" \
@@ -17897,8 +20125,8 @@ done"
cd first-dir
touch aa
dotest modes2-3 "${testcvs} add aa" \
-"${PROG} [a-z]*: scheduling file .aa. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .aa. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest modes2-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v
done
@@ -17920,9 +20148,12 @@ done"
# do this while the file is still writable.
touch aa
chmod a= aa
- dotest_fail modes2-6 "${testcvs} -q update -r 1.1 aa" \
+ # Don't try this when permissions are broken, as with Cygwin.
+ if ls ${CVSROOT_DIRNAME}/first-dir >/dev/null 2>&1; then :; else
+ dotest_fail modes2-6 "${testcvs} -q update -r 1.1 aa" \
"${PROG} \[update aborted\]: cannot open file aa for comparing: Permission denied" \
"${PROG} \[update aborted\]: reading aa: Permission denied"
+ fi
chmod u+rwx aa
cd ../..
@@ -17944,9 +20175,9 @@ done"
Directory ${CVSROOT_DIRNAME}/second-dir added to the repository"
touch first-dir/aa second-dir/ab
dotest modes3-3 "${testcvs} add first-dir/aa second-dir/ab" \
-"${PROG} [a-z]*: scheduling file .first-dir/aa. for addition
-${PROG} [a-z]*: scheduling file .second-dir/ab. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .first-dir/aa. for addition
+${PROG} add: scheduling file .second-dir/ab. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest modes3-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v
done
@@ -17960,32 +20191,64 @@ Checking in second-dir/ab;
${CVSROOT_DIRNAME}/second-dir/ab,v <-- ab
initial revision: 1\.1
done"
- chmod a= ${CVSROOT_DIRNAME}/first-dir
- dotest modes3-5 "${testcvs} update" \
-"${PROG} [a-z]*: Updating \.
-${PROG} [a-z]*: Updating first-dir
-${PROG} [a-z]*: cannot open directory ${CVSROOT_DIRNAME}/first-dir: Permission denied
-${PROG} [a-z]*: skipping directory first-dir
-${PROG} [a-z]*: Updating second-dir"
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod a= ${CVSROOT_DIRNAME}/first-dir"
+ else
+ chmod a= ${CVSROOT_DIRNAME}/first-dir
+ fi
+ if ls ${CVSROOT_DIRNAME}/first-dir >/dev/null 2>&1; then
+ # Avoid this test under Cygwin since permissions work differently
+ # there.
+ #
+ # This test also gets avoided under Mac OS X since the system `ls'
+ # is broken and exits with a 0 status despite the permission
+ # denied error.
+ if test -n "$remotehost"; then
+ cygwin_hack=false
+ else
+ cygwin_hack=:
+ fi
+ else
+ cygwin_hack=false
+ fi
+
+ cd $TESTDIR/1
+ if $cygwin_hack; then :; else
+ dotest modes3-5 "${testcvs} update" \
+"${PROG} update: Updating \.
+${PROG} update: Updating first-dir
+${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/first-dir: Permission denied
+${PROG} update: skipping directory first-dir
+${PROG} update: Updating second-dir"
+ fi
# OK, I can see why one might say the above case could be a
# fatal error, because normally users without access to first-dir
# won't have it in their working directory. But the next
# one is more of a problem if it is fatal.
+ #
+ # The second text string below is for Cygwin again, and again it
+ # should really be XFAIL under Cygwin, but for now deal with the
+ # passing opendir by accepting the alternate string.
rm -r first-dir
dotest modes3-6 "${testcvs} update -dP" \
-"${PROG} [a-z]*: Updating .
-${PROG} [a-z]*: Updating CVSROOT
+"${PROG} update: Updating .
+${PROG} update: Updating CVSROOT
+U ${DOTSTAR}
+${PROG} update: Updating first-dir
+${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/first-dir: Permission denied
+${PROG} update: skipping directory first-dir
+${PROG} update: Updating second-dir" \
+"${PROG} update: Updating .
+${PROG} update: Updating CVSROOT
U ${DOTSTAR}
-${PROG} [a-z]*: Updating first-dir
-${PROG} [a-z]*: cannot open directory ${CVSROOT_DIRNAME}/first-dir: Permission denied
-${PROG} [a-z]*: skipping directory first-dir
-${PROG} [a-z]*: Updating second-dir"
+${PROG} update: Updating first-dir
+${PROG} update: Updating second-dir"
cd ..
rm -r 1
chmod u+rwx ${CVSROOT_DIRNAME}/first-dir
- rm -rf ${CVSROOT_DIRNAME}/first-dir ${TESTDIR}/cvsroot/second-dir
+ rm -rf ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/second-dir
;;
stamps)
@@ -17998,6 +20261,10 @@ ${PROG} [a-z]*: Updating second-dir"
cd first-dir
touch aa
echo '$''Id$' >kw
+ # Cygwin, *cough*, puts the year in the time column until the minute
+ # is no longer the current minute. Sleep 60 seconds to avoid this
+ # problem.
+ sleep 60
ls -l aa >${TESTDIR}/1/stamp.aa.touch
ls -l kw >${TESTDIR}/1/stamp.kw.touch
# "sleep 1" would suffice if we could assume ls --full-time, but
@@ -18005,9 +20272,9 @@ ${PROG} [a-z]*: Updating second-dir"
# way to get the timestamp of a file, including the seconds?
sleep 60
dotest stamps-3 "${testcvs} add aa kw" \
-"${PROG} [a-z]*: scheduling file .aa. for addition
-${PROG} [a-z]*: scheduling file .kw. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .aa. for addition
+${PROG} add: scheduling file .kw. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
ls -l aa >${TESTDIR}/1/stamp.aa.add
ls -l kw >${TESTDIR}/1/stamp.kw.add
# "cvs add" should not muck with the timestamp.
@@ -18029,6 +20296,10 @@ Checking in kw;
${CVSROOT_DIRNAME}/first-dir/kw,v <-- kw
initial revision: 1\.1
done"
+ # Cygwin, *cough*, puts the year in the time column until the minute
+ # is no longer the current minute. Sleep 60 seconds to avoid this
+ # problem.
+ sleep 60
ls -l aa >${TESTDIR}/1/stamp.aa.ci
ls -l kw >${TESTDIR}/1/stamp.kw.ci
# If there are no keywords, "cvs ci" leaves the timestamp alone
@@ -18080,6 +20351,11 @@ Checking in kw;
${CVSROOT_DIRNAME}/first-dir/kw,v <-- kw
new revision: 1\.2; previous revision: 1\.1
done"
+
+ # Cygwin, *cough*, puts the year in the time column until the minute
+ # is no longer the current minute. Sleep 60 seconds to avoid this
+ # problem.
+ sleep 60
ls -l aa >${TESTDIR}/1/stamp.aa.ci2
ls -l kw >${TESTDIR}/1/stamp.kw.ci2
cd ../..
@@ -18144,8 +20420,8 @@ done"
touch foo
chmod 431 foo
dotest perms-3 "${testcvs} add foo" \
-"${PROG} [a-z]*: scheduling file .foo. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .foo. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest perms-4 "${testcvs} -q ci -m ''" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/foo,v
done
@@ -18188,8 +20464,8 @@ done"
dotest symlinks-2.1 "ln -s ${TESTDIR}/fumble slink" ""
dotest symlinks-3 "${testcvs} add slink" \
-"${PROG} [a-z]*: scheduling file .slink. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .slink. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
if $remote; then
# Remote doesn't implement PreservePermissions, and in its
# absence the correct behavior is to follow the symlink.
@@ -18234,8 +20510,8 @@ done"
cd first-dir
echo nonsymlink > slink
dotest symlinks2-3 "${testcvs} add slink" \
-"${PROG} [a-z]*: scheduling file .slink. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .slink. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest symlinks2-4 "${testcvs} -q ci -m ''" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/slink,v
done
@@ -18299,10 +20575,10 @@ done"
fi
dotest hardlinks-3 "${testcvs} add [abd]*" \
-"${PROG} [a-z]*: scheduling file .aaaa. for addition
-${PROG} [a-z]*: scheduling file .b\.b\.b\.b. for addition
-${PROG} [a-z]*: scheduling file .dd dd dd. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .aaaa. for addition
+${PROG} add: scheduling file .b\.b\.b\.b. for addition
+${PROG} add: scheduling file .dd dd dd. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest hardlinks-4 "${testcvs} -q ci -m ''" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaaa,v
done
@@ -18377,8 +20653,8 @@ U first-dir/dd dd dd"
touch file1
dotest sticky-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest sticky-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -18399,13 +20675,13 @@ done"
dotest sticky-10 "cat file1" ''
touch file2
dotest_fail sticky-11 "${testcvs} add file2" \
-"${PROG} [a-z]*: cannot add file on non-branch tag tag1"
+"${PROG} add: cannot add file on non-branch tag tag1"
dotest sticky-12 "${testcvs} -q update -A" "[UP] file1
${QUESTION} file2" "${QUESTION} file2
[UP] file1"
dotest sticky-13 "${testcvs} add file2" \
-"${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest sticky-14 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
done
@@ -18416,12 +20692,12 @@ done"
# Now back to tag1
dotest sticky-15 "${testcvs} -q update -r tag1" "[UP] file1
-${PROG} [a-z]*: file2 is no longer in the repository"
+${PROG} update: file2 is no longer in the repository"
rm file1
dotest sticky-16 "${testcvs} rm file1" \
-"${PROG} [a-z]*: scheduling .file1. for removal
-${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+"${PROG} remove: scheduling .file1. for removal
+${PROG} remove: use .${PROG} commit. to remove this file permanently"
# Hmm, this command seems to silently remove the tag from
# the file. This appears to be intentional.
# The silently part especially strikes me as odd, though.
@@ -18429,15 +20705,15 @@ ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
dotest sticky-18 "${testcvs} -q update -A" "U file1
U file2"
dotest sticky-19 "${testcvs} -q update -r tag1" \
-"${PROG} [a-z]*: file1 is no longer in the repository
-${PROG} [a-z]*: file2 is no longer in the repository"
+"${PROG} update: file1 is no longer in the repository
+${PROG} update: file2 is no longer in the repository"
dotest sticky-20 "${testcvs} -q update -A" "U file1
U file2"
# Now try with a numeric revision.
dotest sticky-21 "${testcvs} -q update -r 1.1 file1" "U file1"
dotest sticky-22 "${testcvs} rm -f file1" \
-"${PROG} [a-z]*: cannot remove file .file1. which has a numeric sticky tag of .1\.1."
+"${PROG} remove: cannot remove file .file1. which has a numeric sticky tag of .1\.1."
# The old behavior was that remove allowed this and then commit
# gave an error, which was somewhat hard to clear. I mean, you
# could get into a long elaborate discussion of this being a
@@ -18452,13 +20728,13 @@ U file2"
# discrepency between local and remote CVS and should probably
# be cleaned up at some point.
dotest sticky-23 "${testcvs} -q update -Dnow file1" \
-"${PROG} [a-z]*: warning: file1 was lost
+"${PROG} update: warning: file1 was lost
U file1" "U file1"
dotest sticky-24 "${testcvs} rm -f file1" \
-"${PROG} [a-z]*: cannot remove file .file1. which has a sticky date of .[0-9.]*."
+"${PROG} remove: cannot remove file .file1. which has a sticky date of .[0-9.]*."
dotest sticky-25 "${testcvs} -q update -A" \
-"${PROG} [a-z]*: warning: file1 was lost
+"${PROG} update: warning: file1 was lost
U file1" "U file1"
cd ../..
@@ -18505,8 +20781,8 @@ U file1" "U file1"
echo 'xx $''Log$' >> file1
dotest keyword-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest keyword-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -18655,7 +20931,16 @@ done"
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.3; previous revision: 1\.2
done"
- dotest keyword-21 "${testcvs} -q update -r tag1" "[UP] file1"
+ # FIXCVS - These unpatchable files are happening because the tag
+ # associated with the current base version of the file in the
+ # sandbox is not available in these cases. See the note in the
+ # patch_file function in update.c.
+ dotest keyword-21 "${testcvs} -q update -r tag1" "U file1" \
+"P file1
+${PROG} update: checksum failure after patch to \./file1; will refetch
+${PROG} client: refetching unpatchable files
+${PROG} update: warning: file1 was lost
+U file1"
dotest keyword-22 "cat file1" '\$'"Name: tag1 "'\$'
@@ -18665,6 +20950,7 @@ done"
dotest keyword-23r "${testcvs} update -A file1" "P file1
${PROG} update: checksum failure after patch to \./file1; will refetch
${PROG} client: refetching unpatchable files
+${PROG} update: warning: file1 was lost
U file1"
else
dotest keyword-23 "${testcvs} update -A file1" "[UP] file1"
@@ -18687,8 +20973,8 @@ change"
cd first-dir
echo initial >file1
dotest keywordlog-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
# See "rmadd" for a list of other tests of cvs ci -r.
dotest keywordlog-4 "${testcvs} -q ci -r 1.3 -m add file1" \
@@ -18712,8 +20998,8 @@ EOF
# As with rmadd-25, "cvs ci -r" sets a sticky tag.
dotest_fail keywordlog-4b \
"${testcvs} ci -F ${TESTDIR}/comment.tmp file1" \
-"${PROG} [a-z]*: sticky tag .1\.3. for file .file1. is not a branch
-${PROG} \[[a-z]* aborted\]: correct above errors first!"
+"${PROG} commit: sticky tag .1\.3. for file .file1. is not a branch
+${PROG} \[commit aborted\]: correct above errors first!"
dotest keywordlog-4c "${testcvs} -q update -A" "M file1"
dotest keywordlog-5 "${testcvs} ci -F ${TESTDIR}/comment.tmp file1" \
@@ -18900,6 +21186,135 @@ xx"
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ keywordname)
+ # Test the Name keyword.
+ # See the keyword test for a descriptions of some other tests that
+ # test keyword expansion modes.
+ mkdir keywordname; cd keywordname
+ mkdir 1; cd 1
+ dotest keywordname-init-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest keywordname-init-2 "${testcvs} add first-dir" \
+"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
+ cd first-dir
+
+ echo '$'"Name$" >file1
+ echo '$'"Name$" >file2
+ dotest keywordname-init-3 "${testcvs} add file1 file2" \
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
+
+ # See "rmadd" for a list of other tests of cvs ci -r.
+ dotest keywordname-init-4 "${testcvs} -q ci -r 1.3 -m add" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+done
+Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+initial revision: 1\.3
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+done
+Checking in file2;
+${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
+initial revision: 1\.3
+done"
+
+ dotest keywordname-init-6 "${testcvs} -q up -A"
+ dotest keywordname-init-7 "${testcvs} -q tag -b br" \
+"T file1
+T file2"
+
+ echo new data >>file1
+ dotest keywordname-init-8 "${testcvs} -q ci -mchange" \
+"Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+new revision: 1\.4; previous revision: 1\.3
+done"
+
+ # First check out a branch.
+ #
+ # There used to be a bug where static tags would be substituted for
+ # Name keywords but not branch tags.
+ #
+ # FIXCVS - BUG
+ # Why shouldn't the non-update case not cause a substitution?
+ # An update -kk or -A will unsub and sub keywords without updates
+ # being required.
+ # FIXCVS - see note above keyword-21
+ dotest keywordname-update-1 "${testcvs} -q up -rbr" "U file1" \
+"P file1
+${PROG} update: checksum failure after patch to \./file1; will refetch
+${PROG} client: refetching unpatchable files
+${PROG} update: warning: file1 was lost
+U file1"
+ dotest keywordname-update-2 "cat file1" '\$'"Name: br "'\$'
+ dotest keywordname-update-3 "cat file2" '\$'"Name: "'\$'
+
+ # Now verify that updating to the trunk leaves no substitution for
+ # $Name
+ dotest keywordname-update-4 "${testcvs} -q tag firsttag" \
+"T file1
+T file2"
+ # FIXCVS - see note above keyword-21
+ dotest keywordname-update-5 "${testcvs} -q up -A" "U file1" \
+"P file1
+${PROG} update: checksum failure after patch to \./file1; will refetch
+${PROG} client: refetching unpatchable files
+${PROG} update: warning: file1 was lost
+U file1"
+ dotest keywordname-update-6 "cat file1" \
+'\$'"Name: "'\$'"
+new data"
+ dotest keywordname-update-7 "cat file2" '\$'"Name: "'\$'
+
+ # But updating to a static tag does cause a substitution
+ # FIXCVS - see same note above
+ dotest keywordname-update-8 "${testcvs} -q up -rfirsttag" "U file1" \
+"P file1
+${PROG} update: checksum failure after patch to \./file1; will refetch
+${PROG} client: refetching unpatchable files
+${PROG} update: warning: file1 was lost
+U file1"
+ dotest keywordname-update-9 "cat file1" '\$'"Name: firsttag "'\$'
+ dotest keywordname-update-10 "cat file2" '\$'"Name: "'\$'
+
+ # And reverify the trunk update when the change is actually removed.
+ dotest keywordname-update-11 "${testcvs} -q up -A" "[UP] file1" \
+"P file1
+${PROG} update: checksum failure after patch to ./file1; will refetch
+${PROG} client: refetching unpatchable files
+${PROG} update: warning: file1 was lost
+U file1"
+ dotest keywordname-update-12 "cat file1" \
+'\$'"Name: "'\$'"
+new data"
+ dotest keywordname-update-13 "cat file2" '\$'"Name: "'\$'
+
+ cd ../..
+
+ # now verify that a fresh checkout substitutes all the $Name fields
+ mkdir 2; cd 2
+ dotest keywordname-checkout-1 \
+"${testcvs} -q co -rfirsttag first-dir" \
+"U first-dir/file1
+U first-dir/file2"
+ cd first-dir
+ dotest keywordname-checkout-2 "cat file1" '\$'"Name: firsttag "'\$'
+ dotest keywordname-checkout-3 "cat file2" '\$'"Name: firsttag "'\$'
+
+ cd ../..
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ cd ..
+ rm -r keywordname
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
keyword2)
# Test merging on files with keywords:
# without -kk
@@ -18932,16 +21347,16 @@ xx"
echo "did a much better" >>file1
echo "job." >>file1
dotest keyword2-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
${AWK} 'BEGIN { printf "%c%c%c%sRevision: 1.1 $@%c%c", \
2, 10, 137, "$", 13, 10 }' \
</dev/null | ${TR} '@' '\000' >../binfile.dat
cp ../binfile.dat .
dotest keyword2-5 "${testcvs} add -kb binfile.dat" \
-"${PROG} [a-z]*: scheduling file .binfile\.dat. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .binfile\.dat. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest keyword2-6 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v
@@ -19003,24 +21418,14 @@ diff -r1\.2 file1
# Here's the problem... shouldn't -kk a binary file...
rm file1
- if $remote; then
- dotest keyword2-13r "${testcvs} -q update -A -kk -j branch" \
-"U binfile.dat
-U file1
-RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
-retrieving revision 1\.1
-retrieving revision 1\.1\.2\.1
-Merging differences between 1\.1 and 1\.1\.2\.1 into file1"
- else
- dotest keyword2-13 "${testcvs} -q update -A -kk -j branch" \
-"U binfile.dat
-${PROG} [a-z]*: warning: file1 was lost
+ dotest keyword2-13 "${testcvs} -q update -A -kk -j branch" \
+"U binfile\.dat
+${PROG} update: warning: file1 was lost
U file1
RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
retrieving revision 1\.1
retrieving revision 1\.1\.2\.1
Merging differences between 1\.1 and 1\.1\.2\.1 into file1"
- fi
# binfile won't get checked in, but it is now corrupt and could
# have been checked in if it had changed on the branch...
@@ -19210,18 +21615,18 @@ ${PLUS} modify on branch after brtag"
# Note that we are testing both the case where this deletes
# a revision (file1) and the case where it does not (file2)
dotest_fail head-o0a "${testcvs} admin -o ::br1" \
-"${PROG} [a-z]*: Administrating \.
+"${PROG} admin: Administrating \.
RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
-${PROG} [a-z]*: cannot remove revision 1\.3\.2\.1 because it has tags
-${PROG} [a-z]*: RCS file for .file1. not modified\.
+${PROG} admin: cannot remove revision 1\.3\.2\.1 because it has tags
+${PROG} admin: RCS file for .file1. not modified\.
RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
done"
dotest head-o0b "${testcvs} tag -d brtag" \
-"${PROG} [a-z]*: Untagging \.
+"${PROG} tag: Untagging \.
D file1
D file2"
dotest head-o1 "${testcvs} admin -o ::br1" \
-"${PROG} [a-z]*: Administrating \.
+"${PROG} admin: Administrating \.
RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
deleting revision 1\.3\.2\.1
done
@@ -19258,8 +21663,8 @@ done"
echo trunk-1 >file1
dotest tagdate-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest tagdate-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -19292,7 +21697,7 @@ done"
# For some reason, doing this on a branch seems to be relevant.
dotest_fail tagdate-12 "${testcvs} -q update -j:yesterday" \
-"${PROG} \[[a-z]* aborted\]: argument to join may not contain a date specifier without a tag"
+"${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
@@ -19359,9 +21764,9 @@ Annotations for file1
echo trunk-1 >file1
echo trunk-1 >file2
dotest multibranch2-3 "${testcvs} add file1 file2" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest multibranch2-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -19498,8 +21903,8 @@ done"
file=m
: > $file
dotest tag8k-3 "$testcvs add $file" \
-"${PROG} [a-z]*: scheduling file .$file. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .$file. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest tag8k-4 "$testcvs -Q ci -m . $file" \
"RCS file: ${CVSROOT_DIRNAME}/$module/$file,v
done
@@ -19536,7 +21941,7 @@ done"
dotest tag8k-16 "$testcvs -Q tag $t-a $file" ''
# Extract the author value.
- name=`sed -n 's/.*; author \([^;]*\);.*/\1/p' ${CVSROOT_DIRNAME}/$module/$file,v|head -1`
+ name=`sed -n 's/.*; author \([^;]*\);.*/\1/p' ${CVSROOT_DIRNAME}/$module/$file,v|sed 1q`
# Form a suffix string of length (16 - length($name)).
# CAREFUL: this will lose if $name is longer than 16.
@@ -19597,15 +22002,17 @@ done"
${PROG} admin: run add or import to create an RCS file
${PROG} \[admin aborted\]: specify ${PROG} -H admin for usage information"
dotest_fail admin-4 "${testcvs} -q log file1" \
-"${PROG} [a-z]*: nothing known about file1"
+"${PROG} log: nothing known about file1"
+ dotest_fail admin-4a "${testcvs} -q admin file1" \
+"${PROG} admin: nothing known about file1"
# Set up some files, file2 a plain one and file1 with a revision
# on a branch.
touch file1 file2
dotest admin-5 "${testcvs} add file1 file2" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest admin-6 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -19623,12 +22030,35 @@ done"
T file2"
dotest admin-8 "${testcvs} -q update -r br" ""
echo 'add a line on the branch' >> file1
- dotest admin-9 "${testcvs} -q ci -m modify-on-branch" \
+ echo 'add a file on the branch' >> file3
+ dotest admin-9a "${testcvs} -q add file3" \
+"${PROG} add: use .${PROG} commit. to add this file permanently"
+ dotest admin-9b "${testcvs} -q ci -m modify-on-branch" \
"Checking in file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.1\.2\.1; previous revision: 1\.1
+done
+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"
+ dotest admin-10 "${testcvs} -q update -A" \
+"U file1
+${PROG} update: file3 is no longer in the repository"
+
+ # Check that we can administer files in the repository that
+ # aren't in the working directory.
+ dotest admin-10-1 "${testcvs} admin ." \
+"${PROG} admin: Administrating .
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+done"
+ dotest admin-10-2 "${testcvs} -q admin file3" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
done"
- dotest admin-10 "${testcvs} -q update -A" "U file1"
# Try to recurse with a numeric revision arg.
# If we wanted to comprehensive about this, we would also test
@@ -19643,11 +22073,11 @@ ${PROG} \[[a-z]* aborted\]: attempt to specify a numeric revision"
# try a bad symbolic revision
dotest_fail admin-10c "${testcvs} -q admin -bBOGUS" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/file1,v: Symbolic name BOGUS is undefined.
-${PROG} [a-z]*: RCS file for .file1. not modified\.
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file1,v: Symbolic name BOGUS is undefined.
+${PROG} admin: RCS file for .file1. not modified\.
RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name BOGUS is undefined.
-${PROG} [a-z]*: RCS file for .file2. not modified\."
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name BOGUS is undefined.
+${PROG} admin: RCS file for .file2. not modified\."
# Note that -s option applies to the new default branch, not
# the old one.
@@ -19764,7 +22194,30 @@ text
@a0 1
add a line on the branch
@"
- dotest admin-14 "${testcvs} -q admin -aauth3 -aauth2,foo \
+ dotest_fail admin-14-1 "${testcvs} -q admin \
+-m1.1.1.1:changed-bogus-log-message file2" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+cvs admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: no such revision 1\.1\.1\.1
+cvs admin: RCS file for .file2. not modified."
+ dotest admin-14-2 "${testcvs} -q log file2" "
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+Working file: file2
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+ br: 1\.1\.0\.2
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+add
+============================================================================="
+
+ dotest admin-14-3 "${testcvs} -q admin -aauth3 -aauth2,foo \
-soneone:1.1 -m1.1:changed-log-message -ntagone: file2" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
done"
@@ -19824,8 +22277,8 @@ modify-on-branch
dotest_fail admin-18 "${testcvs} -q admin -nbr:1.1.2 file1" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/file1,v: symbolic name br already bound to 1\.1
-${PROG} [a-z]*: RCS file for .file1. not modified\."
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file1,v: symbolic name br already bound to 1\.1
+${PROG} admin: RCS file for .file1. not modified\."
dotest admin-19 "${testcvs} -q admin -ebaz -ebar,auth3 -nbr file1" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done"
@@ -19860,8 +22313,8 @@ modify-on-branch
dotest_fail admin-19a-nonexist \
"${testcvs} -q admin -A${TESTDIR}/foo/bar file1" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
-${PROG} [a-z]*: Couldn't open rcs file .${TESTDIR}/foo/bar.: No such file or directory
-${PROG} \[[a-z]* aborted\]: cannot continue"
+${PROG} admin: Couldn't open rcs file .${TESTDIR}/foo/bar.: No such file or directory
+${PROG} \[admin aborted\]: cannot continue"
# In the remote case, we are cd'd off into the temp directory
# and so these tests give "No such file or directory" errors.
@@ -19923,8 +22376,8 @@ done"
echo first rev > aaa
dotest admin-22-o1 "${testcvs} add aaa" \
-"${PROG} [a-z]*: scheduling file .aaa. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .aaa. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest admin-22-o2 "${testcvs} -q ci -m first aaa" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v
done
@@ -19985,8 +22438,8 @@ sixth
============================================================================="
dotest_fail admin-22-o10 "${testcvs} admin -o1.5: aaa" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/aaa,v: can't remove locked revision 1\.6
-${PROG} [a-z]*: RCS file for .aaa. not modified\."
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/aaa,v: can't remove locked revision 1\.6
+${PROG} admin: RCS file for .aaa. not modified\."
dotest admin-22-o11 "${testcvs} admin -u aaa" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v
1\.6 unlocked
@@ -20036,8 +22489,8 @@ done"
dotest_fail admin-22-o17 "${testcvs} admin -o1.2:1.4 aaa" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v
deleting revision 1\.4
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/aaa,v: can't remove branch point 1\.3
-${PROG} [a-z]*: RCS file for .aaa. not modified\."
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/aaa,v: can't remove branch point 1\.3
+${PROG} admin: RCS file for .aaa. not modified\."
dotest admin-22-o18 "${testcvs} update -p -r1.4 aaa" \
"===================================================================
Checking out aaa
@@ -20262,8 +22715,8 @@ done"
dotest_fail admin-27-4 "${testcvs} admin -ntagfour:1.3 file2" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/file2,v: symbolic name tagfour already bound to 1\.1
-${PROG} [a-z]*: RCS file for .file2. not modified\."
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: symbolic name tagfour already bound to 1\.1
+${PROG} admin: RCS file for .file2. not modified\."
# Succeed at reattaching existing tag, using -N
#
@@ -20276,37 +22729,37 @@ done"
#
dotest_fail admin-28-1 "${testcvs} admin -ntagsix:tagfive file2" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name or revision tagfive is undefined\.
-${PROG} [a-z]*: RCS file for .file2. not modified\."
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name or revision tagfive is undefined\.
+${PROG} admin: RCS file for .file2. not modified\."
# Try a some nonexisting numeric target tags
#
dotest_fail admin-28-2 "${testcvs} admin -ntagseven:2.1 file2" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-${PROG} \[[a-z]* aborted\]: revision .2\.1. does not exist"
+${PROG} \[admin aborted\]: revision .2\.1. does not exist"
dotest_fail admin-28-3 "${testcvs} admin -ntageight:2.1.2 file2" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-${PROG} \[[a-z]* aborted\]: revision .2\.1\.2. does not exist"
+${PROG} \[admin aborted\]: revision .2\.1\.2. does not exist"
# Try some invalid targets
#
dotest_fail admin-28-4 "${testcvs} admin -ntagnine:1.a.2 file2" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-${PROG} \[[a-z]* aborted\]: tag .1\.a\.2. must start with a letter"
+${PROG} \[admin aborted\]: tag .1\.a\.2. must start with a letter"
# Confirm that a missing tag is not a fatal error.
dotest admin-28-5.1 "${testcvs} -Q tag BO+GUS file1" ''
dotest_fail admin-28-5.2 "${testcvs} admin -ntagten:BO+GUS file2 file1" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name or revision BO${PLUS}GUS is undefined\.
-${PROG} [a-z]*: RCS file for .file2. not modified\.
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name or revision BO${PLUS}GUS is undefined\.
+${PROG} admin: RCS file for .file2. not modified\.
RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done"
dotest_fail admin-28-6 "${testcvs} admin -nq.werty:tagfour file2" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-${PROG} \[[a-z]* aborted\]: tag .q\.werty. must not contain the characters ..*"
+${PROG} \[admin aborted\]: tag .q\.werty. must not contain the characters ..*"
# Verify the archive
#
@@ -20377,7 +22830,141 @@ text
@d2 1
@"
+ dotest_fail admin-30 "${testcvs} admin -mbr:another-log-message \
+file2 aaa file3" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: no such revision br: 1\.1
+${PROG} admin: RCS file for .file2. not modified.
+RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/aaa,v: no such revision br
+${PROG} admin: RCS file for .aaa. not modified.
+RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
+done"
+ dotest admin-31 "${testcvs} log" \
+"${PROG} log: Logging \.
+
+RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v
+Working file: aaa
+head: 1\.4
+branch:
+locks: strict
+access list:
+symbolic names:
+ br1: 1\.3\.0\.2
+keyword substitution: kv
+total revisions: 5; selected revisions: 5
+description:
+----------------------------
+revision 1\.4
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+fourth
+----------------------------
+revision 1\.3
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+branches: 1\.3\.2;
+third
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+second
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+first
+----------------------------
+revision 1\.3\.2\.4
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}4 -0
+branch-four
+=============================================================================
+
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+Working file: file1
+head: 1\.1
+branch:
+locks: strict
+access list:
+ foo
+ auth2
+symbolic names:
+ tagten: 1\.1
+ BO${PLUS}GUS: 1\.1
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+branches: 1\.1\.2;
+add
+----------------------------
+revision 1\.1\.2\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: foo; lines: ${PLUS}1 -0
+modify-on-branch
+=============================================================================
+
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+Working file: file2
+head: 1\.4
+branch:
+locks: strict
+access list:
+ auth3
+ auth2
+ foo
+symbolic names:
+ tagfour: 1\.3
+ br4: 1\.1\.0\.2
+ br2: 1\.1\.0\.2
+ tagthree: 1\.1
+ br1: 1\.1\.0\.2
+ tagtwo: 1\.1
+ tagone: 1\.1
+ br: 1\.1\.0\.2
+keyword substitution: kv
+total revisions: 3; selected revisions: 3
+description:
+----------------------------
+revision 1\.4
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+yet_another
+----------------------------
+revision 1\.3
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+nuthr_line
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+modify
+=============================================================================
+
+RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
+Working file: file3
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+ br: 1\.1\.0\.2
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: dead;
+branches: 1\.1\.2;
+file file3 was initially added on branch br\.
+----------------------------
+revision 1\.1\.2\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
+another-log-message
+============================================================================="
+
cd ../..
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+ # clean up our after ourselves
rm -r 1
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
@@ -20403,8 +22990,8 @@ text
cd first-dir
touch file1
dotest reserved-3 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest reserved-4 "${testcvs} -q ci -m add" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -20478,12 +23065,17 @@ else
exit 1
fi
EOF
- chmod +x ${TESTDIR}/lockme
+ # Cygwin. Blaaarg.
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod +x ${TESTDIR}/lockme"
+ else
+ chmod +x ${TESTDIR}/lockme
+ fi
echo stuff > a-lock
dotest reserved-9 "${testcvs} add a-lock" \
-"${PROG} [a-z]*: scheduling file .a-lock. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .a-lock. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest reserved-10 "${testcvs} -q ci -m new a-lock" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v
done
@@ -20508,29 +23100,39 @@ done"
${CVSROOT_DIRNAME}/CVSROOT/commitinfo,v <-- commitinfo
new revision: 1\.2; previous revision: 1\.1
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..; cd first-dir
# Simulate (approximately) what a-lock would look like
# if someone else had locked revision 1.1.
sed -e 's/locks; strict;/locks fred:1.1; strict;/' ${CVSROOT_DIRNAME}/first-dir/a-lock,v > a-lock,v
- chmod 644 ${CVSROOT_DIRNAME}/first-dir/a-lock,v
+ # Cygwin.
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod 644 ${CVSROOT_DIRNAME}/first-dir/a-lock,v"
+ else
+ chmod 644 ${CVSROOT_DIRNAME}/first-dir/a-lock,v
+ fi
dotest reserved-13 "mv a-lock,v ${CVSROOT_DIRNAME}/first-dir/a-lock,v"
- chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v
+ # Cygwin. Blah.
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v"
+ else
+ chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v
+ fi
echo more stuff >> a-lock
dotest_fail reserved-13b "${testcvs} ci -m '' a-lock" \
"fred has file a-lock locked for version 1\.1
-${PROG} [a-z]*: Pre-commit check failed
-${PROG} \[[a-z]* aborted\]: correct above errors first!"
+${PROG} commit: Pre-commit check failed
+${PROG} \[commit aborted\]: correct above errors first!"
# OK, now test "cvs admin -l" in the case where someone
# else has the file locked.
dotest_fail reserved-13c "${testcvs} admin -l a-lock" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v
-${PROG} \[[a-z]* aborted\]: Revision 1\.1 is already locked by fred"
+${PROG} \[admin aborted\]: Revision 1\.1 is already locked by fred"
dotest reserved-14 "${testcvs} admin -u1.1 a-lock" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v
-${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/a-lock,v: revision 1\.1 locked by fred; breaking lock
+${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/a-lock,v: revision 1\.1 locked by fred; breaking lock
1\.1 unlocked
done"
dotest reserved-15 "${testcvs} -q ci -m success a-lock" \
@@ -20562,7 +23164,7 @@ done"
${CVSROOT_DIRNAME}/CVSROOT/commitinfo,v <-- commitinfo
new revision: 1\.3; previous revision: 1\.2
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ..; rm -r CVSROOT; cd first-dir
cd ../..
@@ -20590,7 +23192,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
# been lost. Later you discover this, and you suspect me of
# deliberately sabotaging your work, so you let all the air
# out of my tires. Only after a series of expensive lawsuits
- # and countersuits do we discover it this was all CVS's
+ # and countersuits do we discover that this was all CVS's
# fault.
#
# Luckily, this problem has been fixed now, as our test will
@@ -20712,6 +23314,7 @@ RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase07,v
retrieving revision 1\.1\.1\.1
retrieving revision 1\.1\.1\.1\.2\.1
Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase07
+testcase07 already contains the differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1
M testcase08
RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase08,v
retrieving revision 1\.1\.1\.1
@@ -21478,9 +24081,9 @@ EOF
dotest_fail release-7 "test -d first-dir/dir1" ''
dotest_fail release-8 "test -d first-dir/dir2/dir3" ''
dotest release-9 "${testcvs} update" \
-"${PROG} [a-z]*: Updating \.
-${PROG} [a-z]*: Updating first-dir
-${PROG} [a-z]*: Updating first-dir/dir2"
+"${PROG} update: Updating \.
+${PROG} update: Updating first-dir
+${PROG} update: Updating first-dir/dir2"
cd first-dir
mkdir dir1
@@ -21513,26 +24116,628 @@ EOF
rm -rf first-dir/dir1 first-dir/dir2
dotest release-16 "${testcvs} update" \
-"${PROG} [a-z]*: Updating \.
-${PROG} [a-z]*: Updating first-dir"
+"${PROG} update: Updating \.
+${PROG} update: Updating first-dir"
+
+ # Check to make sure release isn't overwriting a
+ # CVS/Entries file in the current directory (using data
+ # from the released directory).
+
+ # cvs 1.11 (remote) fails on release-21 (a message about
+ # chdir into the removed directory), although it seemingly
+ # unedits and removes the directory correctly. If
+ # you manually continue, it then fails on release-22 do
+ # to the messed up CVS/Entries file from release-21.
+ cd first-dir
+ mkdir second-dir
+ dotest release-18 "$testcvs add second-dir" \
+"Directory $CVSROOT_DIRNAME/first-dir/second-dir added to the repository"
+
+ cd second-dir
+ touch file1
+ dotest release-19 "$testcvs -Q add file1"
+ dotest release-20 '$testcvs -q ci -m add' \
+"RCS file: $CVSROOT_DIRNAME/first-dir/second-dir/file1,v
+done
+Checking in file1;
+$CVSROOT_DIRNAME/first-dir/second-dir/file1,v <-- file1
+initial revision: 1\.1
+done"
+ dotest release-21 "$testcvs edit file1"
cd ..
- rm -rf 1
+ dotest release-22 "echo yes | $testcvs release -d second-dir" \
+"You have \[0\] altered files in this repository.
+Are you sure you want to release (and delete) directory \`second-dir': "
+ dotest release-23 "$testcvs -q update -d" "U second-dir/file1"
+ dotest release-24 "$testcvs edit"
+
+ cd ../..
+ rm -rf 1 $CVSROOT_DIRNAME/first-dir
;;
-
+
+
+
+ recase)
+ #
+ # Some tests of behavior which broke at one time or another when run
+ # from case insensitive clients against case sensitive servers.
+ #
+ # These tests are namned according to the following convention:
+ #
+ # ci Client (sandbox filesystem) case Insensitive
+ # cs Client (sandbox filesystem) case Sensitive
+ # si Server (repository filesystem) case Insensitive
+ # ss Server (repository filesystem) case Sensitive
+ #
+
+ mkdir 1; cd 1
+
+ # First, we will expect different results for a few of these tests
+ # based on whether the repository is on a case sensitive filesystem
+ # or not and whether the sandbox is on a case sensitive filesystem or
+ # not, so determine which cases we are dealing with:
+ echo file >file
+ echo FiLe >FiLe
+ if cmp file FiLe >/dev/null; then
+ client_sensitive=false
+ else
+ client_sensitive=:
+ fi
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost 'echo file >file'
+ $CVS_RSH $remotehost 'echo FiLe >FiLe'
+ if $CVS_RSH $remotehost 'cmp file FiLe >/dev/null'; then
+ server_sensitive=false
+ else
+ server_sensitive=:
+ fi
+ else
+ server_sensitive=$client_sensitive
+ fi
+
+ # The first test (recase-1 & recase-2) is for a remove of a file then
+ # a readd in a different case.
+ mkdir $CVSROOT_DIRNAME/first-dir
+ dotest recase-init-1 "$testcvs -Q co first-dir"
+ cd first-dir
+
+ echo this file has no content >file
+ dotest recase-init-2 "$testcvs -Q add file"
+ dotest recase-init-3 "$testcvs -Q ci -madd" \
+"RCS file: $CVSROOT_DIRNAME/first-dir/file,v
+done
+Checking in file;
+$CVSROOT_DIRNAME/first-dir/file,v <-- file
+initial revision: 1\.1
+done"
+ dotest recase-init-4 "$testcvs -Q tag first"
+
+ # Now remove the file.
+ dotest recase-init-5 "$testcvs -Q rm -f file"
+ dotest recase-init-6 "$testcvs -Q ci -mrm" \
+"Removing file;
+$CVSROOT_DIRNAME/first-dir/file,v <-- file
+new revision: delete; previous revision: 1\.1
+done"
+
+ # Now the test - readd in a different case.
+ echo this file needs some content >FiLe
+ if $server_sensitive; then
+ dotest recase-1ss "$testcvs add FiLe" \
+"$PROG add: scheduling file \`FiLe' for addition
+$PROG add: use '$PROG commit' to add this file permanently"
+ dotest recase-2ss "$testcvs -q ci -mrecase" \
+"RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v
+done
+Checking in FiLe;
+$CVSROOT_DIRNAME/first-dir/FiLe,v <-- FiLe
+initial revision: 1\.1
+done"
+ else # server insensitive
+ dotest recase-1si "$testcvs add FiLe" \
+"$PROG add: Re-adding file \`FiLe' (in place of dead revision 1\.2)\.
+$PROG add: use '$PROG commit' to add this file permanently"
+ dotest recase-2si "$testcvs -q ci -mrecase" \
+"Checking in FiLe;
+$CVSROOT_DIRNAME/first-dir/FiLe,v <-- FiLe
+new revision: 1\.3; previous revision: 1\.2
+done"
+ fi
+
+ # Now verify that a checkout will still work
+ cd ../..
+ mkdir 2; cd 2
+ dotest recase-3 "$testcvs -q co first-dir" \
+"U first-dir/FiLe"
+
+ cd first-dir
+ # Prove that we can still get status and log information on
+ # conflicting case files (1 in Attic, one in parent).
+ if $remote; then
+ if $client_sensitive; then
+ file=file
+ fIlE=fIlE
+ else # client insensitive
+ # Because FiLe is present on a case insensitive client, it is the
+ # only one ever found and queried or altered.
+ file=FiLe
+ fIlE=FiLe
+ fi
+ else # ! $remote
+ file=file
+ fIlE=fIlE
+ fi
+ if $server_sensitive; then
+ if $client_sensitive; then
+ # Client finds Entry only for FiLe. Others returned by server.
+ dotest recase-4sscs "$testcvs status file" \
+"===================================================================
+File: no file file Status: Up-to-date
+
+ Working revision: No entry for file
+ Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/Attic/file,v"
+ dotest recase-5sscs "$testcvs log file" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/Attic/file,v
+Working file: file
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ first: 1\.1
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: +0 -0
+rm
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+add
+============================================================================="
+ dotest recase-6sscs "$testcvs status FiLe" \
+"===================================================================
+File: FiLe Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest recase-7sscs "$testcvs log FiLe" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v
+Working file: FiLe
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+recase
+============================================================================="
+ else # server sensitive && client insensitive
+ # Client finds same Entry for file & FiLe.
+ dotest recase-4ssci "$testcvs status file" \
+"===================================================================
+File: FiLe Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest recase-5ssci "$testcvs log file" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v
+Working file: FiLe
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+recase
+============================================================================="
+ dotest recase-6ss "$testcvs status FiLe" \
+"===================================================================
+File: FiLe Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest recase-7ss "$testcvs log FiLe" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v
+Working file: FiLe
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+recase
+============================================================================="
+ fi
+ else # server insensitive
+ # There is only one archive when the server is insensitive, but the
+ # printed file/archive name can vary.
+ dotest recase-4si "$testcvs status file" \
+"===================================================================
+File: $file Status: Up-to-date
+
+ Working revision: 1\.3.*
+ Repository revision: 1\.3 $CVSROOT_DIRNAME/first-dir/$file,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest recase-5si "$testcvs log file" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/$file,v
+Working file: $file
+head: 1\.3
+branch:
+locks: strict
+access list:
+symbolic names:
+ first: 1\.1
+keyword substitution: kv
+total revisions: 3; selected revisions: 3
+description:
+----------------------------
+revision 1\.3
+date: [0-9/]* [0-9:]*; author: $username; state: Exp; lines: +1 -1
+recase
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: +0 -0
+rm
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+add
+============================================================================="
+ dotest recase-6si "$testcvs status FiLe" \
+"===================================================================
+File: FiLe Status: Up-to-date
+
+ Working revision: 1\.3.*
+ Repository revision: 1\.3 $CVSROOT_DIRNAME/first-dir/FiLe,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest recase-7si "$testcvs log FiLe" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v
+Working file: FiLe
+head: 1\.3
+branch:
+locks: strict
+access list:
+symbolic names:
+ first: 1\.1
+keyword substitution: kv
+total revisions: 3; selected revisions: 3
+description:
+----------------------------
+revision 1\.3
+date: [0-9/]* [0-9:]*; author: $username; state: Exp; lines: +1 -1
+recase
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: +0 -0
+rm
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+add
+============================================================================="
+ fi
+
+ # And when the file does not exist on the client, we go with the
+ # client Entries match.
+ if $client_sensitive && $server_sensitive; then
+ dotest recase-8sscs "$testcvs status fIlE" \
+"$PROG status: nothing known about fIlE
+===================================================================
+File: no file fIlE Status: Unknown
+
+ Working revision: No entry for fIlE
+ Repository revision: No revision control file"
+ else # !$client_sensitive || !$server_sensitive
+ dotest recase-8anyi "$testcvs status fIlE" \
+"===================================================================
+File: $fIlE Status: Up-to-date
+
+ Working revision: 1\.[0-9]*.*
+ Repository revision: 1\.[0-9]* $CVSROOT_DIRNAME/first-dir/$fIlE,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ fi
+
+ # and an update
+ if $server_sensitive; then
+ dotest recase-9ss "$testcvs -q up -rfirst" \
+"$PROG update: FiLe is no longer in the repository
+U file"
+
+ if $client_sensitive; then
+ dotest recase-10sscs "$testcvs -q up -A" \
+"U FiLe
+$PROG update: file is no longer in the repository"
+ else # client insensitive
+ # FIXCVS: This should remove the offending file first.
+ dotest_fail recase-10ssci "$testcvs -q up -A" \
+"$PROG update: move away \./FiLe; it is in the way
+C FiLe
+$PROG update: file is no longer in the repository"
+
+ cd ..
+ rm -r first-dir
+ dotest recase-11ssci "$testcvs -q co first-dir" \
+"U first-dir/FiLe"
+ cd first-dir
+ fi
+
+ #
+ # See what happens when cased names clash.
+ #
+
+ # Copy the archive
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "cp $CVSROOT_DIRNAME/first-dir/FiLe,v \
+ $CVSROOT_DIRNAME/first-dir/FILE,v"
+ else
+ cp $CVSROOT_DIRNAME/first-dir/FiLe,v \
+ $CVSROOT_DIRNAME/first-dir/FILE,v
+ fi
+
+ if $client_sensitive; then
+ dotest recase-12sscs "$testcvs -q up" "U FILE"
+ else # client insensitive
+ dotest_fail recase-12ssci "$testcvs -q up" \
+"$PROG update: move away \./FILE; it is in the way
+C FILE"
+ fi
+ else # server insensitive
+ dotest recase-9si "$testcvs -q up -rfirst" "U FiLe"
+ dotest recase-10si "$testcvs -q up -A" "U FiLe"
+ fi
+
+ # Prove that we can still get status and log information on
+ # conflicting case files (1 in Attic, two in parent).
+ if $server_sensitive; then
+ if $client_sensitive; then
+ # Client finds Entry only for FiLe. Others returned by server.
+ dotest recase-13sscs "$testcvs status file" \
+"===================================================================
+File: no file file Status: Up-to-date
+
+ Working revision: No entry for file
+ Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/Attic/file,v"
+ dotest recase-14sscs "$testcvs log file" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/Attic/file,v
+Working file: file
+head: 1\.2
+branch:
+locks: strict
+access list:
+symbolic names:
+ first: 1\.1
+keyword substitution: kv
+total revisions: 2; selected revisions: 2
+description:
+----------------------------
+revision 1\.2
+date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: +0 -0
+rm
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+add
+============================================================================="
+ dotest recase-15sscs "$testcvs status FiLe" \
+"===================================================================
+File: FiLe Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest recase-16sscs "$testcvs log FiLe" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v
+Working file: FiLe
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+recase
+============================================================================="
+ dotest recase-17sscs "$testcvs status FILE" \
+"===================================================================
+File: FILE Status: Up-to-date
+
+ Working revision: 1.1.*
+ Repository revision: 1.1 ${CVSROOT_DIRNAME}/first-dir/FILE,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest recase-18sscs "$testcvs log FILE" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/FILE,v
+Working file: FILE
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+recase
+============================================================================="
+ else # $server_sensitive && !$client_sensitive
+ # Client finds same Entry for file & FiLe.
+ dotest recase-13ssci "$testcvs status file" \
+"===================================================================
+File: FiLe Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest recase-16ssci "$testcvs log FiLe" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v
+Working file: FiLe
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+recase
+============================================================================="
+ dotest recase-17ssci "$testcvs status FILE" \
+"===================================================================
+File: FiLe Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest recase-18ssci "$testcvs log FILE" \
+"
+RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v
+Working file: FiLe
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: $username; state: Exp;
+recase
+============================================================================="
+ fi
+ else # !$server_sensitive
+ # Skip these when the server is case insensitive - nothing
+ # has changed since recase-[4-7]si
+ :
+ fi
+
+ if $client_sensitive && $server_sensitive; then
+ dotest recase-19sscs "$testcvs status fIlE" \
+"$PROG status: nothing known about fIlE
+===================================================================
+File: no file fIlE Status: Unknown
+
+ Working revision: No entry for fIlE
+ Repository revision: No revision control file"
+ else # !$client_sensitive || !$server_sensitive
+ dotest recase-19anyi "$testcvs status fIlE" \
+"===================================================================
+File: $fIlE Status: Up-to-date
+
+ Working revision: 1\.[0-9]*.*
+ Repository revision: 1\.[0-9]* $CVSROOT_DIRNAME/first-dir/$fIlE,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ fi
+
+ # And last but not least, prove that a checkout is still possible.
+ cd ../..
+ mkdir 3; cd 3
+ if $server_sensitive; then
+ if $client_sensitive; then
+ dotest recase-20sscs "$testcvs -q co first-dir" \
+"U first-dir/FILE
+U first-dir/FiLe"
+ else # $server_senstive && !$client_sensitive
+ dotest_fail recase-20ssci "$testcvs -q co first-dir" \
+"U first-dir/FILE
+$PROG checkout: move away first-dir/FiLe; it is in the way
+C first-dir/FiLe"
+ fi
+ else # !$server_sensitive
+ # Skip these since nothing has changed.
+ :
+ fi
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ cd ..
+ rm -r 1 2 3
+ if $server_sensitive && test -n "$remotehost"; then
+ # It is necessary to remove one of the case-conflicted files before
+ # recursively removing the rest under Cygwin on a Samba share or
+ # Samba returns a permission denied error due to its case
+ # confusion.
+ $CVS_RSH $remotehost "rm -f $CVSROOT_DIRNAME/first-dir/FILE,v"
+ fi
+ rm -rf $CVSROOT_DIRNAME/first-dir
+ ;;
+
+
+
multiroot)
-
#
# set up two repositories
#
CVSROOT1_DIRNAME=${TESTDIR}/root1
CVSROOT2_DIRNAME=${TESTDIR}/root2
- CVSROOT1=${CVSROOT1_DIRNAME} ; export CVSROOT1
- CVSROOT2=${CVSROOT2_DIRNAME} ; export CVSROOT2
- if $remote; then
- CVSROOT1=:fork:${CVSROOT1_DIRNAME} ; export CVSROOT1
- CVSROOT2=:fork:${CVSROOT2_DIRNAME} ; export CVSROOT2
- fi
+ CVSROOT1=`newroot $CVSROOT1_DIRNAME`
+ CVSROOT2=`newroot $CVSROOT2_DIRNAME`
testcvs1="${testcvs} -d ${CVSROOT1}"
testcvs2="${testcvs} -d ${CVSROOT2}"
@@ -21544,7 +24749,8 @@ ${PROG} [a-z]*: Updating first-dir"
# create some directories in root1
#
mkdir 1; cd 1
- dotest multiroot-setup-4 "${testcvs1} co -l ." "${PROG} [a-z]*: Updating ."
+ dotest multiroot-setup-4 "${testcvs1} co -l ." \
+"${PROG} checkout: Updating ."
mkdir mod1-1 mod1-2
dotest multiroot-setup-5 "${testcvs1} add mod1-1 mod1-2" \
"Directory ${CVSROOT1_DIRNAME}/mod1-1 added to the repository
@@ -21552,9 +24758,9 @@ Directory ${CVSROOT1_DIRNAME}/mod1-2 added to the repository"
echo file1-1 > mod1-1/file1-1
echo file1-2 > mod1-2/file1-2
dotest multiroot-setup-6 "${testcvs1} add mod1-1/file1-1 mod1-2/file1-2" \
-"${PROG} [a-z]*: scheduling file .mod1-1/file1-1. for addition
-${PROG} [a-z]*: scheduling file .mod1-2/file1-2. for addition
-${PROG} [a-z]*: use '${PROG} commit' to add these files permanently"
+"${PROG} add: scheduling file .mod1-1/file1-1. for addition
+${PROG} add: scheduling file .mod1-2/file1-2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest multiroot-setup-7 "${testcvs1} commit -m is" \
"${PROG} [a-z]*: Examining \.
${PROG} [a-z]*: Examining mod1-1
@@ -21578,7 +24784,8 @@ done"
# create some directories in root2
#
mkdir 1; cd 1
- dotest multiroot-setup-8 "${testcvs2} co -l ." "${PROG} [a-z]*: Updating ."
+ dotest multiroot-setup-8 "${testcvs2} co -l ." \
+"${PROG} checkout: Updating ."
mkdir mod2-1 mod2-2
dotest multiroot-setup-9 "${testcvs2} add mod2-1 mod2-2" \
"Directory ${CVSROOT2_DIRNAME}/mod2-1 added to the repository
@@ -21586,9 +24793,9 @@ Directory ${CVSROOT2_DIRNAME}/mod2-2 added to the repository"
echo file2-1 > mod2-1/file2-1
echo file2-2 > mod2-2/file2-2
dotest multiroot-setup-6 "${testcvs2} add mod2-1/file2-1 mod2-2/file2-2" \
-"${PROG} [a-z]*: scheduling file .mod2-1/file2-1. for addition
-${PROG} [a-z]*: scheduling file .mod2-2/file2-2. for addition
-${PROG} [a-z]*: use '${PROG} commit' to add these files permanently"
+"${PROG} add: scheduling file .mod2-1/file2-1. for addition
+${PROG} add: scheduling file .mod2-2/file2-2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest multiroot-setup-10 "${testcvs2} commit -m anyone" \
"${PROG} [a-z]*: Examining \.
${PROG} [a-z]*: Examining mod2-1
@@ -21628,23 +24835,23 @@ done"
dotest multiroot-workaround "${testcvs1} -q co -l ." ""
dotest multiroot-setup-11 "${testcvs1} co mod1-1 mod1-2" \
-"${PROG} [a-z]*: Updating mod1-1
+"${PROG} checkout: Updating mod1-1
U mod1-1/file1-1
-${PROG} [a-z]*: Updating mod1-2
+${PROG} checkout: Updating mod1-2
U mod1-2/file1-2"
dotest multiroot-setup-12 "${testcvs2} co mod2-1 mod2-2" \
-"${PROG} [a-z]*: Updating mod2-1
+"${PROG} checkout: Updating mod2-1
U mod2-1/file2-1
-${PROG} [a-z]*: Updating mod2-2
+${PROG} checkout: Updating mod2-2
U mod2-2/file2-2"
cd mod1-2
dotest multiroot-setup-13 "${testcvs2} co mod2-2" \
-"${PROG} [a-z]*: Updating mod2-2
+"${PROG} checkout: Updating mod2-2
U mod2-2/file2-2"
cd ..
cd mod2-2
dotest multiroot-setup-14 "${testcvs1} co mod1-2" \
-"${PROG} [a-z]*: Updating mod1-2
+"${PROG} checkout: Updating mod1-2
U mod1-2/file1-2"
cd ..
@@ -21676,33 +24883,33 @@ U mod1-2/file1-2"
# choice of which CVSROOT is specified on the command line.
dotest multiroot-update-1a "${testcvs1} update" \
-"${PROG} [a-z]*: Updating \.
-${PROG} [a-z]*: Updating mod1-1
-${PROG} [a-z]*: Updating mod1-2
-${PROG} [a-z]*: Updating mod1-2/mod2-2
-${PROG} [a-z]*: cannot open directory ${TESTDIR}/root1/mod2-2: No such file or directory
-${PROG} [a-z]*: skipping directory mod1-2/mod2-2
-${PROG} [a-z]*: Updating mod2-1
-${PROG} [a-z]*: cannot open directory ${TESTDIR}/root1/mod2-1: No such file or directory
-${PROG} [a-z]*: skipping directory mod2-1
-${PROG} [a-z]*: Updating mod2-2
-${PROG} [a-z]*: cannot open directory ${TESTDIR}/root1/mod2-2: No such file or directory
-${PROG} [a-z]*: skipping directory mod2-2"
+"${PROG} update: Updating \.
+${PROG} update: Updating mod1-1
+${PROG} update: Updating mod1-2
+${PROG} update: Updating mod1-2/mod2-2
+${PROG} update: cannot open directory ${CVSROOT1_DIRNAME}/mod2-2: No such file or directory
+${PROG} update: skipping directory mod1-2/mod2-2
+${PROG} update: Updating mod2-1
+${PROG} update: cannot open directory ${CVSROOT1_DIRNAME}/mod2-1: No such file or directory
+${PROG} update: skipping directory mod2-1
+${PROG} update: Updating mod2-2
+${PROG} update: cannot open directory ${CVSROOT1_DIRNAME}/mod2-2: No such file or directory
+${PROG} update: skipping directory mod2-2"
# Same deal but with -d ${CVSROOT2}.
dotest multiroot-update-1b "${testcvs2} update" \
-"${PROG} [a-z]*: Updating \.
-${PROG} [a-z]*: Updating mod1-1
-${PROG} [a-z]*: cannot open directory ${TESTDIR}/root2/mod1-1: No such file or directory
-${PROG} [a-z]*: skipping directory mod1-1
-${PROG} [a-z]*: Updating mod1-2
-${PROG} [a-z]*: cannot open directory ${TESTDIR}/root2/mod1-2: No such file or directory
-${PROG} [a-z]*: skipping directory mod1-2
-${PROG} [a-z]*: Updating mod2-1
-${PROG} [a-z]*: Updating mod2-2
-${PROG} [a-z]*: Updating mod2-2/mod1-2
-${PROG} [a-z]*: cannot open directory ${TESTDIR}/root2/mod1-2: No such file or directory
-${PROG} [a-z]*: skipping directory mod2-2/mod1-2"
+"${PROG} update: Updating \.
+${PROG} update: Updating mod1-1
+${PROG} update: cannot open directory ${CVSROOT2_DIRNAME}/mod1-1: No such file or directory
+${PROG} update: skipping directory mod1-1
+${PROG} update: Updating mod1-2
+${PROG} update: cannot open directory ${CVSROOT2_DIRNAME}/mod1-2: No such file or directory
+${PROG} update: skipping directory mod1-2
+${PROG} update: Updating mod2-1
+${PROG} update: Updating mod2-2
+${PROG} update: Updating mod2-2/mod1-2
+${PROG} update: cannot open directory ${CVSROOT2_DIRNAME}/mod1-2: No such file or directory
+${PROG} update: skipping directory mod2-2/mod1-2"
# modify all files and do a diff
@@ -21711,9 +24918,9 @@ ${PROG} [a-z]*: skipping directory mod2-2/mod1-2"
echo goes >> mod2-1/file2-1
echo down >> mod2-2/file2-2
- dotest_status multiroot-diff-1 1 "${testcvs} diff" \
+ dotest_fail multiroot-diff-1 "${testcvs} diff" \
"${PROG} diff: Diffing \.
-${PROG} [a-z]*: Diffing mod1-1
+${PROG} diff: Diffing mod1-1
Index: mod1-1/file1-1
===================================================================
RCS file: ${TESTDIR}/root1/mod1-1/file1-1,v
@@ -21721,7 +24928,7 @@ retrieving revision 1\.1
diff -r1\.1 file1-1
1a2
> bobby
-${PROG} [a-z]*: Diffing mod1-2
+${PROG} diff: Diffing mod1-2
Index: mod1-2/file1-2
===================================================================
RCS file: ${TESTDIR}/root1/mod1-2/file1-2,v
@@ -21729,9 +24936,9 @@ retrieving revision 1\.1
diff -r1\.1 file1-2
1a2
> brown
-${PROG} [a-z]*: Diffing mod2-2/mod1-2
-${PROG} [a-z]*: Diffing mod1-2/mod2-2
-${PROG} [a-z]*: Diffing mod2-1
+${PROG} diff: Diffing mod2-2/mod1-2
+${PROG} diff: Diffing mod1-2/mod2-2
+${PROG} diff: Diffing mod2-1
Index: mod2-1/file2-1
===================================================================
RCS file: ${TESTDIR}/root2/mod2-1/file2-1,v
@@ -21739,7 +24946,7 @@ retrieving revision 1\.1
diff -r1\.1 file2-1
1a2
> goes
-${PROG} [a-z]*: Diffing mod2-2
+${PROG} diff: Diffing mod2-2
Index: mod2-2/file2-2
===================================================================
RCS file: ${TESTDIR}/root2/mod2-2/file2-2,v
@@ -21747,8 +24954,8 @@ retrieving revision 1\.1
diff -r1\.1 file2-2
1a2
> down" \
-"${PROG} server: Diffing \.
-${PROG} [a-z]*: Diffing mod1-1
+"${PROG} diff: Diffing \.
+${PROG} diff: Diffing mod1-1
Index: mod1-1/file1-1
===================================================================
RCS file: ${TESTDIR}/root1/mod1-1/file1-1,v
@@ -21756,7 +24963,7 @@ retrieving revision 1\.1
diff -r1\.1 file1-1
1a2
> bobby
-${PROG} [a-z]*: Diffing mod1-2
+${PROG} diff: Diffing mod1-2
Index: mod1-2/file1-2
===================================================================
RCS file: ${TESTDIR}/root1/mod1-2/file1-2,v
@@ -21764,11 +24971,11 @@ retrieving revision 1\.1
diff -r1\.1 file1-2
1a2
> brown
-${PROG} [a-z]*: Diffing mod2-2
-${PROG} [a-z]*: Diffing mod2-2/mod1-2
-${PROG} [a-z]*: Diffing mod1-2
-${PROG} [a-z]*: Diffing mod1-2/mod2-2
-${PROG} [a-z]*: Diffing mod2-1
+${PROG} diff: Diffing mod2-2
+${PROG} diff: Diffing mod2-2/mod1-2
+${PROG} diff: Diffing mod1-2
+${PROG} diff: Diffing mod1-2/mod2-2
+${PROG} diff: Diffing mod2-1
Index: mod2-1/file2-1
===================================================================
RCS file: ${TESTDIR}/root2/mod2-1/file2-1,v
@@ -21776,7 +24983,7 @@ retrieving revision 1\.1
diff -r1\.1 file2-1
1a2
> goes
-${PROG} [a-z]*: Diffing mod2-2
+${PROG} diff: Diffing mod2-2
Index: mod2-2/file2-2
===================================================================
RCS file: ${TESTDIR}/root2/mod2-2/file2-2,v
@@ -21785,7 +24992,6 @@ diff -r1\.1 file2-2
1a2
> down"
-
dotest multiroot-commit-1 "${testcvs} commit -m actually" \
"${PROG} [a-z]*: Examining \.
${PROG} [a-z]*: Examining mod1-1
@@ -21819,45 +25025,45 @@ ${PROG} [a-z]*: Updating mod2-2/mod1-2
U mod2-2/mod1-2/file1-2
${PROG} [a-z]*: Updating mod1-2/mod2-2
U mod1-2/mod2-2/file2-2
-${PROG} [a-z]*: Updating mod2-1
-${PROG} [a-z]*: Updating mod2-2" \
-"${PROG} server: Updating \.
-${PROG} [a-z]*: Updating mod1-1
-${PROG} [a-z]*: Updating mod1-2
-${PROG} [a-z]*: Updating mod2-2
-${PROG} [a-z]*: Updating mod2-2/mod1-2
+${PROG} update: Updating mod2-1
+${PROG} update: Updating mod2-2" \
+"${PROG} update: Updating \.
+${PROG} update: Updating mod1-1
+${PROG} update: Updating mod1-2
+${PROG} update: Updating mod2-2
+${PROG} update: Updating mod2-2/mod1-2
P mod2-2/mod1-2/file1-2
-${PROG} [a-z]*: Updating mod1-2
-${PROG} [a-z]*: Updating mod1-2/mod2-2
+${PROG} update: Updating mod1-2
+${PROG} update: Updating mod1-2/mod2-2
P mod1-2/mod2-2/file2-2
-${PROG} [a-z]*: Updating mod2-1
-${PROG} [a-z]*: Updating mod2-2"
+${PROG} update: Updating mod2-1
+${PROG} update: Updating mod2-2"
dotest multiroot-tag-1 "${testcvs} tag cattle" \
"${PROG} tag: Tagging \.
-${PROG} [a-z]*: Tagging mod1-1
+${PROG} tag: Tagging mod1-1
T mod1-1/file1-1
-${PROG} [a-z]*: Tagging mod1-2
+${PROG} tag: Tagging mod1-2
T mod1-2/file1-2
-${PROG} [a-z]*: Tagging mod2-2/mod1-2
-${PROG} [a-z]*: Tagging mod1-2/mod2-2
+${PROG} tag: Tagging mod2-2/mod1-2
+${PROG} tag: Tagging mod1-2/mod2-2
T mod1-2/mod2-2/file2-2
-${PROG} [a-z]*: Tagging mod2-1
+${PROG} tag: Tagging mod2-1
T mod2-1/file2-1
-${PROG} [a-z]*: Tagging mod2-2" \
-"${PROG} server: Tagging \.
-${PROG} [a-z]*: Tagging mod1-1
+${PROG} tag: Tagging mod2-2" \
+"${PROG} tag: Tagging \.
+${PROG} tag: Tagging mod1-1
T mod1-1/file1-1
-${PROG} [a-z]*: Tagging mod1-2
+${PROG} tag: Tagging mod1-2
T mod1-2/file1-2
-${PROG} [a-z]*: Tagging mod2-2
-${PROG} [a-z]*: Tagging mod2-2/mod1-2
-${PROG} [a-z]*: Tagging mod1-2
-${PROG} [a-z]*: Tagging mod1-2/mod2-2
+${PROG} tag: Tagging mod2-2
+${PROG} tag: Tagging mod2-2/mod1-2
+${PROG} tag: Tagging mod1-2
+${PROG} tag: Tagging mod1-2/mod2-2
T mod1-2/mod2-2/file2-2
-${PROG} [a-z]*: Tagging mod2-1
+${PROG} tag: Tagging mod2-1
T mod2-1/file2-1
-${PROG} [a-z]*: Tagging mod2-2"
+${PROG} tag: Tagging mod2-2"
echo anotherfile1-1 > mod1-1/anotherfile1-1
echo anotherfile2-1 > mod2-1/anotherfile2-1
@@ -21867,33 +25073,33 @@ ${PROG} [a-z]*: Tagging mod2-2"
if $remote; then
cd mod1-1
dotest multiroot-add-1ar "${testcvs} add anotherfile1-1" \
-"${PROG} [a-z]*: scheduling file .anotherfile1-1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .anotherfile1-1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
cd ../mod2-1
dotest multiroot-add-1br "${testcvs} add anotherfile2-1" \
-"${PROG} [a-z]*: scheduling file .anotherfile2-1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .anotherfile2-1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
cd ../mod2-2/mod1-2
dotest multiroot-add-1cr "${testcvs} add anotherfile1-2" \
-"${PROG} [a-z]*: scheduling file .anotherfile1-2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .anotherfile1-2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
cd ../../mod1-2/mod2-2
dotest multiroot-add-1dr "${testcvs} add anotherfile2-2" \
-"${PROG} [a-z]*: scheduling file .anotherfile2-2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .anotherfile2-2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
cd ../..
else
dotest multiroot-add-1 "${testcvs} add mod1-1/anotherfile1-1 mod2-1/anotherfile2-1 mod2-2/mod1-2/anotherfile1-2 mod1-2/mod2-2/anotherfile2-2" \
-"${PROG} [a-z]*: scheduling file .mod1-1/anotherfile1-1. for addition
-${PROG} [a-z]*: scheduling file .mod2-1/anotherfile2-1. for addition
-${PROG} [a-z]*: scheduling file .mod2-2/mod1-2/anotherfile1-2. for addition
-${PROG} [a-z]*: scheduling file .mod1-2/mod2-2/anotherfile2-2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .mod1-1/anotherfile1-1. for addition
+${PROG} add: scheduling file .mod2-1/anotherfile2-1. for addition
+${PROG} add: scheduling file .mod2-2/mod1-2/anotherfile1-2. for addition
+${PROG} add: scheduling file .mod1-2/mod2-2/anotherfile2-2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
fi
dotest multiroot-status-1 "${testcvs} status -v" \
"${PROG} status: Examining \.
-${PROG} [a-z]*: Examining mod1-1
+${PROG} status: Examining mod1-1
===================================================================
File: anotherfile1-1 Status: Locally Added
@@ -21915,7 +25121,7 @@ File: file1-1 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)
-${PROG} [a-z]*: Examining mod1-2
+${PROG} status: Examining mod1-2
===================================================================
File: file1-2 Status: Up-to-date
@@ -21928,7 +25134,7 @@ File: file1-2 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)
-${PROG} [a-z]*: Examining mod2-2/mod1-2
+${PROG} status: Examining mod2-2/mod1-2
===================================================================
File: anotherfile1-2 Status: Locally Added
@@ -21950,7 +25156,7 @@ File: file1-2 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)
-${PROG} [a-z]*: Examining mod1-2/mod2-2
+${PROG} status: Examining mod1-2/mod2-2
===================================================================
File: anotherfile2-2 Status: Locally Added
@@ -21972,7 +25178,7 @@ File: file2-2 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)
-${PROG} [a-z]*: Examining mod2-1
+${PROG} status: Examining mod2-1
===================================================================
File: anotherfile2-1 Status: Locally Added
@@ -21994,7 +25200,7 @@ File: file2-1 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)
-${PROG} [a-z]*: Examining mod2-2
+${PROG} status: Examining mod2-2
===================================================================
File: file2-2 Status: Up-to-date
@@ -22006,8 +25212,8 @@ File: file2-2 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)" \
-"${PROG} server: Examining \.
-${PROG} [a-z]*: Examining mod1-1
+"${PROG} status: Examining \.
+${PROG} status: Examining mod1-1
===================================================================
File: anotherfile1-1 Status: Locally Added
@@ -22029,7 +25235,7 @@ File: file1-1 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)
-${PROG} [a-z]*: Examining mod1-2
+${PROG} status: Examining mod1-2
===================================================================
File: file1-2 Status: Up-to-date
@@ -22042,8 +25248,8 @@ File: file1-2 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)
-${PROG} [a-z]*: Examining mod2-2
-${PROG} [a-z]*: Examining mod2-2/mod1-2
+${PROG} status: Examining mod2-2
+${PROG} status: Examining mod2-2/mod1-2
===================================================================
File: anotherfile1-2 Status: Locally Added
@@ -22065,8 +25271,8 @@ File: file1-2 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)
-${PROG} [a-z]*: Examining mod1-2
-${PROG} [a-z]*: Examining mod1-2/mod2-2
+${PROG} status: Examining mod1-2
+${PROG} status: Examining mod1-2/mod2-2
===================================================================
File: anotherfile2-2 Status: Locally Added
@@ -22088,7 +25294,7 @@ File: file2-2 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)
-${PROG} [a-z]*: Examining mod2-1
+${PROG} status: Examining mod2-1
===================================================================
File: anotherfile2-1 Status: Locally Added
@@ -22110,7 +25316,7 @@ File: file2-1 Status: Up-to-date
Existing Tags:
cattle (revision: 1\.2)
-${PROG} [a-z]*: Examining mod2-2
+${PROG} status: Examining mod2-2
===================================================================
File: file2-2 Status: Up-to-date
@@ -22166,21 +25372,21 @@ ${PROG} [a-z]*: Updating mod1-2/mod2-2
${PROG} [a-z]*: Updating mod2-1
${PROG} [a-z]*: Updating mod2-2
U mod2-2/anotherfile2-2" \
-"${PROG} server: Updating \.
-${PROG} [a-z]*: Updating mod1-1
-${PROG} [a-z]*: Updating mod1-2
+"${PROG} update: Updating \.
+${PROG} update: Updating mod1-1
+${PROG} update: Updating mod1-2
U mod1-2/anotherfile1-2
-${PROG} [a-z]*: Updating mod2-2
-${PROG} [a-z]*: Updating mod2-2/mod1-2
-${PROG} [a-z]*: Updating mod1-2
-${PROG} [a-z]*: Updating mod1-2/mod2-2
-${PROG} [a-z]*: Updating mod2-1
-${PROG} [a-z]*: Updating mod2-2
+${PROG} update: Updating mod2-2
+${PROG} update: Updating mod2-2/mod1-2
+${PROG} update: Updating mod1-2
+${PROG} update: Updating mod1-2/mod2-2
+${PROG} update: Updating mod2-1
+${PROG} update: Updating mod2-2
U mod2-2/anotherfile2-2"
dotest multiroot-log-1 "${testcvs} log" \
"${PROG} log: Logging \.
-${PROG} [a-z]*: Logging mod1-1
+${PROG} log: Logging mod1-1
RCS file: ${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v
Working file: mod1-1/anotherfile1-1
@@ -22218,7 +25424,7 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
is
=============================================================================
-${PROG} [a-z]*: Logging mod1-2
+${PROG} log: Logging mod1-2
RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v
Working file: mod1-2/anotherfile1-2
@@ -22256,7 +25462,7 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
is
=============================================================================
-${PROG} [a-z]*: Logging mod2-2/mod1-2
+${PROG} log: Logging mod2-2/mod1-2
RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v
Working file: mod2-2/mod1-2/anotherfile1-2
@@ -22294,7 +25500,7 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
is
=============================================================================
-${PROG} [a-z]*: Logging mod1-2/mod2-2
+${PROG} log: Logging mod1-2/mod2-2
RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v
Working file: mod1-2/mod2-2/anotherfile2-2
@@ -22332,7 +25538,7 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
anyone
=============================================================================
-${PROG} [a-z]*: Logging mod2-1
+${PROG} log: Logging mod2-1
RCS file: ${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v
Working file: mod2-1/anotherfile2-1
@@ -22370,7 +25576,7 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
anyone
=============================================================================
-${PROG} [a-z]*: Logging mod2-2
+${PROG} log: Logging mod2-2
RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v
Working file: mod2-2/anotherfile2-2
@@ -22408,8 +25614,8 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
anyone
=============================================================================" \
-"${PROG} server: Logging \.
-${PROG} [a-z]*: Logging mod1-1
+"${PROG} log: Logging \.
+${PROG} log: Logging mod1-1
RCS file: ${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v
Working file: mod1-1/anotherfile1-1
@@ -22447,7 +25653,7 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
is
=============================================================================
-${PROG} [a-z]*: Logging mod1-2
+${PROG} log: Logging mod1-2
RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v
Working file: mod1-2/anotherfile1-2
@@ -22485,8 +25691,8 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
is
=============================================================================
-${PROG} [a-z]*: Logging mod2-2
-${PROG} [a-z]*: Logging mod2-2/mod1-2
+${PROG} log: Logging mod2-2
+${PROG} log: Logging mod2-2/mod1-2
RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v
Working file: mod2-2/mod1-2/anotherfile1-2
@@ -22524,8 +25730,8 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
is
=============================================================================
-${PROG} [a-z]*: Logging mod1-2
-${PROG} [a-z]*: Logging mod1-2/mod2-2
+${PROG} log: Logging mod1-2
+${PROG} log: Logging mod1-2/mod2-2
RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v
Working file: mod1-2/mod2-2/anotherfile2-2
@@ -22563,7 +25769,7 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
anyone
=============================================================================
-${PROG} [a-z]*: Logging mod2-1
+${PROG} log: Logging mod2-1
RCS file: ${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v
Working file: mod2-1/anotherfile2-1
@@ -22601,7 +25807,7 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
anyone
=============================================================================
-${PROG} [a-z]*: Logging mod2-2
+${PROG} log: Logging mod2-2
RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v
Working file: mod2-2/anotherfile2-2
@@ -22663,12 +25869,8 @@ anyone
CVSROOT1_DIRNAME=${TESTDIR}/root1
CVSROOT2_DIRNAME=${TESTDIR}/root2
- CVSROOT1=${CVSROOT1_DIRNAME} ; export CVSROOT1
- CVSROOT2=${CVSROOT2_DIRNAME} ; export CVSROOT2
- if $remote; then
- CVSROOT1=:fork:${CVSROOT1_DIRNAME} ; export CVSROOT1
- CVSROOT2=:fork:${CVSROOT2_DIRNAME} ; export CVSROOT2
- fi
+ CVSROOT1=`newroot $CVSROOT1_DIRNAME`
+ CVSROOT2=`newroot $CVSROOT2_DIRNAME`
dotest multiroot2-1 "${testcvs} -d ${CVSROOT1} init" ""
dotest multiroot2-2 "${testcvs} -d ${CVSROOT2} init" ""
@@ -22686,8 +25888,8 @@ N dir1/file1
N dir1/sdir/sfile
N dir1/sdir/ssdir/ssfile
No conflicts created by this import
-${PROG} [a-z]*: Importing ${TESTDIR}/root1/dir1/sdir
-${PROG} [a-z]*: Importing ${TESTDIR}/root1/dir1/sdir/ssdir"
+${PROG} import: Importing ${TESTDIR}/root1/dir1/sdir
+${PROG} import: Importing ${TESTDIR}/root1/dir1/sdir/ssdir"
cd sdir
dotest_sort multiroot2-4 \
"${testcvs} -d ${CVSROOT2} import -m import-to-root2 sdir vend2 rel2" "
@@ -22695,7 +25897,7 @@ ${PROG} [a-z]*: Importing ${TESTDIR}/root1/dir1/sdir/ssdir"
N sdir/sfile
N sdir/ssdir/ssfile
No conflicts created by this import
-${PROG} [a-z]*: Importing ${TESTDIR}/root2/sdir/ssdir"
+${PROG} import: Importing ${TESTDIR}/root2/sdir/ssdir"
cd ../..
mkdir 1; cd 1
@@ -22719,11 +25921,11 @@ U sdir/ssdir/ssfile"
${PROG} update: Updating dir1
${PROG} update: Updating dir1/sdir
${PROG} update: Updating dir1/sdir/ssdir" \
-"${PROG} server: Updating \.
-${PROG} server: Updating dir1
-${PROG} server: Updating dir1
-${PROG} server: Updating dir1/sdir
-${PROG} server: Updating dir1/sdir/ssdir"
+"${PROG} update: Updating \.
+${PROG} update: Updating dir1
+${PROG} update: Updating dir1
+${PROG} update: Updating dir1/sdir
+${PROG} update: Updating dir1/sdir/ssdir"
# Two reasons we don't run this on the server: (1) the server
# also prints some trace messages, and (2) the server trace
# messages are subject to out-of-order bugs (this one is hard
@@ -22766,7 +25968,7 @@ done"
"T dir1/file1
T dir1/sdir/sfile
T dir1/sdir/ssdir/ssfile"
- dotest_status multiroot2-12 1 \
+ dotest_fail multiroot2-12 \
"${testcvs} -q diff -u -r tag1 -r tag2" \
"Index: dir1/file1
===================================================================
@@ -22809,13 +26011,8 @@ ${PLUS}change him too"
# Not drastically different from multiroot but it covers somewhat
# different stuff.
- if $remote; then
- CVSROOT1=:fork:${TESTDIR}/root1 ; export CVSROOT1
- CVSROOT2=:fork:${TESTDIR}/root2 ; export CVSROOT2
- else
- CVSROOT1=${TESTDIR}/root1 ; export CVSROOT1
- CVSROOT2=${TESTDIR}/root2 ; export CVSROOT2
- fi
+ CVSROOT1=`newroot ${TESTDIR}/root1`
+ CVSROOT2=`newroot ${TESTDIR}/root2`
mkdir 1; cd 1
dotest multiroot3-1 "${testcvs} -d ${CVSROOT1} init" ""
@@ -22849,17 +26046,17 @@ ${PLUS}change him too"
# having a different root from the child, hence the cd.
cd dir1
dotest multiroot3-8 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
cd ..
dotest multiroot3-8a "${testcvs} add dir2/file2" \
-"${PROG} [a-z]*: scheduling file .dir2/file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .dir2/file2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
else
dotest multiroot3-8 "${testcvs} add dir1/file1 dir2/file2" \
-"${PROG} [a-z]*: scheduling file .dir1/file1. for addition
-${PROG} [a-z]*: scheduling file .dir2/file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .dir1/file1. for addition
+${PROG} add: scheduling file .dir2/file2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
fi
dotest multiroot3-9 "${testcvs} -q ci -m add-them" \
@@ -22880,50 +26077,54 @@ done"
# something which doesn't make sense.
dotest_fail multiroot3-10 \
"${testcvs} -q -d ${CVSROOT1} diff dir1/file1 dir2/file2" \
-"${PROG} [a-z]*: failed to create lock directory for .${TESTDIR}/root1/dir2' (${TESTDIR}/root1/dir2/#cvs.lock): No such file or directory
-${PROG} [a-z]*: failed to obtain dir lock in repository .${TESTDIR}/root1/dir2'
-${PROG} \[[a-z]* aborted\]: read lock failed - giving up"
+"${PROG} diff: failed to create lock directory for .${TESTDIR}/root1/dir2' (${TESTDIR}/root1/dir2/#cvs.lock): No such file or directory
+${PROG} diff: failed to obtain dir lock in repository .${TESTDIR}/root1/dir2'
+${PROG} \[diff aborted\]: read lock failed - giving up"
# This one is supposed to work.
dotest multiroot3-11 "${testcvs} -q diff dir1/file1 dir2/file2" ""
# make sure we can't access across repositories
- # FIXCVS: we probably shouldn't even create the local directories
- # in this case, but we do, so deal with it.
mkdir 1a
cd 1a
dotest_fail multiroot3-12 \
-"${testcvs} -d ${CVSROOT1} -q co ../root2/dir2" \
-"${PROG} [a-z]*: in directory \.\./root2/dir2:
-${PROG} [a-z]*: .\.\..-relative repositories are not supported.
-${PROG} \[[a-z]* aborted\]: illegal source repository"
- rm -rf ../root2
+"$testcvs -d $CVSROOT1 -q co ../root2/dir2" \
+"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\." \
+"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\.
+$PROG \[checkout aborted\]: end of file from server (consult above messages if any)"
dotest_fail multiroot3-13 \
-"${testcvs} -d ${CVSROOT2} -q co ../root1/dir1" \
-"${PROG} [a-z]*: in directory \.\./root1/dir1:
-${PROG} [a-z]*: .\.\..-relative repositories are not supported.
-${PROG} \[[a-z]* aborted\]: illegal source repository"
- rm -rf ../root1
+"$testcvs -d $CVSROOT2 -q co ../root1/dir1" \
+"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\.\./root1/dir1'\." \
+"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\.\./root1/dir1'\.
+$PROG \[checkout aborted\]: end of file from server (consult above messages if any)"
dotest_fail multiroot3-14 \
-"${testcvs} -d ${CVSROOT1} -q co ./../root2/dir2" \
-"${PROG} [a-z]*: in directory \./\.\./root2/dir2:
-${PROG} [a-z]*: .\.\..-relative repositories are not supported.
-${PROG} \[[a-z]* aborted\]: illegal source repository"
- rm -rf ../root2
+"$testcvs -d $CVSROOT1 -q co ./../root2/dir2" \
+"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root2/dir2'\." \
+"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root2/dir2'\.
+$PROG \[checkout aborted\]: end of file from server (consult above messages if any)"
dotest_fail multiroot3-15 \
-"${testcvs} -d ${CVSROOT2} -q co ./../root1/dir1" \
-"${PROG} [a-z]*: in directory \./\.\./root1/dir1:
-${PROG} [a-z]*: .\.\..-relative repositories are not supported.
-${PROG} \[[a-z]* aborted\]: illegal source repository"
- rm -rf ../root1
-
- cd ../..
+"$testcvs -d $CVSROOT2 -q co ./../root1/dir1" \
+"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\." \
+"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\.
+$PROG \[checkout aborted\]: end of file from server (consult above messages if any)"
+ dotest_fail multiroot3-16 \
+"$testcvs -d $CVSROOT1 -q co -p ../root2/dir2" \
+"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\." \
+"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\.
+$PROG \[checkout aborted\]: end of file from server (consult above messages if any)"
+ dotest_fail multiroot3-17 \
+"$testcvs -d $CVSROOT1 -q co -p ./../root1/dir1" \
+"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\." \
+"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\.
+$PROG \[checkout aborted\]: end of file from server (consult above messages if any)"
if $keep; then
- echo Keeping ${TESTDIR} and exiting due to --keep
+ echo Keeping $TESTDIR and exiting due to --keep
exit 0
fi
+ cd ../..
+
rm -r 1
rm -rf ${TESTDIR}/root1 ${TESTDIR}/root2
unset CVSROOT1
@@ -22934,13 +26135,9 @@ ${PROG} \[[a-z]* aborted\]: illegal source repository"
# More multiroot tests, in particular we have two roots with
# similarly-named directories and we try to see that CVS can
# keep them separate.
- if $remote; then
- CVSROOT1=:fork:${TESTDIR}/root1 ; export CVSROOT1
- CVSROOT2=:fork:${TESTDIR}/root2 ; export CVSROOT2
- else
- CVSROOT1=${TESTDIR}/root1 ; export CVSROOT1
- CVSROOT2=${TESTDIR}/root2 ; export CVSROOT2
- fi
+
+ CVSROOT1=`newroot ${TESTDIR}/root1`
+ CVSROOT2=`newroot ${TESTDIR}/root2`
mkdir 1; cd 1
dotest multiroot4-1 "${testcvs} -d ${CVSROOT1} init" ""
@@ -22951,8 +26148,8 @@ ${PROG} \[[a-z]* aborted\]: illegal source repository"
cd dircom
touch file1
dotest multiroot4-4 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest multiroot4-5 "${testcvs} -q ci -m add" \
"RCS file: ${TESTDIR}/root1/dircom/file1,v
done
@@ -22970,8 +26167,8 @@ done"
cd dircom
touch file2
dotest multiroot4-9 "${testcvs} add file2" \
-"${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+"${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
dotest multiroot4-10 "${testcvs} -q ci -m add" \
"RCS file: ${TESTDIR}/root2/dircom/file2,v
done
@@ -23019,9 +26216,9 @@ done"
cd first-dir
touch file1 file2
dotest rmroot-setup-3 "${testcvs} add file1 file2" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: scheduling file .file2. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add these files permanently"
dotest rmroot-setup-4 "${testcvs} -q commit -minit" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
@@ -23046,14 +26243,8 @@ done"
# More tests of repositories and specifying them.
# Similar to crerepos but that test is probably getting big
# enough.
-
- if $remote; then
- CVSROOT1=:fork:${TESTDIR}/root1 ; export CVSROOT1
- CVSROOT_MOVED=:fork:${TESTDIR}/root-moved ; export CVSROOT1
- else
- CVSROOT1=${TESTDIR}/root1 ; export CVSROOT1
- CVSROOT_MOVED=${TESTDIR}/root-moved ; export CVSROOT1
- fi
+ CVSROOT1=`newroot ${TESTDIR}/root1`
+ CVSROOT_MOVED=`newroot ${TESTDIR}/root-moved`
dotest reposmv-setup-1 "${testcvs} -d ${CVSROOT1} init" ""
mkdir imp-dir; cd imp-dir
@@ -23091,41 +26282,41 @@ ${PROG} update: skipping directory "
# CVS/Root overrides $CVSROOT
if $remote; then
- CVSROOT_SAVED=${CVSROOT}
+ CVSROOT_save=${CVSROOT}
CVSROOT=:fork:${TESTDIR}/root-moved; export CVSROOT
dotest_fail reposmv-3r "${testcvs} update" \
"Cannot access ${TESTDIR}/root1/CVSROOT
No such file or directory"
- CVSROOT=${CVSROOT_SAVED}; export CVSROOT
+ CVSROOT=${CVSROOT_save}; export CVSROOT
else
- CVSROOT_SAVED=${CVSROOT}
+ CVSROOT_save=${CVSROOT}
CVSROOT=${TESTDIR}/root-moved; export CVSROOT
dotest reposmv-3 "${testcvs} update" \
"${DOTSTAR}
${PROG} update: ignoring CVS/Root because it specifies a non-existent repository ${TESTDIR}/root1
${PROG} update: Updating \.
${DOTSTAR}"
- CVSROOT=${CVSROOT_SAVED}; export CVSROOT
+ CVSROOT=${CVSROOT_save}; export CVSROOT
fi
if $remote; then
- CVSROOT_SAVED=${CVSROOT}
+ CVSROOT_save=${CVSROOT}
CVSROOT=:fork:${TESTDIR}/root-none; export CVSROOT
dotest_fail reposmv-4 "${testcvs} update" \
"Cannot access ${TESTDIR}/root1/CVSROOT
No such file or directory"
- CVSROOT=${CVSROOT_SAVED}; export CVSROOT
+ CVSROOT=${CVSROOT_save}; export CVSROOT
else
# CVS/Root doesn't seem to quite completely override $CVSROOT
# Bug? Not necessarily a big deal if it only affects error
# messages.
- CVSROOT_SAVED=${CVSROOT}
+ CVSROOT_save=${CVSROOT}
CVSROOT=${TESTDIR}/root-none; export CVSROOT
dotest_fail reposmv-4 "${testcvs} update" \
"${PROG} update: in directory \.:
${PROG} update: ignoring CVS/Root because it specifies a non-existent repository ${TESTDIR}/root1
${PROG} \[update aborted\]: ${TESTDIR}/root-none/CVSROOT: No such file or directory"
- CVSROOT=${CVSROOT_SAVED}; export CVSROOT
+ CVSROOT=${CVSROOT_save}; export CVSROOT
fi
# -d overrides CVS/Root
@@ -23134,7 +26325,7 @@ ${PROG} \[update aborted\]: ${TESTDIR}/root-none/CVSROOT: No such file or direct
# local (that is, it would appear that CVS/Root would not
# get used, but would produce an error if it didn't exist).
dotest reposmv-5 "${testcvs} -d ${CVSROOT_MOVED} update" \
-"${PROG} [a-z]*: Updating \."
+"${PROG} update: Updating \."
# TODO: could also test various other things, like what if the
# user removes CVS/Root (which is legit). Or another set of
@@ -23162,9 +26353,10 @@ ${PROG} \[update aborted\]: ${TESTDIR}/root-none/CVSROOT: No such file or direct
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cat >${CVSROOT_DIRNAME}/CVSROOT/passwd <<EOF
testme:q6WV9d2t848B2:$username
+dontroot:q6WV9d2t848B2:root
anonymous::$username
$username:
willfail: :whocares
@@ -23178,6 +26370,28 @@ Ay::'d
END AUTH REQUEST
EOF
+ # Confirm that not sending a newline during auth cannot constitute
+ # a denial-of-service attack. This assumes that PATH_MAX is less
+ # than 65536 bytes. If PATH_MAX is larger than 65535 bytes, this
+ # test could hang indefinitely.
+ ${AWK} 'BEGIN { printf "0123456789abcdef" }' </dev/null >garbageseg
+ echo "BEGIN AUTH REQUEST" >garbageinput
+ i=0
+ while test $i -lt 64; do
+ cat <garbageseg >>garbageseg2
+ i=`expr $i + 1`
+ done
+ i=0
+ while test $i -lt 64; do
+ cat <garbageseg2 >>garbageinput
+ i=`expr $i + 1`
+ done
+ dotest_fail pserver-auth-no-dos \
+"${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${PROG} \\[pserver aborted\\]: Maximum line length exceeded during authentication\." <garbageinput
+ unset i
+ rm garbageseg garbageseg2 garbageinput
+
# Sending the Root and noop before waiting for the
# "I LOVE YOU" is bogus, but hopefully we can get
# away with it.
@@ -23193,6 +26407,16 @@ Root ${CVSROOT_DIRNAME}
noop
EOF
+ dotest_fail pserver-4.2 \
+"${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"error 0: root not allowed" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+dontroot
+Ay::'d
+END AUTH REQUEST
+EOF
+
dotest pserver-5 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
"${DOTSTAR} LOVE YOU
E Protocol error: Root says \"${TESTDIR}/1\" but pserver says \"${CVSROOT_DIRNAME}\"
@@ -23554,7 +26778,7 @@ EOF
# pserver used to try and print from the NULL pointer
# in this error message in this case
dotest_fail pserver-bufinit "${testcvs} pserver" \
-"$PROG \[pserver aborted\]: bad auth protocol start: EOF" </dev/null
+"${PROG} \[pserver aborted\]: bad auth protocol start: EOF" </dev/null
# Clean up.
echo "# comments only" >config
@@ -23563,7 +26787,7 @@ EOF
${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} commit: Rebuilding administrative file database"
cd ../..
rm -r 1
rm ${CVSROOT_DIRNAME}/CVSROOT/passwd ${CVSROOT_DIRNAME}/CVSROOT/writers
@@ -23741,6 +26965,14 @@ ${TESTDIR}/crerepos/dir1
editors
EOF
+ # Test that the global `-l' option is ignored nonfatally.
+ dotest server-16 "${testcvs} server" \
+"E cvs server: WARNING: global \`-l' option ignored\.
+ok" <<EOF
+Global_option -l
+noop
+EOF
+
if $keep; then
echo Keeping ${TESTDIR} and exiting due to --keep
exit 0
@@ -23756,7 +26988,7 @@ EOF
# possible security holes are plugged.
if $remote; then
dotest server2-1 "${testcvs} server" \
-"E protocol error: directory '${CVSROOT_DIRNAME}/\.\./dir1' not within root '${TESTDIR}/cvsroot'
+"E protocol error: directory '${CVSROOT_DIRNAME}/\.\./dir1' not within root '${CVSROOT_DIRNAME}'
error " <<EOF
Root ${CVSROOT_DIRNAME}
Directory .
@@ -23765,7 +26997,7 @@ noop
EOF
dotest server2-2 "${testcvs} server" \
-"E protocol error: directory '${CVSROOT_DIRNAME}dir1' not within root '${TESTDIR}/cvsroot'
+"E protocol error: directory '${CVSROOT_DIRNAME}dir1' not within root '${CVSROOT_DIRNAME}'
error " <<EOF
Root ${CVSROOT_DIRNAME}
Directory .
@@ -23820,7 +27052,13 @@ echo "xyz"
echo "ok"
cat >/dev/null
EOF
- chmod +x ${TESTDIR}/serveme
+ # Cygwin. Pthffffffffft!
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod +x ${TESTDIR}/serveme"
+ else
+ chmod +x ${TESTDIR}/serveme
+ fi
+ save_CVS_SERVER=$CVS_SERVER
CVS_SERVER=${TESTDIR}/serveme; export CVS_SERVER
mkdir 1; cd 1
dotest_fail client-1 "${testcvs} -q co first-dir" \
@@ -23885,6 +27123,7 @@ EOF
# By specifying the time zone in local time, we don't
# know exactly how that will translate to GMT.
dotest client-8 "${testcvs} update -D 99-10-04" "OK, whatever"
+ # String 2 below is Cygwin again - ptoooey.
dotest client-9 "cat ${TESTDIR}/client.tmp" \
"Root ${CVSROOT_DIRNAME}
Valid-responses [-a-zA-Z ]*
@@ -23899,16 +27138,261 @@ Modified file1
u=rw,g=,o=
4
abc
+update" \
+"Root ${CVSROOT_DIRNAME}
+Valid-responses [-a-zA-Z ]*
+valid-requests
+Argument -D
+Argument [34] Oct 1999 [0-9][0-9]:00:00 -0000
+Argument --
+Directory \.
+${CVSROOT_DIRNAME}/first-dir
+Entry /file1/1\.2///
+Modified file1
+u=rw,g=r,o=r
+4
+abc
update"
+ # The following test tests what was a potential client update in
+ # CVS versions 1.11.14 and CVS versions 1.12.6 and earlier. This
+ # exploit would allow a trojan server to create arbitrary files,
+ # anywhere the user had write permissions, even outside of the
+ # user's sandbox.
+ cat >$HOME/.bashrc <<EOF
+#!$TESTSHELL
+# This is where login scripts would usually be
+# stored.
+EOF
+ cat >$TESTDIR/serveme <<EOF
+#!$TESTSHELL
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "Rcs-diff $HOME/"
+echo "$HOME/.bashrc"
+echo "/.bashrc/73.50///"
+echo "u=rw,g=rw,o=rw"
+echo "20"
+echo "a1 1"
+echo "echo 'gotcha!'"
+echo "ok"
+cat >/dev/null
+EOF
+
+ # If I don't run the following sleep between the above cat and
+ # the following calls to dotest, sometimes the serveme file isn't
+ # completely written yet by the time CVS tries to execute it,
+ # causing the shell to intermittantly report syntax errors (usually
+ # early EOF). There's probably a new race condition here, but this
+ # works.
+ #
+ # Incidentally, I can reproduce this behavior with Linux 2.4.20 and
+ # Bash 2.05 or Bash 2.05b.
+ sleep 1
+ dotest_fail client-10 "$testcvs update" \
+"$PROG update: Server attempted to update a file via an invalid pathname:
+$PROG \[update aborted\]: \`$HOME/.bashrc'\."
+
+ # A second try at a client exploit. This one never actually
+ # failed in the past, but I thought it wouldn't hurt to add a test.
+ cat >$TESTDIR/serveme <<EOF
+#!$TESTSHELL
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "Rcs-diff ./"
+echo "$HOME/.bashrc"
+echo "/.bashrc/73.50///"
+echo "u=rw,g=rw,o=rw"
+echo "20"
+echo "a1 1"
+echo "echo 'gotcha!'"
+echo "ok"
+cat >/dev/null
+EOF
+ sleep 1
+ dotest_fail client-11 "$testcvs update" \
+"$PROG \[update aborted\]: patch original file \./\.bashrc does not exist"
+
+ # A third try at a client exploit. This one did used to fail like
+ # client-10.
+ cat >$TESTDIR/serveme <<EOF
+#!$TESTSHELL
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "Rcs-diff ../../home/"
+echo "../../.bashrc"
+echo "/.bashrc/73.50///"
+echo "u=rw,g=rw,o=rw"
+echo "20"
+echo "a1 1"
+echo "echo 'gotcha!'"
+echo "ok"
+cat >/dev/null
+EOF
+ sleep 1
+ dotest_fail client-12 "$testcvs update" \
+"$PROG update: Server attempted to update a file via an invalid pathname:
+$PROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\."
+
+ # Try the same exploit using the Created response.
+ cat >$TESTDIR/serveme <<EOF
+#!$TESTSHELL
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "Created $HOME/"
+echo "$HOME/.bashrc"
+echo "/.bashrc/73.50///"
+echo "u=rw,g=rw,o=rw"
+echo "26"
+echo "#! /bin/sh"
+echo "echo 'gotcha!'"
+echo "ok"
+cat >/dev/null
+EOF
+ sleep 1
+ dotest_fail client-13 "$testcvs update" \
+"$PROG update: Server attempted to update a file via an invalid pathname:
+$PROG \[update aborted\]: \`$HOME/.bashrc'\."
+
+ # Now try using the Update-existing response
+ cat >$TESTDIR/serveme <<EOF
+#!$TESTSHELL
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "Update-existing ../../home/"
+echo "../../home/.bashrc"
+echo "/.bashrc/73.50///"
+echo "u=rw,g=rw,o=rw"
+echo "26"
+echo "#! /bin/sh"
+echo "echo 'gotcha!'"
+echo "ok"
+cat >/dev/null
+EOF
+ sleep 1
+ dotest_fail client-14 "$testcvs update" \
+"$PROG update: Server attempted to update a file via an invalid pathname:
+$PROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\."
+
+ # Try the same exploit using the Merged response.
+ cat >$TESTDIR/serveme <<EOF
+#!$TESTSHELL
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "Merged $HOME/"
+echo "$HOME/.bashrc"
+echo "/.bashrc/73.50///"
+echo "u=rw,g=rw,o=rw"
+echo "26"
+echo "#! /bin/sh"
+echo "echo 'gotcha!'"
+echo "ok"
+cat >/dev/null
+EOF
+ sleep 1
+ dotest_fail client-15 "$testcvs update" \
+"$PROG update: Server attempted to update a file via an invalid pathname:
+$PROG \[update aborted\]: \`$HOME/.bashrc'\."
+
+ # Now try using the Updated response
+ cat >$TESTDIR/serveme <<EOF
+#!$TESTSHELL
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "Updated ../../home/"
+echo "../../home/.bashrc"
+echo "/.bashrc/73.50///"
+echo "u=rw,g=rw,o=rw"
+echo "26"
+echo "#! /bin/sh"
+echo "echo 'gotcha!'"
+echo "ok"
+cat >/dev/null
+EOF
+ sleep 1
+ dotest_fail client-16 "$testcvs update" \
+"$PROG update: Server attempted to update a file via an invalid pathname:
+$PROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\."
+
+ # Try the same exploit using the Copy-file response.
+ # As far as I know, Copy-file was never exploitable either.
+ cat >$TESTDIR/serveme <<EOF
+#!$TESTSHELL
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "ok"
+echo "Created ."
+echo "./innocuous"
+echo "/innocuous/73.50///"
+echo "u=rw,g=rw,o=rw"
+echo "26"
+echo "#! /bin/sh"
+echo "echo 'gotcha!'"
+echo "Copy-file ."
+echo "./innocuous"
+echo "$HOME/innocuous"
+echo "ok"
+cat >/dev/null
+EOF
+ sleep 1
+ dotest_fail client-18 "$testcvs update" \
+"$PROG \[update aborted\]: protocol error: Copy-file tried to specify directory"
+
+ # And verify that none of the exploits was successful.
+ dotest client-19 "cat $HOME/.bashrc" \
+"#!$TESTSHELL
+# This is where login scripts would usually be
+# stored\."
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
cd ../..
rm -r 1
rmdir ${TESTDIR}/bogus
- rm ${TESTDIR}/serveme
- CVS_SERVER=${testcvs}; export CVS_SERVER
+ rm $TESTDIR/serveme $HOME/.bashrc
+ CVS_SERVER=${save_CVS_SERVER}; export CVS_SERVER
fi # skip the whole thing for local
;;
+ dottedroot)
+ # Check that a CVSROOT with a "." in the name will work.
+ CVSROOT_save=${CVSROOT}
+ CVSROOT_DIRNAME_save=${CVSROOT_DIRNAME}
+ CVSROOT_DIRNAME=${TESTDIR}/cvs.root
+ CVSROOT=`newroot ${CVSROOT_DIRNAME}`
+
+ dotest dottedroot-init-1 "${testcvs} init" ""
+ mkdir dir1
+ mkdir dir1/dir2
+ echo version1 >dir1/dir2/file1
+ cd dir1
+ dotest dottedroot-1 "${testcvs} import -m '' module1 AUTHOR INITIAL" \
+"${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/module1/dir2
+N module1/dir2/file1
+
+No conflicts created by this import"
+ cd ..
+
+ # This is the test that used to cause an assertion failure
+ # in recurse.c:do_recursion().
+ dotest dottedroot-2 "${testcvs} co -rINITIAL module1" \
+"${PROG} [a-z]*: Updating module1
+${PROG} [a-z]*: Updating module1/dir2
+U module1/dir2/file1"
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ rm -rf ${CVSROOT_DIRNAME}
+ rm -r dir1 module1
+ CVSROOT_DIRNAME=${CVSROOT_DIRNAME_save}
+ CVSROOT=${CVSROOT_save}
+ ;;
+
fork)
# Test that the server defaults to the correct executable in :fork:
# mode. See the note in the TODO at the end of this file about this.
@@ -23920,6 +27404,7 @@ update"
# working, but that test might be better here.
if $remote; then
mkdir fork; cd fork
+ save_CVS_SERVER=$CVS_SERVER
unset CVS_SERVER
# So looking through $PATH for cvs won't work...
echo "echo junk" >cvs
@@ -23928,11 +27413,14 @@ update"
dotest fork-1 "$testcvs -d:fork:$CVSROOT_DIRNAME version" \
'Client: \(.*\)
Server: \1'
- CVS_SERVER=${testcvs}; export CVS_SERVER
+ CVS_SERVER=${save_CVS_SERVER}; export CVS_SERVER
+ unset save_CVS_SERVER
PATH=$save_PATH; unset save_PATH
cd ..
- if $keep; then :; else
- rm -rf fork
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
fi
fi
;;
@@ -23956,8 +27444,8 @@ Server: \1'
dotest commit-add-missing-4 "$testcvs -Q add $file" ''
rm -f $file
dotest_fail commit-add-missing-5 "$testcvs -Q ci -m. $file" \
-"${PROG} [a-z]*: Up-to-date check failed for .$file'
-${PROG} \[[a-z]* aborted\]: correct above errors first!"
+"${PROG} commit: Up-to-date check failed for .$file'
+${PROG} \[commit aborted\]: correct above errors first!"
cd ../..
rm -rf 1
@@ -23978,11 +27466,11 @@ ${PROG} \[[a-z]* aborted\]: correct above errors first!"
echo nosuchhost:/cvs > CVS/Root
dotest commit-d-3 "$testcvs -Q -d $CVSROOT commit -m." \
"Checking in file1;
-${TESTDIR}/cvsroot/c-d-c/file1,v <-- file1
+${CVSROOT_DIRNAME}/c-d-c/file1,v <-- file1
new revision: 1.2; previous revision: 1.1
done
Checking in subdir/file2;
-${TESTDIR}/cvsroot/c-d-c/subdir/file2,v <-- file2
+${CVSROOT_DIRNAME}/c-d-c/subdir/file2,v <-- file2
new revision: 1.2; previous revision: 1.1
done"
cd ../..
@@ -23993,15 +27481,27 @@ done"
echo $what is not the name of a test -- ignored
;;
esac
-done
-# Sanity check sanity.sh. :)
-#
-# Test our exit directory so that tests that exit in an incorrect directory are
-# noticed during single test runs.
-if test "x$TESTDIR" != "x`pwd`"; then
- fail "cleanup: PWD != TESTDIR (\``pwd`' != \`$TESTDIR')"
-fi
+ # Sanity check sanity.sh. :)
+ #
+ # Test our exit directory so that tests that exit in an incorrect directory
+ # are noticed during single test runs.
+ 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.
+ fail "Found cvs-serv* directories in $TMPDIR."
+ 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
+
+done # The big loop
echo "OK, all tests completed."
diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c
index afd88b8..8d51fa0 100644
--- a/contrib/cvs/src/server.c
+++ b/contrib/cvs/src/server.c
@@ -207,7 +207,7 @@ fd_buffer_input (closure, data, need, size, got)
else
{
/* This case is not efficient. Fortunately, I don't think it
- ever actually happens. */
+ ever actually happens. */
nbytes = read (fd->fd, data, need == 0 ? 1 : need);
}
@@ -222,8 +222,8 @@ fd_buffer_input (closure, data, need, size, got)
if (nbytes == 0)
{
/* End of file. This assumes that we are using POSIX or BSD
- style nonblocking I/O. On System V we will get a zero
- return if there is no data, even when not at EOF. */
+ style nonblocking I/O. On System V we will get a zero
+ return if there is no data, even when not at EOF. */
return -1;
}
@@ -263,14 +263,14 @@ fd_buffer_output (closure, data, have, wrote)
&& (nbytes == 0 || blocking_error (errno)))
{
/* A nonblocking write failed to write any data. Just
- return. */
+ return. */
return 0;
}
/* Some sort of error occurred. */
if (nbytes == 0)
- return EIO;
+ return EIO;
return errno;
}
@@ -314,7 +314,7 @@ fd_buffer_block (closure, block)
flags |= O_NONBLOCK;
if (fcntl (fd->fd, F_SETFL, flags) < 0)
- return errno;
+ return errno;
fd->blocking = block;
@@ -328,6 +328,7 @@ fd_buffer_shutdown (buf)
struct buffer *buf;
{
free (buf->closure);
+ buf->closure = NULL;
return 0;
}
@@ -849,12 +850,8 @@ outside_root (repos)
size_t repos_len = strlen (repos);
size_t root_len = strlen (current_parsed_root->directory);
- /* I think isabsolute (repos) should always be true, and that
- any RELATIVE_REPOS stuff should only be in CVS/Repository
- files, not the protocol (for compatibility), but I'm putting
- in the isabsolute check just in case.
-
- This is a good security precaution regardless. -DRP
+ /* isabsolute (repos) should always be true, but
+ this is a good security precaution regardless. -DRP
*/
if (!isabsolute (repos))
{
@@ -1080,7 +1077,7 @@ dirswitch (dir, repos)
&& current_parsed_root->directory != NULL
&& strcmp (current_parsed_root->directory, repos) == 0)
{
- if (fprintf (f, "/.") < 0)
+ if (fprintf (f, "/.") < 0)
{
int save_errno = errno;
if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
@@ -1157,7 +1154,7 @@ serve_directory (arg)
}
else if (status == -2)
{
- pending_error = ENOMEM;
+ pending_error = ENOMEM;
}
else
{
@@ -1296,7 +1293,7 @@ receive_partial_file (size, file)
nwrote = write (file, data, nread);
if (nwrote < 0)
{
- int save_errno = errno;
+ int save_errno = errno;
if (alloc_pending (40))
strcpy (pending_error_text, "E unable to write");
pending_error = save_errno;
@@ -1470,7 +1467,7 @@ serve_modified (arg)
status = buf_read_line (buf_from_net, &mode_text, (int *) NULL);
if (status != 0)
{
- if (status == -2)
+ if (status == -2)
pending_error = ENOMEM;
else
{
@@ -1530,7 +1527,7 @@ serve_modified (arg)
if (error_pending ())
{
- /* Now that we know the size, read and discard the file data. */
+ /* Now that we know the size, read and discard the file data. */
while (size > 0)
{
int status, nread;
@@ -1852,10 +1849,10 @@ server_write_entries ()
if (!error_pending ())
{
/* We open in append mode because we don't want to clobber an
- existing Entries file. If we are checking out a module
- which explicitly lists more than one file in a particular
- directory, then we will wind up calling
- server_write_entries for each such file. */
+ existing Entries file. If we are checking out a module
+ which explicitly lists more than one file in a particular
+ directory, then we will wind up calling
+ server_write_entries for each such file. */
f = CVS_FOPEN (CVSADM_ENT, "a");
if (f == NULL)
{
@@ -2069,9 +2066,9 @@ server_notify ()
{
char *dir = notify_list->dir + strlen (server_temp_dir) + 1;
if (dir[0] == '\0')
- buf_append_char (buf_to_net, '.');
+ buf_append_char (buf_to_net, '.');
else
- buf_output0 (buf_to_net, dir);
+ buf_output0 (buf_to_net, dir);
buf_append_char (buf_to_net, '/');
buf_append_char (buf_to_net, '\n');
}
@@ -2172,8 +2169,12 @@ serve_global_option (arg)
}
switch (arg[1])
{
+ case 'l':
+ error(0, 0, "WARNING: global `-l' option ignored.");
+ break;
case 'n':
noexec = 1;
+ logoff = 1;
break;
case 'q':
quiet = 1;
@@ -2184,9 +2185,6 @@ serve_global_option (arg)
case 'Q':
really_quiet = 1;
break;
- case 'l':
- logoff = 1;
- break;
case 't':
trace = 1;
break;
@@ -2233,10 +2231,10 @@ serve_gssapi_encrypt (arg)
if (cvs_gssapi_wrapping)
{
/* We're already using a gssapi_wrap buffer for stream
- authentication. Flush everything we've output so far, and
- turn on encryption for future data. On the input side, we
- should only have unwrapped as far as the Gssapi-encrypt
- command, so future unwrapping will become encrypted. */
+ authentication. Flush everything we've output so far, and
+ turn on encryption for future data. On the input side, we
+ should only have unwrapped as far as the Gssapi-encrypt
+ command, so future unwrapping will become encrypted. */
buf_flush (buf_to_net, 1);
cvs_gssapi_encrypt = 1;
return;
@@ -2269,8 +2267,8 @@ serve_gssapi_authenticate (arg)
if (cvs_gssapi_wrapping)
{
/* We're already using a gssapi_wrap buffer for encryption.
- That includes authentication, so we don't have to do
- anything further. */
+ That includes authentication, so we don't have to do
+ anything further. */
return;
}
@@ -2285,7 +2283,9 @@ serve_gssapi_authenticate (arg)
}
#endif /* HAVE_GSSAPI */
-
+
+
+
#ifdef SERVER_FLOWCONTROL
/* The maximum we'll queue to the remote client before blocking. */
# ifndef SERVER_HI_WATER
@@ -2295,30 +2295,10 @@ serve_gssapi_authenticate (arg)
# ifndef SERVER_LO_WATER
# define SERVER_LO_WATER (1 * 1024 * 1024)
# endif /* SERVER_LO_WATER */
+#endif /* SERVER_FLOWCONTROL */
-static int set_nonblock_fd PROTO((int));
-
-/*
- * Set buffer BUF to non-blocking I/O. Returns 0 for success or errno
- * code.
- */
-
-static int
-set_nonblock_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;
-}
-#endif /* SERVER_FLOWCONTROL */
-
static void serve_questionable PROTO((char *));
static void
@@ -2360,15 +2340,8 @@ serve_questionable (arg)
}
}
-static void serve_case PROTO ((char *));
-static void
-serve_case (arg)
- char *arg;
-{
- ign_case = 1;
-}
-
+
static struct buffer *protocol;
/* This is the output which we are saving up to send to the server, in the
@@ -2438,48 +2411,48 @@ check_command_legal_p (cmd_name)
*/
#ifdef AUTH_SERVER_SUPPORT
if (CVS_Username == NULL)
- return 1;
+ return 1;
if (lookup_command_attribute (cmd_name) & CVS_CMD_MODIFIES_REPOSITORY)
{
- /* This command has the potential to modify the repository, so
- * we check if the user have permission to do that.
- *
- * (Only relevant for remote users -- local users can do
- * whatever normal Unix file permissions allow them to do.)
- *
- * The decision method:
- *
- * If $CVSROOT/CVSADMROOT_READERS exists and user is listed
- * in it, then read-only access for user.
- *
- * Or if $CVSROOT/CVSADMROOT_WRITERS exists and user NOT
- * listed in it, then also read-only access for user.
- *
- * Else read-write access for user.
- */
-
- char *linebuf = NULL;
- int num_red = 0;
- size_t linebuf_len = 0;
- char *fname;
- size_t flen;
- FILE *fp;
- int found_it = 0;
-
- /* else */
- flen = strlen (current_parsed_root->directory)
- + strlen (CVSROOTADM)
- + strlen (CVSROOTADM_READERS)
- + 3;
-
- fname = xmalloc (flen);
- (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
+ /* This command has the potential to modify the repository, so
+ * we check if the user have permission to do that.
+ *
+ * (Only relevant for remote users -- local users can do
+ * whatever normal Unix file permissions allow them to do.)
+ *
+ * The decision method:
+ *
+ * If $CVSROOT/CVSADMROOT_READERS exists and user is listed
+ * in it, then read-only access for user.
+ *
+ * Or if $CVSROOT/CVSADMROOT_WRITERS exists and user NOT
+ * listed in it, then also read-only access for user.
+ *
+ * Else read-write access for user.
+ */
+
+ char *linebuf = NULL;
+ int num_red = 0;
+ size_t linebuf_len = 0;
+ char *fname;
+ size_t flen;
+ FILE *fp;
+ int found_it = 0;
+
+ /* else */
+ flen = strlen (current_parsed_root->directory)
+ + strlen (CVSROOTADM)
+ + strlen (CVSROOTADM_READERS)
+ + 3;
+
+ fname = xmalloc (flen);
+ (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
CVSROOTADM, CVSROOTADM_READERS);
- fp = fopen (fname, "r");
+ fp = fopen (fname, "r");
- if (fp == NULL)
+ if (fp == NULL)
{
if (!existence_error (errno))
{
@@ -2490,51 +2463,51 @@ check_command_legal_p (cmd_name)
return 0;
}
}
- else /* successfully opened readers file */
- {
- while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
- {
- /* Hmmm, is it worth importing my own readline
- library into CVS? It takes care of chopping
- leading and trailing whitespace, "#" comments, and
- newlines automatically when so requested. Would
- save some code here... -kff */
-
- /* Chop newline by hand, for strcmp()'s sake. */
- if (linebuf[num_red - 1] == '\n')
- linebuf[num_red - 1] = '\0';
-
- if (strcmp (linebuf, CVS_Username) == 0)
- goto handle_illegal;
- }
+ else /* successfully opened readers file */
+ {
+ while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
+ {
+ /* Hmmm, is it worth importing my own readline
+ library into CVS? It takes care of chopping
+ leading and trailing whitespace, "#" comments, and
+ newlines automatically when so requested. Would
+ save some code here... -kff */
+
+ /* Chop newline by hand, for strcmp()'s sake. */
+ if (linebuf[num_red - 1] == '\n')
+ linebuf[num_red - 1] = '\0';
+
+ if (strcmp (linebuf, CVS_Username) == 0)
+ goto handle_illegal;
+ }
if (num_red < 0 && !feof (fp))
error (0, errno, "cannot read %s", fname);
- /* If not listed specifically as a reader, then this user
- has write access by default unless writers are also
- specified in a file . */
+ /* If not listed specifically as a reader, then this user
+ has write access by default unless writers are also
+ specified in a file . */
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", fname);
- }
+ }
free (fname);
/* Now check the writers file. */
- flen = strlen (current_parsed_root->directory)
- + strlen (CVSROOTADM)
- + strlen (CVSROOTADM_WRITERS)
- + 3;
+ flen = strlen (current_parsed_root->directory)
+ + strlen (CVSROOTADM)
+ + strlen (CVSROOTADM_WRITERS)
+ + 3;
- fname = xmalloc (flen);
- (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
+ fname = xmalloc (flen);
+ (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
CVSROOTADM, CVSROOTADM_WRITERS);
- fp = fopen (fname, "r");
+ fp = fopen (fname, "r");
- if (fp == NULL)
- {
+ if (fp == NULL)
+ {
if (linebuf)
- free (linebuf);
+ free (linebuf);
if (existence_error (errno))
{
/* Writers file does not exist, so everyone is a writer,
@@ -2550,43 +2523,43 @@ check_command_legal_p (cmd_name)
free (fname);
return 0;
}
- }
-
- found_it = 0;
- while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
- {
- /* Chop newline by hand, for strcmp()'s sake. */
- if (linebuf[num_red - 1] == '\n')
- linebuf[num_red - 1] = '\0';
-
- if (strcmp (linebuf, CVS_Username) == 0)
- {
- found_it = 1;
- break;
- }
- }
+ }
+
+ found_it = 0;
+ while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
+ {
+ /* Chop newline by hand, for strcmp()'s sake. */
+ if (linebuf[num_red - 1] == '\n')
+ linebuf[num_red - 1] = '\0';
+
+ if (strcmp (linebuf, CVS_Username) == 0)
+ {
+ found_it = 1;
+ break;
+ }
+ }
if (num_red < 0 && !feof (fp))
error (0, errno, "cannot read %s", fname);
- if (found_it)
- {
- if (fclose (fp) < 0)
+ if (found_it)
+ {
+ if (fclose (fp) < 0)
error (0, errno, "cannot close %s", fname);
- if (linebuf)
- free (linebuf);
+ if (linebuf)
+ free (linebuf);
free (fname);
- return 1;
- }
- else /* writers file exists, but this user not listed in it */
- {
- handle_illegal:
- if (fclose (fp) < 0)
+ return 1;
+ }
+ else /* writers file exists, but this user not listed in it */
+ {
+ handle_illegal:
+ if (fclose (fp) < 0)
error (0, errno, "cannot close %s", fname);
- if (linebuf)
- free (linebuf);
+ if (linebuf)
+ free (linebuf);
free (fname);
return 0;
- }
+ }
}
#endif /* AUTH_SERVER_SUPPORT */
@@ -2595,16 +2568,40 @@ check_command_legal_p (cmd_name)
}
-
+
/* Execute COMMAND in a subprocess with the approriate funky things done. */
static struct fd_set_wrapper { fd_set fds; } command_fds_to_drain;
+#ifdef SUNOS_KLUDGE
static int max_command_fd;
+#endif
#ifdef SERVER_FLOWCONTROL
static int flowcontrol_pipe[2];
#endif /* SERVER_FLOWCONTROL */
+
+
+/*
+ * Set buffer FD to non-blocking I/O. Returns 0 for success or errno
+ * code.
+ */
+int
+set_nonblock_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;
@@ -2643,7 +2640,7 @@ do_cvs_command (cmd_name, command)
if (print_pending_error ())
goto free_args_and_return;
- /* Global `command_name' is probably "server" right now -- only
+ /* Global `cvs_cmd_name' is probably "server" right now -- only
serve_export() sets it to anything else. So we will use local
parameter `cmd_name' to determine if this command is legal for
this user. */
@@ -2657,6 +2654,7 @@ do_cvs_command (cmd_name, command)
error \n");
goto free_args_and_return;
}
+ cvs_cmd_name = cmd_name;
(void) server_notify ();
@@ -2745,14 +2743,22 @@ error \n");
protocol_memory_error);
/* At this point we should no longer be using buf_to_net and
- buf_from_net. Instead, everything should go through
- protocol. */
- buf_to_net = NULL;
- buf_from_net = NULL;
+ buf_from_net. Instead, everything should go through
+ protocol. */
+ if (buf_to_net != NULL)
+ {
+ buf_free (buf_to_net);
+ buf_to_net = NULL;
+ }
+ if (buf_from_net != NULL)
+ {
+ buf_free (buf_from_net);
+ buf_from_net = NULL;
+ }
/* These were originally set up to use outbuf_memory_error.
- Since we're now in the child, we should use the simpler
- protocol_memory_error function. */
+ Since we're now in the child, we should use the simpler
+ protocol_memory_error function. */
saved_output->memory_error = protocol_memory_error;
saved_outerr->memory_error = protocol_memory_error;
@@ -2799,11 +2805,34 @@ error \n");
/* For now we just discard partial lines on stderr. I suspect
that CVS can't write such lines unless there is a bug. */
- /*
- * When we exit, that will close the pipes, giving an EOF to
- * the parent.
- */
buf_free (protocol);
+
+ /* Close the pipes explicitly in order to send an EOF to the parent,
+ * then wait for the parent to close the flow control pipe. This
+ * avoids a race condition where a child which dumped more than the
+ * high water mark into the pipes could complete its job and exit,
+ * leaving the parent process to attempt to write a stop byte to the
+ * closed flow control pipe, which earned the parent a SIGPIPE, which
+ * it normally only expects on the network pipe and that causes it to
+ * exit with an error message, rather than the SIGCHILD that it knows
+ * how to handle correctly.
+ */
+ /* Let exit() close STDIN - it's from /dev/null anyhow. */
+ fclose (stderr);
+ fclose (stdout);
+ close (protocol_pipe[1]);
+#ifdef SERVER_FLOWCONTROL
+ {
+ char junk;
+ ssize_t status;
+ while ((status = read (flowcontrol_pipe[0], &junk, 1)) > 0
+ || (status == -1 && errno == EAGAIN));
+ }
+ /* FIXME: No point in printing an error message with error(),
+ * as STDERR is already closed, but perhaps this could be syslogged?
+ */
+#endif
+
exit (exitstatus);
}
@@ -2830,7 +2859,9 @@ error \n");
FD_SET (protocol_pipe[0], &command_fds_to_drain.fds);
if (STDOUT_FILENO > num_to_check)
num_to_check = STDOUT_FILENO;
+#ifdef SUNOS_KLUDGE
max_command_fd = num_to_check;
+#endif
/*
* File descriptors are numbered from 0, so num_to_check needs to
* be one larger than the largest descriptor.
@@ -2974,8 +3005,8 @@ error \n");
child process. */
do {
/* This used to select on exceptions too, but as far
- as I know there was never any reason to do that and
- SCO doesn't let you select on exceptions on pipes. */
+ as I know there was never any reason to do that and
+ SCO doesn't let you select on exceptions on pipes. */
numfds = select (num_to_check, &readfds, &writefds,
(fd_set *)0, timeout_ptr);
if (numfds < 0
@@ -3075,9 +3106,9 @@ error \n");
if (stdout_pipe[0] >= 0
&& (FD_ISSET (stdout_pipe[0], &readfds)))
{
- int status;
+ int status;
- status = buf_input_data (stdoutbuf, (int *) NULL);
+ status = buf_input_data (stdoutbuf, (int *) NULL);
buf_copy_lines (buf_to_net, stdoutbuf, 'M');
@@ -3100,9 +3131,9 @@ error \n");
if (stderr_pipe[0] >= 0
&& (FD_ISSET (stderr_pipe[0], &readfds)))
{
- int status;
+ int status;
- status = buf_input_data (stderrbuf, (int *) NULL);
+ status = buf_input_data (stderrbuf, (int *) NULL);
buf_copy_lines (buf_to_net, stderrbuf, 'E');
@@ -3167,8 +3198,8 @@ error \n");
errs += WEXITSTATUS (status);
else
{
- int sig = WTERMSIG (status);
- char buf[50];
+ int sig = WTERMSIG (status);
+ char buf[50];
/*
* This is really evil, because signals might be numbered
* differently on the two systems. We should be using
@@ -3180,8 +3211,8 @@ error \n");
sprintf (buf, "%d\n", sig);
buf_output0 (buf_to_net, buf);
- /* Test for a core dump. Is this portable? */
- if (status & 0x80)
+ /* Test for a core dump. */
+ if (WCOREDUMP (status))
{
buf_output0 (buf_to_net, "E Core dumped; preserving ");
buf_output0 (buf_to_net, orig_server_temp_dir);
@@ -3320,28 +3351,30 @@ server_pause_check()
}
/* This assumes that we are using BSD or POSIX nonblocking
- I/O. System V nonblocking I/O returns zero if there is
- nothing to read. */
+ I/O. System V nonblocking I/O returns zero if there is
+ nothing to read. */
if (got == 0)
- error (1, 0, "flow control EOF");
+ error (1, 0, "flow control EOF");
if (got < 0 && ! blocking_error (errno))
{
- error (1, errno, "flow control read failed");
+ error (1, errno, "flow control read failed");
}
}
}
}
#endif /* SERVER_FLOWCONTROL */
-
+
/* This variable commented in server.h. */
char *server_dir = NULL;
-static void output_dir PROTO((char *, char *));
+
+
+static void output_dir PROTO((const char *, const char *));
static void
output_dir (update_dir, repository)
- char *update_dir;
- char *repository;
+ const char *update_dir;
+ const char *repository;
{
if (server_dir != NULL)
{
@@ -3356,7 +3389,9 @@ output_dir (update_dir, repository)
buf_output0 (protocol, repository);
buf_output0 (protocol, "/");
}
-
+
+
+
/*
* Entries line that we are squirreling away to send to the client when
* we are ready.
@@ -3375,15 +3410,17 @@ static char *scratched_file;
*/
static int kill_scratched_file;
+
+
void
server_register (name, version, timestamp, options, tag, date, conflict)
- char *name;
- char *version;
- char *timestamp;
- char *options;
- char *tag;
- char *date;
- char *conflict;
+ const char *name;
+ const char *version;
+ const char *timestamp;
+ const char *options;
+ const char *tag;
+ const char *date;
+ const char *conflict;
{
int len;
@@ -3449,9 +3486,11 @@ server_register (name, version, timestamp, options, tag, date, conflict)
}
}
+
+
void
server_scratch (fname)
- char *fname;
+ const char *fname;
{
/*
* I have reports of Scratch_Entry and Register both happening, in
@@ -3549,9 +3588,9 @@ checked_in_response (file, update_dir, repository)
void
server_checked_in (file, update_dir, repository)
- char *file;
- char *update_dir;
- char *repository;
+ const char *file;
+ const char *update_dir;
+ const char *repository;
{
if (noexec)
return;
@@ -3577,9 +3616,9 @@ server_checked_in (file, update_dir, repository)
void
server_update_entries (file, update_dir, repository, updated)
- char *file;
- char *update_dir;
- char *repository;
+ const char *file;
+ const char *update_dir;
+ const char *repository;
enum server_updated_arg4 updated;
{
if (noexec)
@@ -3625,8 +3664,6 @@ static void
serve_rlog (arg)
char *arg;
{
- /* Tell cvslog() to behave like rlog not log. */
- command_name = "rlog";
do_cvs_command ("rlog", cvslog);
}
@@ -3669,8 +3706,6 @@ static void
serve_rtag (arg)
char *arg;
{
- /* Tell cvstag() to behave like rtag not tag. */
- command_name = "rtag";
do_cvs_command ("rtag", cvstag);
}
@@ -3836,8 +3871,6 @@ static void
serve_rannotate (arg)
char *arg;
{
- /* Tell annotate() to behave like rannotate not annotate. */
- command_name = "rannotate";
do_cvs_command ("rannotate", annotate);
}
@@ -3888,14 +3921,14 @@ serve_co (arg)
free (tempdir);
}
- /* Compensate for server_export()'s setting of command_name.
+ /* Compensate for server_export()'s setting of cvs_cmd_name.
*
* [It probably doesn't matter if do_cvs_command() gets "export"
* or "checkout", but we ought to be accurate where possible.]
*/
- do_cvs_command ((strcmp (command_name, "export") == 0) ?
- "export" : "checkout",
- checkout);
+ do_cvs_command ((strcmp (cvs_cmd_name, "export") == 0) ?
+ "export" : "checkout",
+ checkout);
}
static void
@@ -3903,16 +3936,18 @@ serve_export (arg)
char *arg;
{
/* Tell checkout() to behave like export not checkout. */
- command_name = "export";
+ cvs_cmd_name = "export";
serve_co (arg);
}
-
+
+
+
void
server_copy_file (file, update_dir, repository, newfile)
- char *file;
- char *update_dir;
- char *repository;
- char *newfile;
+ const char *file;
+ const char *update_dir;
+ const char *repository;
+ const char *newfile;
{
/* At least for now, our practice is to have the server enforce
noexec for the repository and the client enforce it for the
@@ -4052,10 +4087,10 @@ CVS server internal error: no mode in server_updated");
if (checksum_supported)
{
- int i;
+ int i;
char buf[3];
- buf_output0 (protocol, "Checksum ");
+ buf_output0 (protocol, "Checksum ");
for (i = 0; i < 16; i++)
{
sprintf (buf, "%02x", (unsigned int) checksum[i]);
@@ -4086,7 +4121,7 @@ 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 = (Entnode *)node->data;
+ entnode = node->data;
free (entnode->timestamp);
entnode->timestamp = xstrdup ("=");
}
@@ -4104,7 +4139,7 @@ CVS server internal error: no mode in server_updated");
new_entries_line ();
- {
+ {
char *mode_string;
mode_string = mode_to_string (mode);
@@ -4144,9 +4179,9 @@ CVS server internal error: no mode in server_updated");
int fd;
/* Callers must avoid passing us a buffer if
- file_gzip_level is set. We could handle this case,
- but it's not worth it since this case never arises
- with a current client and server. */
+ file_gzip_level is set. We could handle this case,
+ but it's not worth it since this case never arises
+ with a current client and server. */
if (filebuf != NULL)
error (1, 0, "\
CVS server internal error: unhandled case in server_updated");
@@ -4196,7 +4231,6 @@ CVS server internal error: unhandled case in server_updated");
else
{
buf_append_buffer (protocol, filebuf);
- buf_free (filebuf);
}
/* Note we only send a newline here if the file ended with one. */
@@ -4277,10 +4311,12 @@ server_use_rcs_diff ()
return supported_response ("Rcs-diff");
}
+
+
void
server_set_entstat (update_dir, repository)
- char *update_dir;
- char *repository;
+ const char *update_dir;
+ const char *repository;
{
static int set_static_supported = -1;
if (set_static_supported == -1)
@@ -4293,10 +4329,12 @@ server_set_entstat (update_dir, repository)
buf_send_counted (protocol);
}
+
+
void
server_clear_entstat (update_dir, repository)
- char *update_dir;
- char *repository;
+ const char *update_dir;
+ const char *repository;
{
static int clear_static_supported = -1;
if (clear_static_supported == -1)
@@ -4311,13 +4349,15 @@ server_clear_entstat (update_dir, repository)
buf_output0 (protocol, "\n");
buf_send_counted (protocol);
}
-
+
+
+
void
server_set_sticky (update_dir, repository, tag, date, nonbranch)
- char *update_dir;
- char *repository;
- char *tag;
- char *date;
+ const char *update_dir;
+ const char *repository;
+ const char *tag;
+ const char *date;
int nonbranch;
{
static int set_sticky_supported = -1;
@@ -4362,8 +4402,8 @@ server_set_sticky (update_dir, repository, tag, date, nonbranch)
struct template_proc_data
{
- char *update_dir;
- char *repository;
+ const char *update_dir;
+ const char *repository;
};
/* Here as a static until we get around to fixing Parse_Info to pass along
@@ -4412,15 +4452,18 @@ template_proc (repository, template)
return 1;
}
}
+ buf_send_counted (protocol);
if (fclose (fp) < 0)
error (0, errno, "cannot close rcsinfo template file %s", template);
return 0;
}
+
+
void
server_template (update_dir, repository)
- char *update_dir;
- char *repository;
+ const char *update_dir;
+ const char *repository;
{
struct template_proc_data data;
data.update_dir = update_dir;
@@ -4428,7 +4471,9 @@ server_template (update_dir, repository)
tpd = &data;
(void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, 1);
}
-
+
+
+
static void
serve_gzip_contents (arg)
char *arg;
@@ -4473,8 +4518,8 @@ serve_wrapper_sendme_rcs_options (arg)
wrap_setup ();
for (wrap_unparse_rcs_options (&wrapper_line, 1);
- wrapper_line;
- wrap_unparse_rcs_options (&wrapper_line, 0))
+ wrapper_line;
+ wrap_unparse_rcs_options (&wrapper_line, 0))
{
buf_output0 (buf_to_net, "Wrapper-rcsOption ");
buf_output0 (buf_to_net, wrapper_line);
@@ -4541,7 +4586,7 @@ expand_proc (argc, argv, where, mwhere, mfile, shorten,
else
{
/* We may not need to do this anymore -- check the definition
- of aliases before removing */
+ of aliases before removing */
if (argc == 1)
{
buf_output0 (buf_to_net, "Module-expansion ");
@@ -4557,7 +4602,7 @@ expand_proc (argc, argv, where, mwhere, mfile, shorten,
{
for (i = 1; i < argc; ++i)
{
- buf_output0 (buf_to_net, "Module-expansion ");
+ buf_output0 (buf_to_net, "Module-expansion ");
if (server_dir != NULL)
{
buf_output0 (buf_to_net, server_dir);
@@ -4610,112 +4655,8 @@ serve_expand_modules (arg)
buf_flush (buf_to_net, 1);
}
-void
-server_prog (dir, name, which)
- char *dir;
- char *name;
- enum progs which;
-{
- if (!supported_response ("Set-checkin-prog"))
- {
- buf_output0 (protocol, "E \
-warning: this client does not support -i or -u flags in the modules file.\n");
- return;
- }
- switch (which)
- {
- case PROG_CHECKIN:
- buf_output0 (protocol, "Set-checkin-prog ");
- break;
- case PROG_UPDATE:
- buf_output0 (protocol, "Set-update-prog ");
- break;
- }
- buf_output0 (protocol, dir);
- buf_append_char (protocol, '\n');
- buf_output0 (protocol, name);
- buf_append_char (protocol, '\n');
- buf_send_counted (protocol);
-}
-
-static void
-serve_checkin_prog (arg)
- char *arg;
-{
- FILE *f;
- f = CVS_FOPEN (CVSADM_CIPROG, "w+");
- if (f == NULL)
- {
- int save_errno = errno;
- if (alloc_pending (80 + strlen (CVSADM_CIPROG)))
- sprintf (pending_error_text, "E cannot open %s", CVSADM_CIPROG);
- pending_error = save_errno;
- return;
- }
- if (fprintf (f, "%s\n", arg) < 0)
- {
- int save_errno = errno;
- if (alloc_pending (80 + strlen (CVSADM_CIPROG)))
- sprintf (pending_error_text,
- "E cannot write to %s", CVSADM_CIPROG);
- pending_error = save_errno;
- return;
- }
- if (fclose (f) == EOF)
- {
- int save_errno = errno;
- if (alloc_pending (80 + strlen (CVSADM_CIPROG)))
- sprintf (pending_error_text, "E cannot close %s", CVSADM_CIPROG);
- pending_error = save_errno;
- return;
- }
-}
-
-static void
-serve_update_prog (arg)
- char *arg;
-{
- FILE *f;
- /* Before we do anything we need to make sure we are not in readonly
- mode. */
- if (!check_command_legal_p ("commit"))
- {
- /* I might be willing to make this a warning, except we lack the
- machinery to do so. */
- if (alloc_pending (80))
- sprintf (pending_error_text, "\
-E Flag -u in modules not allowed in readonly mode");
- return;
- }
- f = CVS_FOPEN (CVSADM_UPROG, "w+");
- if (f == NULL)
- {
- int save_errno = errno;
- if (alloc_pending (80 + strlen (CVSADM_UPROG)))
- sprintf (pending_error_text, "E cannot open %s", CVSADM_UPROG);
- pending_error = save_errno;
- return;
- }
- if (fprintf (f, "%s\n", arg) < 0)
- {
- int save_errno = errno;
- if (alloc_pending (80 + strlen (CVSADM_UPROG)))
- sprintf (pending_error_text, "E cannot write to %s", CVSADM_UPROG);
- pending_error = save_errno;
- return;
- }
- if (fclose (f) == EOF)
- {
- int save_errno = errno;
- if (alloc_pending (80 + strlen (CVSADM_UPROG)))
- sprintf (pending_error_text, "E cannot close %s", CVSADM_UPROG);
- pending_error = save_errno;
- return;
- }
-}
-
static void serve_valid_requests PROTO((char *arg));
#endif /* SERVER_SUPPORT */
@@ -4745,8 +4686,6 @@ struct request requests[] =
REQ_LINE("Max-dotdot", serve_max_dotdot, 0),
REQ_LINE("Static-directory", serve_static_directory, 0),
REQ_LINE("Sticky", serve_sticky, 0),
- REQ_LINE("Checkin-prog", serve_checkin_prog, 0),
- REQ_LINE("Update-prog", serve_update_prog, 0),
REQ_LINE("Entry", serve_entry, RQ_ESSENTIAL),
REQ_LINE("Kopt", serve_kopt, 0),
REQ_LINE("Checkin-time", serve_checkin_time, 0),
@@ -4761,14 +4700,13 @@ struct request requests[] =
REQ_LINE("Unchanged", serve_unchanged, RQ_ESSENTIAL),
REQ_LINE("Notify", serve_notify, 0),
REQ_LINE("Questionable", serve_questionable, 0),
- REQ_LINE("Case", serve_case, 0),
REQ_LINE("Argument", serve_argument, RQ_ESSENTIAL),
REQ_LINE("Argumentx", serve_argumentx, RQ_ESSENTIAL),
REQ_LINE("Global_option", serve_global_option, RQ_ROOTLESS),
REQ_LINE("Gzip-stream", serve_gzip_stream, 0),
REQ_LINE("wrapper-sendme-rcsOptions",
- serve_wrapper_sendme_rcs_options,
- 0),
+ serve_wrapper_sendme_rcs_options,
+ 0),
REQ_LINE("Set", serve_set, RQ_ROOTLESS),
#ifdef ENCRYPTION
# ifdef HAVE_KERBEROS
@@ -4882,25 +4820,27 @@ server_cleanup (sig)
* have generated any final output, we shut down BUF_TO_NET.
*/
- status = buf_shutdown (buf_from_net);
- if (status != 0)
- error (0, status, "shutting down buffer from client");
- buf_free (buf_from_net);
- buf_from_net = NULL;
- }
+ if (buf_from_net != NULL)
+ {
+ status = buf_shutdown (buf_from_net);
+ if (status != 0)
+ error (0, status, "shutting down buffer from client");
+ buf_free (buf_from_net);
+ buf_from_net = NULL;
+ }
- if (dont_delete_temp)
- {
- if (buf_to_net != NULL)
+ if (dont_delete_temp)
{
(void) buf_flush (buf_to_net, 1);
(void) buf_shutdown (buf_to_net);
buf_free (buf_to_net);
buf_to_net = NULL;
error_use_protocol = 0;
+ return;
}
- return;
}
+ else if (dont_delete_temp)
+ return;
/* What a bogus kludge. This disgusting code makes all kinds of
assumptions about SunOS, and is only for a bug in that system.
@@ -5092,13 +5032,13 @@ error ENOMEM Virtual memory exhausted.\n");
orig_server_temp_dir = server_temp_dir;
/* Create the temporary directory, and set the mode to
- 700, to discourage random people from tampering with
- it. */
+ 700, to discourage random people from tampering with
+ it. */
while ((status = mkdir_p (server_temp_dir)) == EEXIST)
{
- static const char suffix[] = "abcdefghijklmnopqrstuvwxyz";
+ static const char suffix[] = "abcdefghijklmnopqrstuvwxyz";
- if (i >= sizeof suffix - 1) break;
+ if (i >= sizeof suffix - 1) break;
if (i == 0) p = server_temp_dir + strlen (server_temp_dir);
p[0] = suffix[i++];
p[1] = '\0';
@@ -5138,8 +5078,7 @@ error ENOMEM Virtual memory exhausted.\n");
/* Small for testing. */
argument_vector_size = 1;
- argument_vector =
- (char **) xmalloc (argument_vector_size * sizeof (char *));
+ argument_vector = xmalloc (argument_vector_size * sizeof (char *));
argument_count = 1;
/* This gets printed if the client supports an option which the
server doesn't, causing the server to print a usage message.
@@ -5148,7 +5087,7 @@ error ENOMEM Virtual memory exhausted.\n");
by options which are for a particular command. Might be nice to
say something like "client apparently supports an option not supported
by this server" or something like that instead of usage message. */
- error_prog_name = xmalloc( strlen(program_name) + 8 );
+ error_prog_name = xmalloc (strlen (program_name) + 8);
sprintf(error_prog_name, "%s server", program_name);
argument_vector[0] = error_prog_name;
@@ -5158,7 +5097,7 @@ error ENOMEM Virtual memory exhausted.\n");
struct request *rq;
int status;
- status = buf_read_line (buf_from_net, &cmd, (int *) NULL);
+ status = buf_read_line (buf_from_net, &cmd, NULL);
if (status == -2)
{
buf_output0 (buf_to_net, "E Fatal server error, aborting.\n\
@@ -5215,7 +5154,7 @@ error ENOMEM Virtual memory exhausted.\n");
{
if (!print_pending_error ())
{
- buf_output0 (buf_to_net, "error unrecognized request `");
+ buf_output0 (buf_to_net, "error unrecognized request `");
buf_output0 (buf_to_net, cmd);
buf_append_char (buf_to_net, '\'');
buf_append_char (buf_to_net, '\n');
@@ -5223,12 +5162,33 @@ error ENOMEM Virtual memory exhausted.\n");
}
free (orig_cmd);
}
- free(error_prog_name);
+ free (error_prog_name);
+
+ /* We expect the client is done talking to us at this point. If there is
+ * any data in the buffer or on the network pipe, then something we didn't
+ * prepare for is happening.
+ */
+ if (!buf_empty (buf_from_net))
+ {
+ /* Try to send the error message to the client, but also syslog it, in
+ * case the client isn't listening anymore.
+ */
+#ifdef HAVE_SYSLOG_H
+ /* FIXME: Can the IP address of the connecting client be retrieved
+ * and printed here?
+ */
+ syslog (LOG_DAEMON | LOG_ERR, "Dying gasps received from client.");
+#endif
+ error (0, 0, "Dying gasps received from client.");
+ }
+
+ /* This command will actually close the network buffers. */
server_cleanup (0);
return 0;
}
-
+
+
#if defined (HAVE_KERBEROS) || defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
static void switch_to_user PROTO((const char *, const char *));
@@ -5242,11 +5202,11 @@ switch_to_user (cvs_username, username)
pw = getpwnam (username);
if (pw == NULL)
{
- /* Normally this won't be reached; check_password contains
- a similar check. */
+ /* check_password contains a similar check, so this usually won't be
+ reached unless the CVS user is mapped to an invalid system user. */
printf ("E Fatal error, aborting.\n\
-error 0 %s: no such user\n", username);
+error 0 %s: no such system user\n", username);
/* Don't worry about server_cleanup; server_active isn't set yet. */
error_exit ();
}
@@ -5305,6 +5265,11 @@ error 0 %s: no such user\n", username);
{
/* See comments at setuid call below for more discussion. */
printf ("error 0 setgid failed: %s\n", strerror (errno));
+#ifdef HAVE_SYSLOG_H
+ syslog (LOG_DAEMON | LOG_ERR,
+ "setgid to %d failed (%m): real %d/%d, effective %d/%d ",
+ pw->pw_gid, getuid(), getgid(), geteuid(), getegid());
+#endif
/* Don't worry about server_cleanup;
server_active isn't set yet. */
error_exit ();
@@ -5320,6 +5285,11 @@ error 0 %s: no such user\n", username);
it does mean that some people might need to update their
CVSROOT/passwd file. */
printf ("error 0 setuid failed: %s\n", strerror (errno));
+#ifdef HAVE_SYSLOG_H
+ syslog (LOG_DAEMON | LOG_ERR,
+ "setuid to %d failed (%m): real %d/%d, effective %d/%d ",
+ pw->pw_uid, getuid(), getgid(), geteuid(), getegid());
+#endif
/* Don't worry about server_cleanup; server_active isn't set yet. */
error_exit ();
}
@@ -5350,9 +5320,9 @@ error 0 %s: no such user\n", username);
(void) putenv (env);
#ifdef AUTH_SERVER_SUPPORT
- env = xmalloc (sizeof "CVS_USER=" + strlen (CVS_Username));
- (void) sprintf (env, "CVS_USER=%s", CVS_Username);
- (void) putenv (env);
+ env = xmalloc (sizeof "CVS_USER=" + strlen (CVS_Username));
+ (void) sprintf (env, "CVS_USER=%s", CVS_Username);
+ (void) putenv (env);
#endif
}
#endif /* HAVE_PUTENV */
@@ -5401,7 +5371,7 @@ check_repository_password (username, password, repository, host_user_ptr)
+ 1);
(void) sprintf (filename, "%s/%s/%s", repository,
- CVSROOTADM, CVSROOTADM_PASSWD);
+ CVSROOTADM, CVSROOTADM_PASSWD);
fp = CVS_FOPEN (filename, "r");
if (fp == NULL)
@@ -5417,10 +5387,10 @@ check_repository_password (username, password, repository, host_user_ptr)
{
if ((strncmp (linebuf, username, namelen) == 0)
&& (linebuf[namelen] == ':'))
- {
+ {
found_it = 1;
break;
- }
+ }
}
if (ferror (fp))
error (0, errno, "cannot read %s", filename);
@@ -5431,78 +5401,83 @@ check_repository_password (username, password, repository, host_user_ptr)
if (found_it)
{
char *found_password, *host_user_tmp;
- char *non_cvsuser_portion;
-
- /* We need to make sure lines such as
- *
- * "username::sysuser\n"
- * "username:\n"
- * "username: \n"
- *
- * all result in a found_password of NULL, but we also need to
- * make sure that
- *
- * "username: :sysuser\n"
- * "username: <whatever>:sysuser\n"
- *
- * continues to result in an impossible password. That way,
- * an admin would be on safe ground by going in and tacking a
- * space onto the front of a password to disable the account
- * (a technique some people use to close accounts
- * temporarily).
- */
-
- /* Make `non_cvsuser_portion' contain everything after the CVS
- username, but null out any final newline. */
+ char *non_cvsuser_portion;
+
+ /* We need to make sure lines such as
+ *
+ * "username::sysuser\n"
+ * "username:\n"
+ * "username: \n"
+ *
+ * all result in a found_password of NULL, but we also need to
+ * make sure that
+ *
+ * "username: :sysuser\n"
+ * "username: <whatever>:sysuser\n"
+ *
+ * continues to result in an impossible password. That way,
+ * an admin would be on safe ground by going in and tacking a
+ * space onto the front of a password to disable the account
+ * (a technique some people use to close accounts
+ * temporarily).
+ */
+
+ /* Make `non_cvsuser_portion' contain everything after the CVS
+ username, but null out any final newline. */
non_cvsuser_portion = linebuf + namelen;
- strtok (non_cvsuser_portion, "\n");
-
- /* If there's a colon now, we just want to inch past it. */
- if (strchr (non_cvsuser_portion, ':') == non_cvsuser_portion)
- non_cvsuser_portion++;
-
- /* Okay, after this conditional chain, found_password and
- host_user_tmp will have useful values: */
-
- if ((non_cvsuser_portion == NULL)
- || (strlen (non_cvsuser_portion) == 0)
- || ((strspn (non_cvsuser_portion, " \t"))
- == strlen (non_cvsuser_portion)))
- {
- found_password = NULL;
- host_user_tmp = NULL;
- }
- else if (strncmp (non_cvsuser_portion, ":", 1) == 0)
- {
- found_password = NULL;
- host_user_tmp = non_cvsuser_portion + 1;
- if (strlen (host_user_tmp) == 0)
- host_user_tmp = NULL;
- }
- else
- {
- found_password = strtok (non_cvsuser_portion, ":");
- host_user_tmp = strtok (NULL, ":");
- }
-
- /* Of course, maybe there was no system user portion... */
+ strtok (non_cvsuser_portion, "\n");
+
+ /* If there's a colon now, we just want to inch past it. */
+ if (strchr (non_cvsuser_portion, ':') == non_cvsuser_portion)
+ non_cvsuser_portion++;
+
+ /* Okay, after this conditional chain, found_password and
+ host_user_tmp will have useful values: */
+
+ if ((non_cvsuser_portion == NULL)
+ || (strlen (non_cvsuser_portion) == 0)
+ || ((strspn (non_cvsuser_portion, " \t"))
+ == strlen (non_cvsuser_portion)))
+ {
+ found_password = NULL;
+ host_user_tmp = NULL;
+ }
+ else if (strncmp (non_cvsuser_portion, ":", 1) == 0)
+ {
+ found_password = NULL;
+ host_user_tmp = non_cvsuser_portion + 1;
+ if (strlen (host_user_tmp) == 0)
+ host_user_tmp = NULL;
+ }
+ else
+ {
+ found_password = strtok (non_cvsuser_portion, ":");
+ host_user_tmp = strtok (NULL, ":");
+ }
+
+ /* Of course, maybe there was no system user portion... */
if (host_user_tmp == NULL)
- host_user_tmp = username;
-
- /* Verify blank passwords directly, otherwise use crypt(). */
- if ((found_password == NULL)
- || ((strcmp (found_password, crypt (password, found_password))
- == 0)))
- {
- /* Give host_user_ptr permanent storage. */
- *host_user_ptr = xstrdup (host_user_tmp);
+ host_user_tmp = username;
+
+ /* Verify blank passwords directly, otherwise use crypt(). */
+ if ((found_password == NULL)
+ || ((strcmp (found_password, crypt (password, found_password))
+ == 0)))
+ {
+ /* Give host_user_ptr permanent storage. */
+ *host_user_ptr = xstrdup (host_user_tmp);
retval = 1;
- }
+ }
else
- {
- *host_user_ptr = NULL;
- retval = 2;
- }
+ {
+#ifdef LOG_AUTHPRIV
+ syslog (LOG_AUTHPRIV | LOG_NOTICE,
+ "password mismatch for %s in %s: %s vs. %s", username,
+ repository, crypt(password, found_password), found_password);
+#endif
+ *host_user_ptr = NULL;
+ retval = 2;
+ }
}
else /* Didn't find this user, so deny access. */
{
@@ -5512,12 +5487,13 @@ check_repository_password (username, password, repository, host_user_ptr)
free (filename);
if (linebuf)
- free (linebuf);
+ free (linebuf);
return retval;
}
+
/* Return a hosting username if password matches, else NULL. */
static char *
check_password (username, password, repository)
@@ -5525,6 +5501,8 @@ check_password (username, password, repository)
{
int rc;
char *host_user = NULL;
+ char *found_passwd = NULL;
+ struct passwd *pw;
/* First we see if this user has a password in the CVS-specific
password file. If so, that's enough to authenticate with. If
@@ -5536,20 +5514,31 @@ check_password (username, password, repository)
if (rc == 2)
return NULL;
- /* else */
-
if (rc == 1)
{
- /* host_user already set by reference, so just return. */
- goto handle_return;
+ /* host_user already set by reference, so just return. */
+ goto handle_return;
}
- else if (rc == 0 && system_auth)
+
+ assert (rc == 0);
+
+ if (!system_auth)
{
- /* No cvs password found, so try /etc/passwd. */
+ /* Note that the message _does_ distinguish between the case in
+ which we check for a system password and the case in which
+ we do not. It is a real pain to track down why it isn't
+ letting you in if it won't say why, and I am not convinced
+ that the potential information disclosure to an attacker
+ outweighs this. */
+ printf ("error 0 no such user %s in CVSROOT/passwd\n", username);
+
+ error_exit ();
+ }
+
+ /* No cvs password found, so try /etc/passwd. */
- char *found_passwd = NULL;
- struct passwd *pw;
#ifdef HAVE_GETSPNAM
+ {
struct spwd *spw;
spw = getspnam (username);
@@ -5557,85 +5546,78 @@ check_password (username, password, repository)
{
found_passwd = spw->sp_pwdp;
}
+ }
#endif
- if (found_passwd == NULL && (pw = getpwnam (username)) != NULL)
- {
- found_passwd = pw->pw_passwd;
- }
+ if (found_passwd == NULL && (pw = getpwnam (username)) != NULL)
+ {
+ found_passwd = pw->pw_passwd;
+ }
- if (found_passwd == NULL)
- {
- printf ("E Fatal error, aborting.\n\
+ if (found_passwd == NULL)
+ {
+ printf ("E Fatal error, aborting.\n\
error 0 %s: no such user\n", username);
- error_exit ();
- }
+ error_exit ();
+ }
- /* Allow for dain bramaged HPUX passwd aging
- * - Basically, HPUX adds a comma and some data
- * about whether the passwd has expired or not
- * on the end of the passwd field.
- * - This code replaces the ',' with '\0'.
- *
- * FIXME - our workaround is brain damaged too. I'm
- * guessing that HPUX WANTED other systems to think the
- * password was wrong so logins would fail if the
- * system didn't handle expired passwds and the passwd
- * might be expired. I think the way to go here
- * is with PAM.
- */
- strtok (found_passwd, ",");
-
- if (*found_passwd)
- {
- /* user exists and has a password */
- host_user = ((! strcmp (found_passwd,
- crypt (password, found_passwd)))
- ? xstrdup (username) : NULL);
- goto handle_return;
- }
- else if (password && *password)
- {
- /* user exists and has no system password, but we got
- one as parameter */
+ /* Allow for dain bramaged HPUX passwd aging
+ * - Basically, HPUX adds a comma and some data
+ * about whether the passwd has expired or not
+ * on the end of the passwd field.
+ * - This code replaces the ',' with '\0'.
+ *
+ * FIXME - our workaround is brain damaged too. I'm
+ * guessing that HPUX WANTED other systems to think the
+ * password was wrong so logins would fail if the
+ * system didn't handle expired passwds and the passwd
+ * might be expired. I think the way to go here
+ * is with PAM.
+ */
+ strtok (found_passwd, ",");
+
+ if (*found_passwd)
+ {
+ /* user exists and has a password */
+ if (strcmp (found_passwd, crypt (password, found_passwd)) == 0)
+ {
host_user = xstrdup (username);
- goto handle_return;
- }
+ }
else
- {
- /* user exists but has no password at all */
+ {
host_user = NULL;
- goto handle_return;
- }
+#ifdef LOG_AUTHPRIV
+ syslog (LOG_AUTHPRIV | LOG_NOTICE,
+ "password mismatch for %s: %s vs. %s", username,
+ crypt(password, found_passwd), found_passwd);
+#endif
+ }
+ goto handle_return;
}
- else if (rc == 0)
- {
- /* Note that the message _does_ distinguish between the case in
- which we check for a system password and the case in which
- we do not. It is a real pain to track down why it isn't
- letting you in if it won't say why, and I am not convinced
- that the potential information disclosure to an attacker
- outweighs this. */
- printf ("error 0 no such user %s in CVSROOT/passwd\n", username);
- error_exit ();
- }
- else
+ if (password && *password)
{
- /* Something strange happened. We don't know what it was, but
- we certainly won't grant authorization. */
- host_user = NULL;
- goto handle_return;
+ /* user exists and has no system password, but we got
+ one as parameter */
+ host_user = xstrdup (username);
+ goto handle_return;
}
+ /* user exists but has no password at all */
+ host_user = NULL;
+#ifdef LOG_AUTHPRIV
+ syslog (LOG_AUTHPRIV | LOG_NOTICE,
+ "login refused for %s: user has no password", username);
+#endif
+
handle_return:
if (host_user)
{
- /* Set CVS_Username here, in allocated space.
- It might or might not be the same as host_user. */
- CVS_Username = xmalloc (strlen (username) + 1);
- strcpy (CVS_Username, username);
+ /* Set CVS_Username here, in allocated space.
+ It might or might not be the same as host_user. */
+ CVS_Username = xmalloc (strlen (username) + 1);
+ strcpy (CVS_Username, username);
}
return host_user;
@@ -5690,7 +5672,7 @@ pserver_authenticate_connection ()
*
* BEGIN VERIFICATION REQUEST\n
*
- * and
+ * and
*
* END VERIFICATION REQUEST\n
*
@@ -5762,10 +5744,16 @@ pserver_authenticate_connection ()
getline_safe (&username, &username_allocated, stdin, PATH_MAX);
getline_safe (&password, &password_allocated, stdin, PATH_MAX);
- /* Make them pure. */
- strip_trailing_newlines (repository);
- strip_trailing_newlines (username);
- strip_trailing_newlines (password);
+ /* Make them pure.
+ *
+ * We check that none of the lines were truncated by getnline in order
+ * to be sure that we don't accidentally allow a blind DOS attack to
+ * authenticate, however slim the odds of that might be.
+ */
+ if (!strip_trailing_newlines (repository)
+ || !strip_trailing_newlines (username)
+ || !strip_trailing_newlines (password))
+ error (1, 0, "Maximum line length exceeded during authentication.");
/* ... and make sure the protocol ends on the right foot. */
/* See above comment about error handling. */
@@ -5800,10 +5788,6 @@ pserver_authenticate_connection ()
{
#ifdef HAVE_SYSLOG_H
syslog (LOG_DAEMON | LOG_NOTICE, "login failure (for %s)", repository);
-#ifdef LOG_AUTHPRIV
- syslog (LOG_AUTHPRIV | LOG_NOTICE, "login failure by %s / %s (for %s)",
- username, descrambled_password, repository);
-#endif
#endif
memset (descrambled_password, 0, strlen (descrambled_password));
free (descrambled_password);
@@ -5920,7 +5904,7 @@ error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status));
}
/* Switch to run as this user. */
- switch_to_user (user);
+ switch_to_user ("Kerberos 4", user);
}
#endif /* HAVE_KERBEROS */
@@ -5941,6 +5925,8 @@ gserver_authenticate_connection ()
struct hostent *hp;
gss_buffer_desc tok_in, tok_out;
char buf[1024];
+ char *credbuf;
+ size_t credbuflen;
OM_uint32 stat_min, ret;
gss_name_t server_name, client_name;
gss_cred_id_t server_creds;
@@ -5975,26 +5961,35 @@ gserver_authenticate_connection ()
error (1, errno, "read of length failed");
nbytes = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff);
- assert (nbytes <= sizeof buf);
-
- if (fread (buf, 1, nbytes, stdin) != nbytes)
+ if (nbytes <= sizeof buf)
+ {
+ credbuf = buf;
+ credbuflen = sizeof buf;
+ }
+ else
+ {
+ credbuflen = nbytes;
+ credbuf = xmalloc (credbuflen);
+ }
+
+ if (fread (credbuf, 1, nbytes, stdin) != nbytes)
error (1, errno, "read of data failed");
gcontext = GSS_C_NO_CONTEXT;
tok_in.length = nbytes;
- tok_in.value = buf;
+ tok_in.value = credbuf;
if (gss_accept_sec_context (&stat_min,
- &gcontext, /* context_handle */
- server_creds, /* verifier_cred_handle */
- &tok_in, /* input_token */
- NULL, /* channel bindings */
- &client_name, /* src_name */
- &mechid, /* mech_type */
- &tok_out, /* output_token */
- &ret,
- NULL, /* ignore time_rec */
- NULL) /* ignore del_cred_handle */
+ &gcontext, /* context_handle */
+ server_creds, /* verifier_cred_handle */
+ &tok_in, /* input_token */
+ NULL, /* channel bindings */
+ &client_name, /* src_name */
+ &mechid, /* mech_type */
+ &tok_out, /* output_token */
+ &ret,
+ NULL, /* ignore time_rec */
+ NULL) /* ignore del_cred_handle */
!= GSS_S_COMPLETE)
{
error (1, 0, "could not verify credentials");
@@ -6034,6 +6029,9 @@ gserver_authenticate_connection ()
switch_to_user ("GSSAPI", buf);
+ if (credbuf != buf)
+ free (credbuf);
+
printf ("I LOVE YOU\n");
fflush (stdout);
}
@@ -6425,8 +6423,9 @@ this client does not support writing binary files to stdout");
}
}
-/* Like CVS_OUTPUT but output is for stderr not stdout. */
+
+/* Like CVS_OUTPUT but output is for stderr not stdout. */
void
cvs_outerr (str, len)
const char *str;
@@ -6470,10 +6469,11 @@ cvs_outerr (str, len)
}
}
+
+
/* Flush stderr. stderr is normally flushed automatically, of course,
but this function is used to flush information from the server back
to the client. */
-
void
cvs_flusherr ()
{
@@ -6500,10 +6500,11 @@ cvs_flusherr ()
fflush (stderr);
}
+
+
/* Make it possible for the user to see what has been written to
stdout (it is up to the implementation to decide exactly how far it
should go to ensure this). */
-
void
cvs_flushout ()
{
@@ -6542,8 +6543,8 @@ cvs_flushout ()
void
cvs_output_tagged (tag, text)
- char *tag;
- char *text;
+ const char *tag;
+ const char *text;
{
if (text != NULL && strchr (text, '\n') != NULL)
/* Uh oh. The protocol has no way to cope with this. For now
diff --git a/contrib/cvs/src/server.h b/contrib/cvs/src/server.h
index 31f23d51..20152d8 100644
--- a/contrib/cvs/src/server.h
+++ b/contrib/cvs/src/server.h
@@ -1,4 +1,16 @@
-/* Interface between the server and the rest of CVS. */
+/*
+ * Copyright (c) 2003 The Free Software Foundation.
+ *
+ * Portions Copyright (c) 2003 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 kit.
+ *
+ *
+ *
+ * This file contains the interface between the server and the rest of CVS.
+ */
/* Miscellaneous stuff which isn't actually particularly server-specific. */
#ifndef STDIN_FILENO
@@ -6,7 +18,7 @@
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
-
+
/*
* Expand to `S', ` ', or the empty string. Used in `%s-> ...' trace printfs.
@@ -30,13 +42,24 @@ extern int server_active;
/* Run the server. */
extern int server PROTO((int argc, char **argv));
+/* kserver user authentication. */
+# ifdef HAVE_KERBEROS
+extern void kserver_authenticate_connection PROTO ((void));
+# endif
+
+/* pserver user authentication. */
+# if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
+extern void pserver_authenticate_connection PROTO ((void));
+# endif
+
/* See server.c for description. */
extern void server_pathname_check PROTO ((char *));
/* We have a new Entries line for a file. TAG or DATE can be NULL. */
extern void server_register
- PROTO((char *name, char *version, char *timestamp,
- char *options, char *tag, char *date, char *conflict));
+ PROTO((const char *name, const char *version, const char *timestamp,
+ const char *options, const char *tag, const char *date,
+ const char *conflict));
/* Set the modification time of the next file sent. This must be
followed by a call to server_updated on the same file. */
@@ -47,7 +70,7 @@ extern void server_modtime PROTO ((struct file_info *finfo,
* We want to nuke the Entries line for a file, and (unless
* server_scratch_entry_only is subsequently called) the file itself.
*/
-extern void server_scratch PROTO((char *name));
+extern void server_scratch PROTO((const char *name));
/*
* The file which just had server_scratch called on it needs to have only
@@ -61,10 +84,11 @@ extern void server_scratch_entry_only PROTO((void));
* repository.
*/
extern void server_checked_in
- PROTO((char *file, char *update_dir, char *repository));
+ PROTO((const char *file, const char *update_dir, const char *repository));
extern void server_copy_file
- PROTO((char *file, char *update_dir, char *repository, char *newfile));
+ PROTO((const char *file, const char *update_dir, const char *repository,
+ const char *newfile));
/* Send the appropriate responses for a file described by FINFO and
VERS. This is called after server_register or server_scratch. In
@@ -99,18 +123,21 @@ extern void server_updated
extern int server_use_rcs_diff PROTO((void));
/* Set the Entries.Static flag. */
-extern void server_set_entstat PROTO((char *update_dir, char *repository));
+extern void server_set_entstat PROTO((const char *update_dir,
+ const char *repository));
/* Clear it. */
-extern void server_clear_entstat PROTO((char *update_dir, char *repository));
+extern void server_clear_entstat PROTO((const char *update_dir,
+ const char *repository));
/* Set or clear a per-directory sticky tag or date. */
-extern void server_set_sticky PROTO((char *update_dir, char *repository,
- char *tag, char *date, int nonbranch));
+extern void server_set_sticky PROTO((const char *update_dir,
+ const char *repository, const char *tag,
+ const char *date, int nonbranch));
/* Send Template response. */
-extern void server_template PROTO ((char *, char *));
+extern void server_template PROTO ((const char *, const char *));
extern void server_update_entries
- PROTO((char *file, char *update_dir, char *repository,
+ PROTO((const char *file, const char *update_dir, const char *repository,
enum server_updated_arg4 updated));
/* Pointer to a malloc'd string which is the directory which
@@ -118,8 +145,6 @@ extern void server_update_entries
to the client. */
extern char *server_dir;
-enum progs {PROG_CHECKIN, PROG_UPDATE};
-extern void server_prog PROTO((char *, char *, enum progs));
extern void server_cleanup PROTO((int sig));
#ifdef SERVER_FLOWCONTROL
@@ -173,5 +198,5 @@ extern struct request requests[];
/* Gzip library, see zlib.c. */
extern int gunzip_and_write PROTO ((int, char *, unsigned char *, size_t));
-extern int read_and_gzip PROTO ((int, char *, unsigned char **, size_t *,
- size_t *, int));
+extern int read_and_gzip PROTO ((int, const char *, unsigned char **, size_t *,
+ size_t *, int));
diff --git a/contrib/cvs/src/stack.c b/contrib/cvs/src/stack.c
new file mode 100644
index 0000000..edba905
--- /dev/null
+++ b/contrib/cvs/src/stack.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2004, Free Software Foundation,
+ * Derek Price,
+ * & 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.
+ *
+ * This module uses the hash.c module to implement a stack.
+ */
+
+#include "cvs.h"
+#include <assert.h>
+
+
+
+static void
+do_push (stack, elem, isstring)
+ List *stack;
+ void *elem;
+ int isstring;
+{
+ Node *p = getnode();
+
+ if (isstring)
+ p->key = elem;
+ else
+ p->data = elem;
+
+ addnode(stack, p);
+}
+
+
+
+void
+push (stack, elem)
+ List *stack;
+ void *elem;
+{
+ do_push (stack, elem, 0);
+}
+
+
+
+void
+push_string (stack, elem)
+ List *stack;
+ char *elem;
+{
+ do_push (stack, elem, 1);
+}
+
+
+
+static void *
+do_pop (stack, isstring)
+ List *stack;
+ int isstring;
+{
+ void *elem;
+
+ if (isempty (stack)) return NULL;
+
+ if (isstring)
+ {
+ elem = stack->list->prev->key;
+ stack->list->prev->key = NULL;
+ }
+ else
+ {
+ elem = stack->list->prev->data;
+ stack->list->prev->data = NULL;
+ }
+
+ delnode (stack->list->prev);
+ return elem;
+}
+
+
+
+void *
+pop (stack)
+ List *stack;
+{
+ return do_pop (stack, 0);
+}
+
+
+
+char *
+pop_string (stack)
+ List *stack;
+{
+ return do_pop (stack, 1);
+}
+
+
+
+static void
+do_unshift (stack, elem, isstring)
+ List *stack;
+ void *elem;
+ int isstring;
+{
+ Node *p = getnode();
+
+ if (isstring)
+ p->key = elem;
+ else
+ p->data = elem;
+
+ addnode_at_front(stack, p);
+}
+
+
+
+void
+unshift (stack, elem)
+ List *stack;
+ void *elem;
+{
+ do_unshift (stack, elem, 0);
+}
+
+
+
+void
+unshift_string (stack, elem)
+ List *stack;
+ char *elem;
+{
+ do_unshift (stack, elem, 1);
+}
+
+
+
+static void *
+do_shift (stack, isstring)
+ List *stack;
+ int isstring;
+{
+ void *elem;
+
+ if (isempty (stack)) return NULL;
+
+ if (isstring)
+ {
+ elem = stack->list->next->key;
+ stack->list->next->key = NULL;
+ }
+ else
+ {
+ elem = stack->list->next->data;
+ stack->list->next->data = NULL;
+ }
+ delnode (stack->list->next);
+ return elem;
+}
+
+
+
+void *
+shift (stack)
+ List *stack;
+{
+ return do_shift (stack, 0);
+}
+
+
+
+char *
+shift_string (stack)
+ List *stack;
+{
+ return do_shift (stack, 1);
+}
+
+
+
+int
+isempty (stack)
+ List *stack;
+{
+ if (stack->list == stack->list->next)
+ return 1;
+ return 0;
+}
diff --git a/contrib/cvs/src/stack.h b/contrib/cvs/src/stack.h
new file mode 100644
index 0000000..49ebdf8
--- /dev/null
+++ b/contrib/cvs/src/stack.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2004, Free Software Foundation,
+ * Derek Price,
+ * & 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.
+ */
+
+void push PROTO((List *_stack, void *_elem));
+void *pop PROTO((List *_stack));
+void unshift PROTO((List *_stack, void *_elem));
+void *shift PROTO((List *_stack));
+void push_string PROTO((List *_stack, char *_elem));
+char *pop_string PROTO((List *_stack));
+void unshift_string PROTO((List *_stack, char *_elem));
+char *shift_string PROTO((List *_stack));
+int isempty PROTO((List *_stack));
diff --git a/contrib/cvs/src/status.c b/contrib/cvs/src/status.c
index b7853e5..2e2957e 100644
--- a/contrib/cvs/src/status.c
+++ b/contrib/cvs/src/status.c
@@ -10,8 +10,8 @@
#include "cvs.h"
-static Dtype status_dirproc PROTO ((void *callerdat, char *dir,
- char *repos, char *update_dir,
+static Dtype status_dirproc PROTO ((void *callerdat, const char *dir,
+ const char *repos, const char *update_dir,
List *entries));
static int status_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static int tag_list_proc PROTO((Node * p, void *closure));
@@ -107,7 +107,8 @@ cvsstatus (argc, argv)
err = start_recursion (status_fileproc, (FILESDONEPROC) NULL,
status_dirproc, (DIRLEAVEPROC) NULL, NULL,
argc, argv, local,
- W_LOCAL, 0, CVS_LOCK_READ, (char *) NULL, 1);
+ W_LOCAL, 0, CVS_LOCK_READ, (char *) NULL, 1,
+ (char *) NULL);
return (err);
}
@@ -152,9 +153,15 @@ status_fileproc (callerdat, finfo)
sstat = "Locally Removed";
break;
case T_MODIFIED:
- if (vers->ts_conflict)
+ if ( vers->ts_conflict
+ && ( file_has_conflict ( finfo, vers->ts_conflict )
+ || file_has_markers ( finfo ) ) )
sstat = "File had conflicts on merge";
else
+ /* Note that we do not re Register() the file when we spot
+ * a resolved conflict like update_fileproc() does on the
+ * premise that status should not alter the sandbox.
+ */
sstat = "Locally Modified";
break;
case T_REMOVE_ENTRY:
@@ -316,9 +323,9 @@ status_fileproc (callerdat, finfo)
static Dtype
status_dirproc (callerdat, dir, repos, update_dir, entries)
void *callerdat;
- char *dir;
- char *repos;
- char *update_dir;
+ const char *dir;
+ const char *repos;
+ const char *update_dir;
List *entries;
{
if (!quiet)
@@ -344,7 +351,7 @@ tag_list_proc (p, closure)
+ (branch ? strlen (branch) : strlen (p->data)));
sprintf (buf, "\t%-25s\t(%s: %s)\n", p->key,
branch ? "branch" : "revision",
- branch ? branch : p->data);
+ branch ? branch : (char *)p->data);
cvs_output (buf, 0);
free (buf);
diff --git a/contrib/cvs/src/subr.c b/contrib/cvs/src/subr.c
index 7a6acfb..94f5bbd 100644
--- a/contrib/cvs/src/subr.c
+++ b/contrib/cvs/src/subr.c
@@ -8,6 +8,7 @@
* Various useful functions for the CVS support code.
*/
+#include <assert.h>
#include "cvs.h"
#include "getline.h"
@@ -51,7 +52,7 @@ xmalloc (bytes)
/*
* realloc data and die if it fails [I've always wanted to have "realloc" do
* a "malloc" if the argument is NULL, but you can't depend on it. Here, I
- * can *force* it.
+ * can *force* it.]
*/
void *
xrealloc (ptr, bytes)
@@ -149,61 +150,70 @@ xstrdup (str)
return (s);
}
-/* Remove trailing newlines from STRING, destructively. */
-void
+
+
+/* Remove trailing newlines from STRING, destructively.
+ *
+ * RETURNS
+ *
+ * True if any newlines were removed, false otherwise.
+ */
+int
strip_trailing_newlines (str)
- char *str;
+ char *str;
{
- int len;
- len = strlen (str) - 1;
+ size_t index, origlen;
+ index = origlen = strlen (str);
- while (str[len] == '\n')
- str[len--] = '\0';
+ while (index > 0 && str[index-1] == '\n')
+ str[--index] = '\0';
+
+ return index != origlen;
}
-/* Return the number of levels that path ascends above where it starts.
- For example:
- "../../foo" -> 2
- "foo/../../bar" -> 1
- */
-/* FIXME: Should be using ISDIRSEP, last_component, or some other
- mechanism which is more general than just looking at slashes,
- particularly for the client.c caller. The server.c caller might
- want something different, so be careful. */
+
+
+/* Return the number of levels that PATH ascends above where it starts.
+ * For example:
+ *
+ * "../../foo" -> 2
+ * "foo/../../bar" -> 1
+ */
int
-pathname_levels (path)
- char *path;
+pathname_levels (p)
+ const char *p;
{
- char *p;
- char *q;
int level;
int max_level;
+ if (p == NULL) return 0;
+
max_level = 0;
- p = path;
level = 0;
do
{
- q = strchr (p, '/');
- if (q != NULL)
- ++q;
- if (p[0] == '.' && p[1] == '.' && (p[2] == '\0' || p[2] == '/'))
+ /* Now look for pathname level-ups. */
+ if (p[0] == '.' && p[1] == '.' && (p[2] == '\0' || ISDIRSEP (p[2])))
{
--level;
if (-level > max_level)
max_level = -level;
}
- else if (p[0] == '\0' || p[0] == '/' ||
- (p[0] == '.' && (p[1] == '\0' || p[1] == '/')))
+ else if (p[0] == '\0' || ISDIRSEP (p[0]) ||
+ (p[0] == '.' && (p[1] == '\0' || ISDIRSEP (p[1]))))
;
else
++level;
- p = q;
- } while (p != NULL);
+
+ /* q = strchr (p, '/'); but sub ISDIRSEP() for '/': */
+ while (*p != '\0' && !ISDIRSEP (*p)) p++;
+ if (*p != '\0') p++;
+ } while (*p != '\0');
return max_level;
}
-
+
+
/* Free a vector, where (*ARGV)[0], (*ARGV)[1], ... (*ARGV)[*PARGC - 1]
are malloc'd and so is *ARGV itself. Such a vector is allocated by
line2argv or expand_wild, for example. */
@@ -283,13 +293,12 @@ compare_revnums (rev1, rev2)
const char *rev1;
const char *rev2;
{
- const char *s, *sp;
- const char *t, *tp;
+ const char *sp, *tp;
char *snext, *tnext;
int result = 0;
- sp = s = rev1;
- tp = t = rev2;
+ sp = rev1;
+ tp = rev2;
while (result == 0)
{
result = strtoul (sp, &snext, 10) - strtoul (tp, &tnext, 10);
@@ -393,6 +402,71 @@ get_date (date, now)
#endif
#endif
+
+
+/* Given some revision, REV, return the first prior revision that exists in the
+ * RCS file, RCS.
+ *
+ * ASSUMPTIONS
+ * REV exists.
+ *
+ * INPUTS
+ * RCS The RCS node pointer.
+ * REV An existing revision in the RCS file referred to by RCS.
+ *
+ * RETURNS
+ * The first prior revision that exists in the RCS file, or NULL if no prior
+ * revision exists. The caller is responsible for disposing of this string.
+ *
+ * NOTES
+ * This function currently neglects the case where we are on the trunk with
+ * rev = X.1, where X != 1. If rev = X.Y, where X != 1 and Y > 1, then this
+ * function should work fine, as revision X.1 must exist, due to RCS rules.
+ */
+char *
+previous_rev (rcs, rev)
+ RCSNode *rcs;
+ const char *rev;
+{
+ char *p;
+ char *tmp = xstrdup (rev);
+ long r1;
+ char *retval;
+
+ /* Our retval can have no more digits and dots than our input revision. */
+ retval = xmalloc (strlen (rev) + 1);
+ p = strrchr (tmp, '.');
+ *p = '\0';
+ r1 = strtol (p+1, NULL, 10);
+ do {
+ if (--r1 == 0)
+ {
+ /* If r1 == 0, then we must be on a branch and our parent must
+ * exist, or we must be on the trunk with a REV like X.1.
+ * We are neglecting the X.1 with X != 1 case by assuming that
+ * there is no previous revision when we discover we were on
+ * the trunk.
+ */
+ p = strrchr (tmp, '.');
+ if (p == NULL)
+ /* We are on the trunk. */
+ retval = NULL;
+ else
+ {
+ *p = '\0';
+ sprintf (retval, "%s", tmp);
+ }
+ break;
+ }
+ sprintf (retval, "%s.%ld", tmp, r1);
+ } while (!RCS_exist_rev (rcs, retval));
+
+ free (tmp);
+ return retval;
+}
+
+
+
/* Given two revisions, find their greatest common ancestor. If the
two input revisions exist, then rcs guarantees that the gca will
exist. */
@@ -518,9 +592,10 @@ check_numeric (rev, argc, argv)
*/
char *
make_message_rcslegal (message)
- char *message;
+ const char *message;
{
- char *dst, *dp, *mp;
+ char *dst, *dp;
+ const char *mp;
if (message == NULL) message = "";
@@ -553,6 +628,61 @@ make_message_rcslegal (message)
return dst;
}
+
+
+/*
+ * 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
@@ -695,19 +825,18 @@ void
resolve_symlink (filename)
char **filename;
{
- if ((! filename) || (! *filename))
+ if (filename == NULL || *filename == NULL)
return;
while (islink (*filename))
{
- char *newname;
#ifdef HAVE_READLINK
/* The clean thing to do is probably to have each filesubr.c
implement this (with an error if not supported by the
platform, in which case islink would presumably return 0).
But that would require editing each filesubr.c and so the
expedient hack seems to be looking at HAVE_READLINK. */
- newname = xreadlink (*filename);
+ char *newname = xreadlink (*filename);
if (isabsolute (newname))
{
@@ -716,7 +845,7 @@ resolve_symlink (filename)
}
else
{
- char *oldname = last_component (*filename);
+ const char *oldname = last_component (*filename);
int dirlen = oldname - *filename;
char *fullnewname = xmalloc (dirlen + strlen (newname) + 1);
strncpy (fullnewname, *filename, dirlen);
@@ -797,6 +926,8 @@ shell_escape(buf, str)
return buf;
}
+
+
/*
* We can only travel forwards in time, not backwards. :)
*/
@@ -849,7 +980,8 @@ sleep_past (desttime)
struct timeval tv;
tv.tv_sec = s;
tv.tv_usec = us;
- (void)select (0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL, &tv);
+ (void)select (0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL,
+ &tv);
}
#else
if (us > 0) s++;
@@ -857,3 +989,14 @@ sleep_past (desttime)
#endif
}
}
+
+
+
+/* Return non-zero iff FILENAME is absolute.
+ Trivial under Unix, but more complicated under other systems. */
+int
+isabsolute (filename)
+ const char *filename;
+{
+ return ISABSOLUTE (filename);
+}
diff --git a/contrib/cvs/src/tag.c b/contrib/cvs/src/tag.c
index 73c241e..ab4992f 100644
--- a/contrib/cvs/src/tag.c
+++ b/contrib/cvs/src/tag.c
@@ -20,16 +20,17 @@ static int rtag_proc PROTO((int argc, char **argv, char *xwhere,
int local_specified, char *mname, char *msg));
static int check_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static int check_filesdoneproc PROTO ((void *callerdat, int err,
- char *repos, char *update_dir,
- List *entries));
-static int pretag_proc PROTO((char *repository, char *filter));
+ const char *repos,
+ const char *update_dir,
+ List *entries));
+static int pretag_proc PROTO((const char *repository, const char *filter));
static void masterlist_delproc PROTO((Node *p));
static void tag_delproc PROTO((Node *p));
static int pretag_list_proc PROTO((Node *p, void *closure));
-static Dtype tag_dirproc PROTO ((void *callerdat, char *dir,
- char *repos, char *update_dir,
- List *entries));
+static Dtype tag_dirproc PROTO ((void *callerdat, const char *dir,
+ const char *repos, const char *update_dir,
+ List *entries));
static int rtag_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static int rtag_delete PROTO((RCSNode *rcsfile));
static int tag_fileproc PROTO ((void *callerdat, struct file_info *finfo));
@@ -110,7 +111,7 @@ cvstag (argc, argv)
int err = 0;
int run_module_prog = 1;
- is_rtag = (strcmp (command_name, "rtag") == 0);
+ is_rtag = (strcmp (cvs_cmd_name, "rtag") == 0);
if (argc == -1)
usage (is_rtag ? rtag_usage : tag_usage);
@@ -156,7 +157,7 @@ cvstag (argc, argv)
#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
- command_name);
+ cvs_cmd_name);
break;
case 'R':
local = 0;
@@ -353,14 +354,12 @@ rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
free (repository);
return (1);
}
- free (repository);
/* End section which is identical to patch_proc. */
if (delete_flag || attic_too || (force_tag_match && numtag))
which = W_REPOS | W_ATTIC;
else
which = W_REPOS;
- repository = NULL;
}
else
{
@@ -382,7 +381,7 @@ rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
err = start_recursion (check_fileproc, check_filesdoneproc,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
argc - 1, argv + 1, local_specified, which, 0,
- CVS_LOCK_READ, where, 1);
+ CVS_LOCK_READ, where, 1, repository);
if (err)
{
@@ -397,7 +396,9 @@ rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
err = start_recursion (is_rtag ? rtag_fileproc : tag_fileproc,
(FILESDONEPROC) NULL, tag_dirproc,
(DIRLEAVEPROC) NULL, NULL, argc - 1, argv + 1,
- local_specified, which, 0, CVS_LOCK_WRITE, where, 1);
+ local_specified, which, 0, CVS_LOCK_WRITE, where, 1,
+ repository);
+ if ( which & W_REPOS ) free ( repository );
dellist (&mtlist);
if (where != NULL)
free (where);
@@ -412,7 +413,7 @@ check_fileproc (callerdat, finfo)
void *callerdat;
struct file_info *finfo;
{
- char *xdir;
+ const char *xdir;
Node *p;
Vers_TS *vers;
@@ -460,7 +461,7 @@ check_fileproc (callerdat, finfo)
ml = (struct master_lists *)
xmalloc (sizeof (struct master_lists));
ml->tlist = tlist;
- p->data = (char *) ml;
+ p->data = ml;
p->delproc = masterlist_delproc;
(void) addnode (mtlist, p);
}
@@ -536,8 +537,8 @@ static int
check_filesdoneproc (callerdat, err, repos, update_dir, entries)
void *callerdat;
int err;
- char *repos;
- char *update_dir;
+ const char *repos;
+ const char *update_dir;
List *entries;
{
int n;
@@ -565,9 +566,9 @@ check_filesdoneproc (callerdat, err, repos, update_dir, entries)
}
static int
-pretag_proc(repository, filter)
- char *repository;
- char *filter;
+pretag_proc (repository, filter)
+ const char *repository;
+ const char *filter;
{
if (filter[0] == '/')
{
@@ -602,9 +603,8 @@ static void
masterlist_delproc(p)
Node *p;
{
- struct master_lists *ml;
+ struct master_lists *ml = p->data;
- ml = (struct master_lists *)p->data;
dellist(&ml->tlist);
free(ml);
return;
@@ -866,6 +866,7 @@ tag_fileproc (callerdat, finfo)
char *rev;
Vers_TS *vers;
int retcode = 0;
+ int retval = 0;
vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
@@ -877,10 +878,7 @@ tag_fileproc (callerdat, finfo)
force_tag_match,
(int *) NULL);
if (nversion == NULL)
- {
- freevers_ts (&vers);
- return (0);
- }
+ goto free_vars_and_return;
}
if (delete_flag)
{
@@ -898,10 +896,8 @@ tag_fileproc (callerdat, finfo)
version = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1,
(int *) NULL);
if (version == NULL || vers->srcfile == NULL)
- {
- freevers_ts (&vers);
- return (0);
- }
+ goto free_vars_and_return;
+
free (version);
isbranch = RCS_nodeisbranch (finfo->rcs, symtag);
@@ -914,8 +910,8 @@ tag_fileproc (callerdat, finfo)
isbranch ? "branch" : "non-branch",
symtag, vers->srcfile->path,
isbranch ? "" : " due to `-B' option");
- freevers_ts (&vers);
- return (1);
+ retval = 1;
+ goto free_vars_and_return;
}
if ((retcode = RCS_deltag(vers->srcfile, symtag)) != 0)
@@ -924,8 +920,8 @@ tag_fileproc (callerdat, finfo)
error (0, retcode == -1 ? errno : 0,
"failed to remove tag %s from %s", symtag,
vers->srcfile->path);
- freevers_ts (&vers);
- return (1);
+ retval = 1;
+ goto free_vars_and_return;
}
RCS_rewrite (vers->srcfile, NULL, NULL);
@@ -937,8 +933,7 @@ tag_fileproc (callerdat, finfo)
cvs_output ("\n", 1);
}
- freevers_ts (&vers);
- return (0);
+ goto free_vars_and_return;
}
/*
@@ -955,29 +950,25 @@ tag_fileproc (callerdat, finfo)
}
if (version == NULL)
{
- freevers_ts (&vers);
- return (0);
+ goto free_vars_and_return;
}
else if (strcmp (version, "0") == 0)
{
if (!quiet)
error (0, 0, "couldn't tag added but un-commited file `%s'", finfo->file);
- freevers_ts (&vers);
- return (0);
+ goto free_vars_and_return;
}
else if (version[0] == '-')
{
if (!quiet)
error (0, 0, "skipping removed but un-commited file `%s'", finfo->file);
- freevers_ts (&vers);
- return (0);
+ goto free_vars_and_return;
}
else if (vers->srcfile == NULL)
{
if (!quiet)
error (0, 0, "cannot find revision control file for `%s'", finfo->file);
- freevers_ts (&vers);
- return (0);
+ goto free_vars_and_return;
}
/*
@@ -1004,8 +995,7 @@ tag_fileproc (callerdat, finfo)
free (oversion);
if (branch_mode)
free (rev);
- freevers_ts (&vers);
- return (0);
+ goto free_vars_and_return;
}
if (!force_tag_move)
@@ -1027,8 +1017,7 @@ tag_fileproc (callerdat, finfo)
free (oversion);
if (branch_mode)
free (rev);
- freevers_ts (&vers);
- return (0);
+ goto free_vars_and_return;
}
else /* force_tag_move == 1 and... */
if ((isbranch && !disturb_branch_tags) ||
@@ -1040,9 +1029,9 @@ tag_fileproc (callerdat, finfo)
symtag, oversion, rev,
isbranch ? "" : " due to `-B' option");
free (oversion);
- if (branch_mode) free(rev);
- freevers_ts (&vers);
- return (0);
+ if (branch_mode)
+ free (rev);
+ goto free_vars_and_return;
}
free (oversion);
}
@@ -1054,8 +1043,8 @@ tag_fileproc (callerdat, finfo)
symtag, rev, vers->srcfile->path);
if (branch_mode)
free (rev);
- freevers_ts (&vers);
- return (1);
+ retval = 1;
+ goto free_vars_and_return;
}
if (branch_mode)
free (rev);
@@ -1069,12 +1058,11 @@ tag_fileproc (callerdat, finfo)
cvs_output ("\n", 1);
}
+ free_vars_and_return:
if (nversion != NULL)
- {
free (nversion);
- }
freevers_ts (&vers);
- return (0);
+ return (retval);
}
/*
@@ -1084,9 +1072,9 @@ tag_fileproc (callerdat, finfo)
static Dtype
tag_dirproc (callerdat, dir, repos, update_dir, entries)
void *callerdat;
- char *dir;
- char *repos;
- char *update_dir;
+ const char *dir;
+ const char *repos;
+ const char *update_dir;
List *entries;
{
@@ -1142,14 +1130,17 @@ val_fileproc (callerdat, finfo)
return 0;
}
-static Dtype val_direntproc PROTO ((void *, char *, char *, char *, List *));
+
+
+static Dtype val_direntproc PROTO ((void *, const char *, const char *,
+ const char *, List *));
static Dtype
val_direntproc (callerdat, dir, repository, update_dir, entries)
void *callerdat;
- char *dir;
- char *repository;
- char *update_dir;
+ const char *dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
/* This is not quite right--it doesn't get right the case of "cvs
@@ -1184,7 +1175,6 @@ tag_check_valid (name, argc, argv, local, aflag, repository)
{
DBM *db;
char *valtags_filename;
- int err;
int nowrite = 0;
datum mytag;
struct val_args the_val_args;
@@ -1276,16 +1266,16 @@ Numeric tag %s contains characters other than digits and '.'", name);
{
if (save_cwd (&cwd))
error_exit ();
- if ( CVS_CHDIR (repository) < 0)
+ if (CVS_CHDIR (repository) < 0)
error (1, errno, "cannot change to %s directory", repository);
}
}
- err = start_recursion (val_fileproc, (FILESDONEPROC) NULL,
- val_direntproc, (DIRLEAVEPROC) NULL,
- (void *)&the_val_args,
- argc, argv, local, which, aflag,
- CVS_LOCK_READ, NULL, 1);
+ start_recursion (val_fileproc, (FILESDONEPROC) NULL,
+ val_direntproc, (DIRLEAVEPROC) NULL,
+ (void *)&the_val_args,
+ argc, argv, local, which, aflag,
+ CVS_LOCK_READ, NULL, 1, repository);
if (repository != NULL && repository[0] != '\0')
{
if (restore_cwd (&cwd, NULL))
@@ -1313,7 +1303,7 @@ Numeric tag %s contains characters other than digits and '.'", name);
mode_t omask;
omask = umask (cvsumask);
db = dbm_open (valtags_filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
- (void) umask (omask);
+ (void)umask (omask);
if (db == NULL)
{
diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c
index b7c21eb..e245e7b 100644
--- a/contrib/cvs/src/update.c
+++ b/contrib/cvs/src/update.c
@@ -49,30 +49,29 @@ static int checkout_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts,
int adding, int merging, int update_server));
#ifdef SERVER_SUPPORT
static void checkout_to_buffer PROTO ((void *, const char *, size_t));
-#endif
-#ifdef SERVER_SUPPORT
static int patch_file PROTO ((struct file_info *finfo,
Vers_TS *vers_ts,
int *docheckout, struct stat *file_info,
unsigned char *checksum));
static void patch_file_write PROTO ((void *, const char *, size_t));
-#endif
+#endif /* SERVER_SUPPORT */
static int merge_file PROTO ((struct file_info *finfo, Vers_TS *vers));
static int scratch_file PROTO((struct file_info *finfo, Vers_TS *vers));
-static Dtype update_dirent_proc PROTO ((void *callerdat, char *dir,
- char *repository, char *update_dir,
- List *entries));
-static int update_dirleave_proc PROTO ((void *callerdat, char *dir,
- int err, char *update_dir,
+static Dtype update_dirent_proc PROTO ((void *callerdat, const char *dir,
+ const char *repository,
+ const char *update_dir,
+ List *entries));
+static int update_dirleave_proc PROTO ((void *callerdat, const char *dir,
+ int err, const char *update_dir,
List *entries));
static int update_fileproc PROTO ((void *callerdat, struct file_info *));
static int update_filesdone_proc PROTO ((void *callerdat, int err,
- char *repository, char *update_dir,
- List *entries));
+ const char *repository,
+ const char *update_dir,
+ List *entries));
#ifdef PRESERVE_PERMISSIONS_SUPPORT
static int get_linkinfo_proc PROTO ((void *callerdat, struct file_info *));
#endif
-static void write_letter PROTO ((struct file_info *finfo, int letter));
static void join_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts));
static char *options = NULL;
@@ -184,7 +183,7 @@ update (argc, argv)
#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
- command_name);
+ cvs_cmd_name);
break;
case 'd':
update_build_dirs = 1;
@@ -414,7 +413,8 @@ update (argc, argv)
/* call the command line interface */
err = do_update (argc, argv, options, tag, date, force_tag_match,
local, update_build_dirs, aflag, update_prune_dirs,
- pipeout, which, join_rev1, join_rev2, (char *) NULL, 1);
+ pipeout, which, join_rev1, join_rev2, (char *) NULL, 1,
+ (char *) NULL);
/* free the space Make_Date allocated if necessary */
if (date != NULL)
@@ -429,7 +429,7 @@ update (argc, argv)
int
do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir,
- xdotemplate)
+ xdotemplate, repository)
int argc;
char **argv;
char *xoptions;
@@ -446,6 +446,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
char *xjoin_rev2;
char *preload_update_dir;
int xdotemplate;
+ char *repository;
{
int err = 0;
char *cp;
@@ -493,7 +494,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
err = start_recursion (get_linkinfo_proc, (FILESDONEPROC) NULL,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
argc, argv, local, which, aflag, CVS_LOCK_READ,
- preload_update_dir, 1);
+ preload_update_dir, 1, (char *) NULL);
if (err)
return (err);
@@ -509,7 +510,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
err = start_recursion (update_fileproc, update_filesdone_proc,
update_dirent_proc, update_dirleave_proc, NULL,
argc, argv, local, which, aflag, CVS_LOCK_READ,
- preload_update_dir, 1);
+ preload_update_dir, 1, repository);
#ifdef SERVER_SUPPORT
if (server_active)
@@ -562,12 +563,14 @@ get_linkinfo_proc (callerdat, finfo)
hlinfo->status = (Ctype) 0; /* is this dumb? */
hlinfo->checked_out = 0;
- linkp->data = (char *) hlinfo;
+ linkp->data = hlinfo;
return 0;
}
#endif
+
+
/*
* This is the callback proc for update. It is called for each file in each
* directory by the recursion code. The current directory is the local
@@ -690,38 +693,8 @@ update_fileproc (callerdat, finfo)
{
if (vers->ts_conflict)
{
- char *filestamp;
- int retcode;
-
- /*
- * If the timestamp has changed and no
- * conflict indicators are found, it isn't a
- * 'C' any more.
- */
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- retcode = vers->ts_conflict[0] != '=';
- else
- {
- filestamp = time_stamp (finfo->file);
- retcode = strcmp (vers->ts_conflict, filestamp);
- free (filestamp);
- }
-#else
- filestamp = time_stamp (finfo->file);
- retcode = strcmp (vers->ts_conflict, filestamp);
- free (filestamp);
-#endif
-
- if (retcode)
- {
- /* The timestamps differ. But if there
- are conflict markers print 'C' anyway. */
- retcode = !file_has_markers (finfo);
- }
-
- if (!retcode)
+ if (file_has_conflict (finfo, vers->ts_conflict)
+ || file_has_markers (finfo))
{
write_letter (finfo, 'C');
retval = 1;
@@ -736,10 +709,7 @@ update_fileproc (callerdat, finfo)
}
}
if (!retval)
- {
write_letter (finfo, 'M');
- retval = 0;
- }
}
break;
case T_PATCH: /* needs patch */
@@ -809,42 +779,48 @@ update_fileproc (callerdat, finfo)
}
freevers_ts (&vers);
- return (retval);
+ return retval;
}
-static void update_ignproc PROTO ((char *, char *));
+
+
+static void update_ignproc PROTO ((const char *, const char *));
static void
update_ignproc (file, dir)
- char *file;
- char *dir;
+ const char *file;
+ const char *dir;
{
struct file_info finfo;
+ char *tmp;
memset (&finfo, 0, sizeof (finfo));
finfo.file = file;
finfo.update_dir = dir;
if (dir[0] == '\0')
- finfo.fullname = xstrdup (file);
+ tmp = xstrdup (file);
else
{
- finfo.fullname = xmalloc (strlen (file) + strlen (dir) + 10);
- strcpy (finfo.fullname, dir);
- strcat (finfo.fullname, "/");
- strcat (finfo.fullname, file);
+ tmp = xmalloc (strlen (file) + strlen (dir) + 10);
+ strcpy (tmp, dir);
+ strcat (tmp, "/");
+ strcat (tmp, file);
}
+ finfo.fullname = tmp;
write_letter (&finfo, '?');
- free (finfo.fullname);
+ free (tmp);
}
+
+
/* ARGSUSED */
static int
update_filesdone_proc (callerdat, err, repository, update_dir, entries)
void *callerdat;
int err;
- char *repository;
- char *update_dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
if (rewrite_tag)
@@ -861,7 +837,7 @@ update_filesdone_proc (callerdat, err, repository, update_dir, entries)
}
/* Clean up CVS admin dirs if we are export */
- if (strcmp (command_name, "export") == 0)
+ if (strcmp (cvs_cmd_name, "export") == 0)
{
/* I'm not sure the existence_error is actually possible (except
in cases where we really should print a message), but since
@@ -883,6 +859,8 @@ update_filesdone_proc (callerdat, err, repository, update_dir, entries)
return (err);
}
+
+
/*
* update_dirent_proc () is called back by the recursion processor before a
* sub-directory is processed for update. In this case, update_dirent proc
@@ -894,9 +872,9 @@ update_filesdone_proc (callerdat, err, repository, update_dir, entries)
static Dtype
update_dirent_proc (callerdat, dir, repository, update_dir, entries)
void *callerdat;
- char *dir;
- char *repository;
- char *update_dir;
+ const char *dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
if (ignore_directory (update_dir))
@@ -1040,6 +1018,8 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
return (R_PROCESS);
}
+
+
/*
* update_dirleave_proc () is called back by the recursion code upon leaving
* a directory. It will prune empty directories if needed and will execute
@@ -1049,13 +1029,11 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
static int
update_dirleave_proc (callerdat, dir, err, update_dir, entries)
void *callerdat;
- char *dir;
+ const char *dir;
int err;
- char *update_dir;
+ const char *update_dir;
List *entries;
{
- FILE *fp;
-
/* Delete the ignore list if it hasn't already been done. */
if (ignlist)
dellist (&ignlist);
@@ -1081,45 +1059,6 @@ update_dirleave_proc (callerdat, dir, err, update_dir, entries)
tag_update_dir = NULL;
}
- /* run the update_prog if there is one */
- /* FIXME: should be checking for errors from CVS_FOPEN and printing
- them if not existence_error. */
- if (err == 0 && !pipeout && !noexec &&
- (fp = CVS_FOPEN (CVSADM_UPROG, "r")) != NULL)
- {
- char *cp;
- char *repository;
- char *line = NULL;
- size_t line_allocated = 0;
-
- repository = Name_Repository ((char *) NULL, update_dir);
- if (getline (&line, &line_allocated, fp) >= 0)
- {
- if ((cp = strrchr (line, '\n')) != NULL)
- *cp = '\0';
- run_setup (line);
- run_arg (repository);
- cvs_output (program_name, 0);
- cvs_output (" ", 1);
- cvs_output (command_name, 0);
- cvs_output (": Executing '", 0);
- run_print (stdout);
- cvs_output ("'\n", 0);
- cvs_flushout ();
- (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- }
- else if (ferror (fp))
- error (0, errno, "cannot read %s", CVSADM_UPROG);
- else
- error (0, 0, "unexpected end of file on %s", CVSADM_UPROG);
-
- if (fclose (fp) < 0)
- error (0, errno, "cannot close %s", CVSADM_UPROG);
- if (line != NULL)
- free (line);
- free (repository);
- }
-
if (strchr (dir, '/') == NULL)
{
/* FIXME: chdir ("..") loses with symlinks. */
@@ -1147,7 +1086,7 @@ isremoved (node, closure)
Node *node;
void *closure;
{
- Entnode *entdata = (Entnode*) node->data;
+ Entnode *entdata = node->data;
/* If the first character of the version is a '-', the file has been
removed. */
@@ -1159,7 +1098,7 @@ isremoved (node, closure)
and the directory doesn't exist, then just return 0. */
int
isemptydir (dir, might_not_exist)
- char *dir;
+ const char *dir;
int might_not_exist;
{
DIR *dirp;
@@ -1363,7 +1302,7 @@ VERS: ", 0);
{
revbuf = buf_nonio_initialize ((BUFMEMERRPROC) NULL);
status = RCS_checkout (vers_ts->srcfile, (char *) NULL,
- vers_ts->vn_rcs, vers_ts->vn_tag,
+ vers_ts->vn_rcs, vers_ts->tag,
vers_ts->options, RUN_TTY,
checkout_to_buffer, revbuf);
}
@@ -1371,7 +1310,7 @@ VERS: ", 0);
#endif
status = RCS_checkout (vers_ts->srcfile,
pipeout ? NULL : finfo->file,
- vers_ts->vn_rcs, vers_ts->vn_tag,
+ vers_ts->vn_rcs, vers_ts->tag,
vers_ts->options, RUN_TTY,
(RCSCHECKOUTPROC) NULL, (void *) NULL);
}
@@ -1394,8 +1333,11 @@ VERS: ", 0);
is here only because noexec doesn't write srcfile->path
for us to stat. */
if (stat (vers_ts->srcfile->path, &sb) < 0)
+ {
+ buf_free (revbuf);
error (1, errno, "cannot stat %s",
vers_ts->srcfile->path);
+ }
mode = sb.st_mode &~ (S_IWRITE | S_IWGRP | S_IWOTH);
}
@@ -1501,6 +1443,8 @@ VERS: ", 0);
/* fix up the vers structure, in case it is used by join */
if (join_rev1)
{
+ /* FIXME: Throwing away the original revision info is almost
+ certainly wrong -- what if join_rev1 is "BASE"? */
if (vers_ts->vn_user != NULL)
free (vers_ts->vn_user);
if (vers_ts->vn_rcs != NULL)
@@ -1510,7 +1454,7 @@ VERS: ", 0);
}
/* If this is really Update and not Checkout, recode history */
- if (strcmp (command_name, "update") == 0)
+ if (strcmp (cvs_cmd_name, "update") == 0)
history_write ('U', finfo->update_dir, xvers_ts->vn_rcs, finfo->file,
finfo->repository);
@@ -1557,6 +1501,8 @@ VERS: ", 0);
free (backup);
}
+ if (revbuf != NULL)
+ buf_free (revbuf);
return (retval);
}
@@ -1703,8 +1649,20 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
data.final_nl = 0;
data.compute_checksum = 0;
+ /* FIXME - Passing vers_ts->tag here is wrong in the least number
+ * of cases. Since we don't know whether vn_user was checked out
+ * using a tag, we pass vers_ts->tag, which, assuming the user did
+ * not specify a new TAG to -r, will be the branch we are on.
+ *
+ * The only thing it is used for is to substitute in for the Name
+ * RCS keyword, so in the error case, the patch fails to apply on
+ * the client end and we end up resending the whole file.
+ *
+ * At least, if we are keeping track of the tag vn_user came from,
+ * I don't know where yet. -DRP
+ */
retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
- vers_ts->vn_user, (char *) NULL,
+ vers_ts->vn_user, vers_ts->tag,
vers_ts->options, RUN_TTY,
patch_file_write, (void *) &data);
@@ -1727,7 +1685,7 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
cvs_MD5Init (&data.context);
retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
- vers_ts->vn_rcs, vers_ts->vn_tag,
+ vers_ts->vn_rcs, vers_ts->tag,
vers_ts->options, RUN_TTY,
patch_file_write, (void *) &data);
@@ -1849,10 +1807,10 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
if (CVS_STAT (finfo->file, file_info) < 0)
error (1, errno, "could not stat %s", finfo->file);
- /* If this is really Update and not Checkout, recode history */
- if (strcmp (command_name, "update") == 0)
- history_write ('P', finfo->update_dir, xvers_ts->vn_rcs, finfo->file,
- finfo->repository);
+ /* If this is really Update and not Checkout, record history. */
+ if (strcmp (cvs_cmd_name, "update") == 0)
+ history_write ('P', finfo->update_dir, xvers_ts->vn_rcs,
+ finfo->file, finfo->repository);
freevers_ts (&xvers_ts);
@@ -1919,7 +1877,7 @@ patch_file_write (callerdat, buffer, len)
* Several of the types we process only print a bit of information consisting
* of a single letter and the name.
*/
-static void
+void
write_letter (finfo, letter)
struct file_info *finfo;
int letter;
@@ -1960,6 +1918,8 @@ write_letter (finfo, letter)
return;
}
+
+
/*
* Do all the magic associated with a file which needs to be merged
*/
@@ -2034,8 +1994,8 @@ merge_file (finfo, vers)
goto out;
}
- status = RCS_merge(finfo->rcs, vers->srcfile->path, finfo->file,
- vers->options, vers->vn_user, vers->vn_rcs);
+ status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file,
+ vers->options, vers->vn_user, vers->vn_rcs);
if (status != 0 && status != 1)
{
error (0, status == -1 ? errno : 0,
@@ -2071,6 +2031,8 @@ merge_file (finfo, vers)
/* fix up the vers structure, in case it is used by join */
if (join_rev1)
{
+ /* FIXME: Throwing away the original revision info is almost
+ certainly wrong -- what if join_rev1 is "BASE"? */
if (vers->vn_user != NULL)
free (vers->vn_user);
vers->vn_user = xstrdup (vers->vn_rcs);
@@ -2113,7 +2075,8 @@ merge_file (finfo, vers)
write_letter (finfo, 'C');
- history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file, finfo->repository);
+ history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file,
+ finfo->repository);
}
else if (retcode == -1)
@@ -2133,9 +2096,23 @@ merge_file (finfo, vers)
return retval;
}
+
+
/*
* Do all the magic associated with a file which needs to be joined
- * (-j option)
+ * (reached via the -j option to checkout or update).
+ *
+ * INPUTS
+ * finfo File information about the destination file.
+ * vers The Vers_TS structure for finfo.
+ *
+ * GLOBALS
+ * join_rev1 From the command line.
+ * join_rev2 From the command line.
+ * server_active Natch.
+ *
+ * ASSUMPTIONS
+ * 1. Is not called in client mode.
*/
static void
join_file (finfo, vers)
@@ -2186,6 +2163,9 @@ join_file (finfo, vers)
jdate1 = NULL;
}
+ /* FIXME: Need to handle "BASE" for jrev1 and/or jrev2. Note caveat
+ below about vn_user. */
+
/* Convert the second revision, walking branches and dates. */
rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1, (int *) NULL);
@@ -2367,13 +2347,41 @@ join_file (finfo, vers)
return;
}
- /* If the target of the merge is the same as the working file
- revision, then there is nothing to do. */
- if (vers->vn_user != NULL && strcmp (rev2, vers->vn_user) == 0)
+ /* If the two merge revisions are the same, then there is nothing
+ * to do. This needs to be checked before the rev2 == up-to-date base
+ * revision check tha comes next. Otherwise, rev1 can == rev2 and get an
+ * "already contains the changes between <rev1> and <rev1>" message.
+ */
+ if (rev1 && strcmp (rev1, rev2) == 0)
+ {
+ free (rev1);
+ free (rev2);
+ return;
+ }
+
+ /* If we know that the user file is up-to-date, then it becomes an
+ * optimization to skip the merge when rev2 is the same as the base
+ * revision. i.e. we know that diff3(file2,file1,file2) will produce
+ * file2.
+ */
+ if (vers->vn_user != NULL && vers->ts_user != NULL
+ && strcmp (vers->ts_user, vers->ts_rcs) == 0
+ && strcmp (rev2, vers->vn_user) == 0)
{
+ if (!really_quiet)
+ {
+ cvs_output (finfo->fullname, 0);
+ cvs_output (" already contains the differences between ", 0);
+ cvs_output (rev1 ? rev1 : "creation", 0);
+ cvs_output (" and ", 0);
+ cvs_output (rev2, 0);
+ cvs_output ("\n", 1);
+ }
+
if (rev1 != NULL)
free (rev1);
free (rev2);
+
return;
}
@@ -2428,17 +2436,8 @@ join_file (finfo, vers)
return;
}
- /* If the two merge revisions are the same, then there is nothing
- to do. */
- if (strcmp (rev1, rev2) == 0)
- {
- free (rev1);
- free (rev2);
- return;
- }
-
/* If there is no working file, then we can't do the merge. */
- if (vers->vn_user == NULL)
+ if (vers->vn_user == NULL || vers->vn_user[0] == '-')
{
free (rev1);
free (rev2);
@@ -2462,8 +2461,11 @@ join_file (finfo, vers)
{
int retcode;
/* The file is up to date. Need to check out the current contents. */
+ /* FIXME - see the FIXME comment above the call to RCS_checkout in the
+ * patch_file function.
+ */
retcode = RCS_checkout (vers->srcfile, finfo->file,
- vers->vn_user, (char *) NULL,
+ vers->vn_user, vers->tag,
(char *) NULL, RUN_TTY,
(RCSCHECKOUTPROC) NULL, (void *) NULL);
if (retcode != 0)
@@ -2509,16 +2511,29 @@ join_file (finfo, vers)
&& vers->ts_user != NULL
&& strcmp (vers->ts_user, vers->ts_rcs) == 0
- /* This is because of the worry below about $Name. If that
- isn't a problem, I suspect this code probably works for
- text files too. */
+ /* Avoid this in the text file case. See below for why.
+ */
&& (strcmp (t_options, "-kb") == 0
|| wrap_merge_is_copy (finfo->file)))
{
- /* FIXME: what about nametag? What does RCS_merge do with
- $Name? */
- if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, t_options,
- RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0)
+ /* FIXME: Verify my comment below:
+ *
+ * RCS_merge does nothing with keywords. It merges the changes between
+ * two revisions without expanding the keywords (it might expand in
+ * -kk mode before computing the diff between rev1 and rev2 - I'm not
+ * sure). In other words, the keyword lines in the current work file
+ * get left alone.
+ *
+ * Therfore, checking out the destination revision (rev2) is probably
+ * incorrect in the text case since we should see the keywords that were
+ * substituted into the original file at the time it was checked out
+ * and not the keywords from rev2.
+ *
+ * Also, it is safe to pass in NULL for nametag since we know no
+ * substitution is happening during the binary mode checkout.
+ */
+ if (RCS_checkout ( finfo->rcs, finfo->file, rev2, (char *)NULL, t_options,
+ RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0 )
status = 2;
else
status = 0;
@@ -2546,13 +2561,14 @@ join_file (finfo, vers)
|| special_file_mismatch (finfo, rev1, rev2))
{
/* We are dealing with binary files, or files with a
- permission/linkage mismatch, and real merging would
+ permission/linkage mismatch (this second case only occurs when
+ PRESERVE_PERMISSIONS_SUPPORT is enabled), and real merging would
need to take place. This is a conflict. We give the user
the two files, and let them resolve it. It is possible
that we should require a "touch foo" or similar step before
we allow a checkin. */
- if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, t_options,
- RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0)
+ if (RCS_checkout ( finfo->rcs, finfo->file, rev2, (char *)NULL,
+ t_options, RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0)
status = 2;
else
status = 0;
@@ -2584,16 +2600,39 @@ join_file (finfo, vers)
status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file,
t_options, rev1, rev2);
- if (status != 0 && status != 1)
+ if (status != 0)
{
- error (0, status == -1 ? errno : 0,
- "could not merge revision %s of %s", rev2, finfo->fullname);
- error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
- finfo->fullname, backup);
- rename_file (backup, finfo->file);
+ if (status != 1)
+ {
+ error (0, status == -1 ? errno : 0,
+ "could not merge revision %s of %s", rev2, finfo->fullname);
+ error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
+ finfo->fullname, backup);
+ rename_file (backup, finfo->file);
+ }
+ }
+ else /* status == 0 */
+ {
+ /* FIXME: the noexec case is broken. RCS_merge could be doing the
+ xcmp on the temporary files without much hassle, I think. */
+ if (!noexec && !xcmp (backup, finfo->file))
+ {
+ if (!really_quiet)
+ {
+ cvs_output (finfo->fullname, 0);
+ cvs_output (" already contains the differences between ", 0);
+ cvs_output (rev1, 0);
+ cvs_output (" and ", 0);
+ cvs_output (rev2, 0);
+ cvs_output ("\n", 1);
+ }
+
+ /* and skip the registering and sending the new file since it
+ * hasn't been updated.
+ */
+ goto out;
+ }
}
- free (rev1);
- free (rev2);
/* The file has changed, but if we just checked it out it may
still have the same timestamp it did when it was first
@@ -2630,9 +2669,15 @@ join_file (finfo, vers)
(struct buffer *) NULL);
}
#endif
+
+out:
+ free (rev1);
+ free (rev2);
free (backup);
}
+
+
/*
* Report whether revisions REV1 and REV2 of FINFO agree on:
* . file ownership
@@ -2712,7 +2757,7 @@ special_file_mismatch (finfo, rev1, rev2)
else
{
n = findnode (finfo->rcs->versions, rev1);
- vp = (RCSVers *) n->data;
+ vp = n->data;
n = findnode (vp->other_delta, "symlink");
if (n != NULL)
@@ -2747,7 +2792,7 @@ special_file_mismatch (finfo, rev1, rev2)
if (sscanf (n->data, "%15s %lu", ftype,
&dev_long) < 2)
error (1, 0, "%s:%s has bad `special' newphrase %s",
- finfo->file, rev1, n->data);
+ finfo->file, rev1, (char *)n->data);
rev1_dev = dev_long;
if (strcmp (ftype, "character") == 0)
rev1_mode |= S_IFCHR;
@@ -2790,7 +2835,7 @@ special_file_mismatch (finfo, rev1, rev2)
else
{
n = findnode (finfo->rcs->versions, rev2);
- vp = (RCSVers *) n->data;
+ vp = n->data;
n = findnode (vp->other_delta, "symlink");
if (n != NULL)
@@ -2825,7 +2870,7 @@ special_file_mismatch (finfo, rev1, rev2)
if (sscanf (n->data, "%15s %lu", ftype,
&dev_long) < 2)
error (1, 0, "%s:%s has bad `special' newphrase %s",
- finfo->file, rev2, n->data);
+ finfo->file, rev2, (char *)n->data);
rev2_dev = dev_long;
if (strcmp (ftype, "character") == 0)
rev2_mode |= S_IFCHR;
diff --git a/contrib/cvs/src/update.h b/contrib/cvs/src/update.h
index 9a1fc00..8d581b1 100644
--- a/contrib/cvs/src/update.h
+++ b/contrib/cvs/src/update.h
@@ -14,6 +14,6 @@ int do_update PROTO((int argc, char *argv[], char *xoptions, char *xtag,
char *xdate, int xforce, int local, int xbuild,
int xaflag, int xprune, int xpipeout, int which,
char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir,
- int xdotemplate));
+ int xdotemplate, char *repository));
int joining PROTO((void));
-extern int isemptydir PROTO ((char *dir, int might_not_exist));
+extern int isemptydir PROTO ((const char *dir, int might_not_exist));
diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c
index 9f71218..8ad9c4e 100644
--- a/contrib/cvs/src/vers_ts.c
+++ b/contrib/cvs/src/vers_ts.c
@@ -9,9 +9,11 @@
#include "cvs.h"
#ifdef SERVER_SUPPORT
-static void time_stamp_server PROTO((char *, Vers_TS *, Entnode *));
+static void time_stamp_server PROTO((const char *, Vers_TS *, Entnode *));
#endif
+
+
/* Fill in and return a Vers_TS structure for the file FINFO. TAG and
DATE are from the command line. */
@@ -55,13 +57,13 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
else
{
p = findnode_fn (finfo->entries, finfo->file);
- sdtp = (struct stickydirtag *) finfo->entries->list->data; /* list-private */
+ sdtp = finfo->entries->list->data; /* list-private */
}
entdata = NULL;
if (p != NULL)
{
- entdata = (Entnode *) p->data;
+ entdata = p->data;
if (entdata->type == ENT_SUBDIR)
{
@@ -204,11 +206,10 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
struct utimbuf t;
memset (&t, 0, sizeof (t));
- t.modtime =
- RCS_getrevtime (rcsdata, vers_ts->vn_rcs, 0, 0);
+ t.modtime = RCS_getrevtime (rcsdata, vers_ts->vn_rcs, 0, 0);
if (t.modtime != (time_t) -1)
{
- t.actime = t.modtime;
+ (void) time (&t.actime);
#ifdef UTIME_EXPECTS_WRITABLE
if (!iswritable (finfo->file))
@@ -226,7 +227,7 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
(void) utime (finfo->file, &t);
#ifdef UTIME_EXPECTS_WRITABLE
- if (change_it_back == 1)
+ if (change_it_back)
{
xchmod (finfo->file, 0);
change_it_back = 0;
@@ -261,7 +262,7 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
static void
time_stamp_server (file, vers_ts, entdata)
- char *file;
+ const char *file;
Vers_TS *vers_ts;
Entnode *entdata;
{
@@ -327,7 +328,7 @@ time_stamp_server (file, vers_ts, entdata)
*/
char *
time_stamp (file)
- char *file;
+ const char *file;
{
struct stat sb;
char *cp;
diff --git a/contrib/cvs/src/watch.c b/contrib/cvs/src/watch.c
index 8c57ebe..58442c4 100644
--- a/contrib/cvs/src/watch.c
+++ b/contrib/cvs/src/watch.c
@@ -17,13 +17,14 @@
const char *const watch_usage[] =
{
- "Usage: %s %s [on|off|add|remove] [-lR] [-a action] [files...]\n",
+ "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\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\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",
NULL
};
@@ -32,7 +33,7 @@ static struct addremove_args the_args;
void
watch_modify_watchers (file, what)
- char *file;
+ const char *file;
struct addremove_args *what;
{
char *curattr = fileattr_get0 (file, "_watchers");
@@ -225,15 +226,17 @@ addremove_fileproc (callerdat, finfo)
return 0;
}
-static int addremove_filesdoneproc PROTO ((void *, int, char *, char *,
- List *));
+
+
+static int addremove_filesdoneproc PROTO ((void *, int, const char *,
+ const char *, List *));
static int
addremove_filesdoneproc (callerdat, err, repository, update_dir, entries)
void *callerdat;
int err;
- char *repository;
- char *update_dir;
+ const char *repository;
+ const char *update_dir;
List *entries;
{
if (the_args.setting_default)
@@ -342,7 +345,7 @@ watch_addremove (argc, argv)
err = start_recursion (addremove_fileproc, addremove_filesdoneproc,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
argc, argv, local, W_LOCAL, 0, CVS_LOCK_NONE,
- (char *)NULL, 1);
+ (char *) NULL, 1, (char *) NULL);
Lock_Cleanup ();
return err;
@@ -516,5 +519,5 @@ watchers (argc, argv)
return start_recursion (watchers_fileproc, (FILESDONEPROC) NULL,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
argc, argv, local, W_LOCAL, 0, CVS_LOCK_READ,
- (char *)NULL, 1);
+ (char *) NULL, 1, (char *) NULL);
}
diff --git a/contrib/cvs/src/watch.h b/contrib/cvs/src/watch.h
index fa34ef5..0394635 100644
--- a/contrib/cvs/src/watch.h
+++ b/contrib/cvs/src/watch.h
@@ -45,7 +45,7 @@ struct addremove_args {
/* Modify the watchers for FILE. *WHAT tells what to do to them.
If FILE is NULL, modify default args (WHAT->SETTING_DEFAULT is
not used). */
-extern void watch_modify_watchers PROTO ((char *file,
+extern void watch_modify_watchers PROTO ((const char *file,
struct addremove_args *what));
extern int watch_add PROTO ((int argc, char **argv));
diff --git a/contrib/cvs/src/wrapper.c b/contrib/cvs/src/wrapper.c
index ab0b19f..8d7a8ef 100644
--- a/contrib/cvs/src/wrapper.c
+++ b/contrib/cvs/src/wrapper.c
@@ -30,8 +30,6 @@
wildcard [option value][option value]...
where option is one of
- -f from cvs filter value: path to filter
- -t to cvs filter value: path to filter
-m update methodology value: MERGE or COPY
-k default -k rcs option to use on import or add
diff --git a/contrib/cvs/src/zlib.c b/contrib/cvs/src/zlib.c
index 00b3682..32c95e5 100644
--- a/contrib/cvs/src/zlib.c
+++ b/contrib/cvs/src/zlib.c
@@ -431,6 +431,20 @@ compress_buffer_shutdown_output (buf)
/* Here is our librarified gzip implementation. It is very minimal
but attempts to be RFC1952 compliant. */
+/* GZIP ID byte values */
+#define GZIP_ID1 31
+#define GZIP_ID2 139
+
+/* Compression methods */
+#define GZIP_CDEFLATE 8
+
+/* Flags */
+#define GZIP_FTEXT 1
+#define GZIP_FHCRC 2
+#define GZIP_FEXTRA 4
+#define GZIP_FNAME 8
+#define GZIP_FCOMMENT 16
+
/* BUF should contain SIZE bytes of gzipped data (RFC1952/RFC1951).
We are to uncompress the data and write the result to the file
descriptor FD. If something goes wrong, give a nonfatal error message
@@ -450,28 +464,78 @@ gunzip_and_write (fd, fullname, buf, size)
unsigned char outbuf[32768];
unsigned long crc;
- if (buf[0] != 31 || buf[1] != 139)
+ if (size < 10)
+ {
+ error (0, 0, "gzipped data too small - lacks complete header");
+ return 1;
+ }
+ if (buf[0] != GZIP_ID1 || buf[1] != GZIP_ID2)
{
error (0, 0, "gzipped data does not start with gzip identification");
return 1;
}
- if (buf[2] != 8)
+ if (buf[2] != GZIP_CDEFLATE)
{
error (0, 0, "only the deflate compression method is supported");
return 1;
}
/* Skip over the fixed header, and then skip any of the variable-length
- fields. */
+ fields. As we skip each field, we keep pos <= size. The checks
+ on positions and lengths are really checks for malformed or
+ incomplete gzip data. */
pos = 10;
- if (buf[3] & 4)
+ if (buf[3] & GZIP_FEXTRA)
+ {
+ if (pos + 2 >= size)
+ {
+ error (0, 0, "%s lacks proper gzip XLEN field", fullname);
+ return 1;
+ }
pos += buf[pos] + (buf[pos + 1] << 8) + 2;
- if (buf[3] & 8)
- pos += strlen ((char *) buf + pos) + 1;
- if (buf[3] & 16)
- pos += strlen ((char *) buf + pos) + 1;
- if (buf[3] & 2)
+ if (pos > size)
+ {
+ error (0, 0, "%s lacks proper gzip \"extra field\"", fullname);
+ return 1;
+ }
+
+ }
+ if (buf[3] & GZIP_FNAME)
+ {
+ unsigned char *p = memchr(buf + pos, '\0', size - pos);
+ if (p == NULL)
+ {
+ error (0, 0, "%s has bad gzip filename field", fullname);
+ return 1;
+ }
+ pos = p - buf + 1;
+ }
+ if (buf[3] & GZIP_FCOMMENT)
+ {
+ unsigned char *p = memchr(buf + pos, '\0', size - pos);
+ if (p == NULL)
+ {
+ error (0, 0, "%s has bad gzip comment field", fullname);
+ return 1;
+ }
+ pos = p - buf + 1;
+ }
+ if (buf[3] & GZIP_FHCRC)
+ {
pos += 2;
+ if (pos > size)
+ {
+ error (0, 0, "%s has bad gzip CRC16 field", fullname);
+ return 1;
+ }
+ }
+
+ /* There could be no data to decompress - check and short circuit. */
+ if (pos >= size)
+ {
+ error (0, 0, "gzip data incomplete for %s (no data)", fullname);
+ return 1;
+ }
memset (&zstr, 0, sizeof zstr);
/* Passing a negative argument tells zlib not to look for a zlib
@@ -513,19 +577,29 @@ gunzip_and_write (fd, fullname, buf, size)
if (zstatus != Z_OK)
compress_error (0, zstatus, &zstr, fullname);
- if (crc != (buf[zstr.total_in + 10]
- + (buf[zstr.total_in + 11] << 8)
- + (buf[zstr.total_in + 12] << 16)
- + (buf[zstr.total_in + 13] << 24)))
+ /* Check that there is still 8 trailer bytes remaining (CRC32
+ and ISIZE). Check total decomp. data, plus header len (pos)
+ against input buffer total size. */
+ pos += zstr.total_in;
+ if (size - pos != 8)
+ {
+ error (0, 0, "gzip data incomplete for %s (no trailer)", fullname);
+ return 1;
+ }
+
+ if (crc != ((unsigned long)buf[pos]
+ + ((unsigned long)buf[pos + 1] << 8)
+ + ((unsigned long)buf[pos + 2] << 16)
+ + ((unsigned long)buf[pos + 3] << 24)))
{
error (0, 0, "CRC error uncompressing %s", fullname);
return 1;
}
- if (zstr.total_out != (buf[zstr.total_in + 14]
- + (buf[zstr.total_in + 15] << 8)
- + (buf[zstr.total_in + 16] << 16)
- + (buf[zstr.total_in + 17] << 24)))
+ if (zstr.total_out != ((unsigned long)buf[pos + 4]
+ + ((unsigned long)buf[pos + 5] << 8)
+ + ((unsigned long)buf[pos + 6] << 16)
+ + ((unsigned long)buf[pos + 7] << 24)))
{
error (0, 0, "invalid length uncompressing %s", fullname);
return 1;
@@ -544,7 +618,7 @@ gunzip_and_write (fd, fullname, buf, size)
int
read_and_gzip (fd, fullname, buf, size, len, level)
int fd;
- char *fullname;
+ const char *fullname;
unsigned char **buf;
size_t *size;
size_t *len;
@@ -569,9 +643,9 @@ read_and_gzip (fd, fullname, buf, size, len, level)
}
*buf = newbuf;
}
- (*buf)[0] = 31;
- (*buf)[1] = 139;
- (*buf)[2] = 8;
+ (*buf)[0] = GZIP_ID1;
+ (*buf)[1] = GZIP_ID2;
+ (*buf)[2] = GZIP_CDEFLATE;
(*buf)[3] = 0;
(*buf)[4] = (*buf)[5] = (*buf)[6] = (*buf)[7] = 0;
/* Could set this based on level, but why bother? */
@@ -587,7 +661,10 @@ read_and_gzip (fd, fullname, buf, size, len, level)
compress_error (0, zstatus, &zstr, fullname);
return 1;
}
- zstr.avail_out = *size;
+
+ /* Adjust for 10-byte output header (filled in above) */
+ zstr.total_out = 10;
+ zstr.avail_out = *size - 10;
zstr.next_out = *buf + 10;
while (1)
@@ -609,8 +686,6 @@ read_and_gzip (fd, fullname, buf, size, len, level)
do
{
- size_t offset;
-
/* I don't see this documented anywhere, but deflate seems
to tend to dump core sometimes if we pass it Z_FINISH and
a small (e.g. 2147 byte) avail_out. So we insist on at
@@ -620,7 +695,8 @@ read_and_gzip (fd, fullname, buf, size, len, level)
{
unsigned char *newbuf;
- offset = zstr.next_out - *buf;
+ assert(zstr.avail_out + zstr.total_out == *size);
+ assert(zstr.next_out == *buf + zstr.total_out);
*size *= 2;
newbuf = xrealloc (*buf, *size);
if (newbuf == NULL)
@@ -629,8 +705,10 @@ read_and_gzip (fd, fullname, buf, size, len, level)
return 1;
}
*buf = newbuf;
- zstr.next_out = *buf + offset;
- zstr.avail_out = *size - offset;
+ zstr.next_out = *buf + zstr.total_out;
+ zstr.avail_out = *size - zstr.total_out;
+ assert(zstr.avail_out + zstr.total_out == *size);
+ assert(zstr.next_out == *buf + zstr.total_out);
}
zstatus = deflate (&zstr, finish ? Z_FINISH : 0);
@@ -641,17 +719,45 @@ read_and_gzip (fd, fullname, buf, size, len, level)
} while (zstr.avail_out == 0);
}
done:
- *(*buf + zstr.total_out + 10) = crc & 0xff;
- *(*buf + zstr.total_out + 11) = (crc >> 8) & 0xff;
- *(*buf + zstr.total_out + 12) = (crc >> 16) & 0xff;
- *(*buf + zstr.total_out + 13) = (crc >> 24) & 0xff;
-
- *(*buf + zstr.total_out + 14) = zstr.total_in & 0xff;
- *(*buf + zstr.total_out + 15) = (zstr.total_in >> 8) & 0xff;
- *(*buf + zstr.total_out + 16) = (zstr.total_in >> 16) & 0xff;
- *(*buf + zstr.total_out + 17) = (zstr.total_in >> 24) & 0xff;
+ /* Need to add the CRC information (8 bytes)
+ to the end of the gzip'd output.
+ Ensure there is enough space in the output buffer
+ to do so. */
+ if (zstr.avail_out < 8)
+ {
+ unsigned char *newbuf;
- *len = zstr.total_out + 18;
+ assert(zstr.avail_out + zstr.total_out == *size);
+ assert(zstr.next_out == *buf + zstr.total_out);
+ *size += 8 - zstr.avail_out;
+ newbuf = realloc (*buf, *size);
+ if (newbuf == NULL)
+ {
+ error (0, 0, "out of memory");
+ return 1;
+ }
+ *buf = newbuf;
+ zstr.next_out = *buf + zstr.total_out;
+ zstr.avail_out = *size - zstr.total_out;
+ assert(zstr.avail_out + zstr.total_out == *size);
+ assert(zstr.next_out == *buf + zstr.total_out);
+ }
+ *zstr.next_out++ = (unsigned char)(crc & 0xff);
+ *zstr.next_out++ = (unsigned char)((crc >> 8) & 0xff);
+ *zstr.next_out++ = (unsigned char)((crc >> 16) & 0xff);
+ *zstr.next_out++ = (unsigned char)((crc >> 24) & 0xff);
+
+ *zstr.next_out++ = (unsigned char)(zstr.total_in & 0xff);
+ *zstr.next_out++ = (unsigned char)((zstr.total_in >> 8) & 0xff);
+ *zstr.next_out++ = (unsigned char)((zstr.total_in >> 16) & 0xff);
+ *zstr.next_out++ = (unsigned char)((zstr.total_in >> 24) & 0xff);
+
+ zstr.total_out += 8;
+ zstr.avail_out -= 8;
+ assert(zstr.avail_out + zstr.total_out == *size);
+ assert(zstr.next_out == *buf + zstr.total_out);
+
+ *len = zstr.total_out;
zstatus = deflateEnd (&zstr);
if (zstatus != Z_OK)
OpenPOWER on IntegriCloud