From a037ef8f32200b26968e77344bcfb963251fa8b9 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 10 Aug 2001 09:43:22 +0000 Subject: Import cvs-1.11.1p1 onto vendor branch --- contrib/cvs/src/ChangeLog | 1077 ++++++- contrib/cvs/src/Makefile.am | 144 + contrib/cvs/src/Makefile.in | 676 ++++- contrib/cvs/src/add.c | 54 +- contrib/cvs/src/admin.c | 92 +- contrib/cvs/src/annotate.c | 277 ++ contrib/cvs/src/checkout.c | 125 +- contrib/cvs/src/classify.c | 245 +- contrib/cvs/src/client.c | 343 ++- contrib/cvs/src/commit.c | 84 +- contrib/cvs/src/create_adm.c | 15 +- contrib/cvs/src/cvs.h | 56 +- contrib/cvs/src/cvsbug.in | 526 ++++ contrib/cvs/src/diff.c | 116 +- contrib/cvs/src/edit.c | 18 +- contrib/cvs/src/entries.c | 4 +- contrib/cvs/src/error.c | 18 + contrib/cvs/src/error.h | 6 +- contrib/cvs/src/expand_path.c | 2 +- contrib/cvs/src/filesubr.c | 227 +- contrib/cvs/src/find_names.c | 18 +- contrib/cvs/src/history.c | 74 +- contrib/cvs/src/ignore.c | 42 +- contrib/cvs/src/import.c | 28 +- contrib/cvs/src/lock.c | 22 +- contrib/cvs/src/log.c | 197 +- contrib/cvs/src/login.c | 758 +++-- contrib/cvs/src/logmsg.c | 35 +- contrib/cvs/src/main.c | 219 +- contrib/cvs/src/mkmodules.c | 10 +- contrib/cvs/src/modules.c | 38 +- contrib/cvs/src/parseinfo.c | 10 +- contrib/cvs/src/patch.c | 51 +- contrib/cvs/src/rcs.c | 240 +- contrib/cvs/src/rcs.h | 10 +- contrib/cvs/src/rcscmds.c | 8 +- contrib/cvs/src/recurse.c | 24 +- contrib/cvs/src/release.c | 14 +- contrib/cvs/src/remove.c | 4 +- contrib/cvs/src/repos.c | 12 +- contrib/cvs/src/root.c | 473 ++- contrib/cvs/src/run.c | 12 +- contrib/cvs/src/sanity.sh | 6559 +++++++++++++++++++++++++++-------------- contrib/cvs/src/server.c | 445 ++- contrib/cvs/src/stamp-h2.in | 1 + contrib/cvs/src/status.c | 4 +- contrib/cvs/src/subr.c | 115 + contrib/cvs/src/tag.c | 557 +++- contrib/cvs/src/update.c | 131 +- contrib/cvs/src/update.h | 3 +- contrib/cvs/src/vers_ts.c | 4 + contrib/cvs/src/version.c | 17 +- contrib/cvs/src/version.c.in | 86 + contrib/cvs/src/watch.c | 6 +- contrib/cvs/src/wrapper.c | 8 +- 55 files changed, 10071 insertions(+), 4269 deletions(-) create mode 100644 contrib/cvs/src/Makefile.am create mode 100644 contrib/cvs/src/annotate.c create mode 100755 contrib/cvs/src/cvsbug.in create mode 100644 contrib/cvs/src/stamp-h2.in create mode 100644 contrib/cvs/src/version.c.in (limited to 'contrib/cvs/src') diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog index a33464d..f483a7b 100644 --- a/contrib/cvs/src/ChangeLog +++ b/contrib/cvs/src/ChangeLog @@ -1,4 +1,1079 @@ -2000-09-19 Larry Jones +2001-04-27 Larry Jones + + * main.c (lookup_command_attribute): Lookup specified command, not + whatever's in the global command_name. + +2001-04-25 Derek Price + + * Makefile.in: Regenerated using AM 1.4e as of today at 18:10 -0400. + * version.c: Regenerated. + +2001-04-22 Larry Jones + + * tag.c (tag_check_valid): Make an unwritable val-tags file a + warning instead of a fatal error. + +2001-04-20 Larry Jones + + * annotate.c (annotate_usage): -r and -D are not mutually exclusive. + * main.c (cmd_usage): Add missing version subcommand. + * update.c (update_usage): Add missing -C option. + + * sanity.sh (death2): New tests for previous change. + + * classify.c (Classify_File): Treat a dead revision like the RCS + file doesn't exist. + * sanity.sh: Update to match. + +2001-04-16 Larry Jones + + * checkout.c, update.c: Fix usage messages: -r and -D are not + mutually exclusive. + (Suggested by David L. Martin .) + + * logmsg.c (do_editor): Don't add a blank line to the message. + * sanity.sh (editor-log-file*): Update to match. + + * checkout.c, update.c: Note in usage message that -k is sticky. + + * server.c: (server_cleanup, wait_sig): Remove ancient SunOS kludge. + (Suggested by Rob Saccoccio .) + +2001-04-04 Larry Jones + + * sanity.sh (dotest, dotest_lit, dotest_fail, dotest_status, + dotest_sort): Don't count on $? being set in then or else clauses. + + * ignore.c (ignore_files): Collect unignored files into a list and + sort it before calling PROC to avoid order dependencies. Rewrite + the while loop to allow normal continues instead of goto. + +2001-04-04 Derek Price + + * sanity.sh (ignore-on-branch-3): Fix in the remote case. + +2001-04-03 Larry Jones + + * update.c (update_fileproc): Remove unused variable (resurrecting). + +2001-04-03 Derek Price + Larry Jones + reported by Jakob Bøhm + + * update.c (update_fileproc): Don't store a file with T_UNKNOWN status + in ignlist if present in the sandbox. + * sanity.sh (ignore-on-branch): New test. + (ignore): Tidy this test. + +2001-04-02 Derek Price + + * sanity.sh: Make sure the test for `id' fails when a nonstandard `id' + is used and the user is root. Fix some quoting in error messages. + (fork): Take `cvs' out of the PATH. + (TODO): Add note about the test suite not working with user names over + eight characters in length. + +2001-04-02 Derek Price + + * sanity.sh (fork): New test for CVS_SERVER default. + (TODO): Note about eventually removing most of the references to + CVS_SERVER. + +2001-04-02 Larry Jones + + * client.c (connect_to_forked_server): Use program_path as the default + server instead of "cvs". + +2001-04-02 Derek Price + + * sanity.sh: Use less obfuscated English in my comment about sanity + checking sanity.sh. + +2001-04-02 Derek Price + + * sanity.sh (rm-update-message): Create a test directory again but + change back to the correct directory upon completion this time. + +2001-04-02 Derek Price + + * sanity.sh: Change last two '[.*]'s to 'test's for + consistency and remove... + (TODO): the note from the TODO list. + +2001-04-02 Derek Price + + * sanity.sh: Add test for PWD before successful exit. + +2001-03-30 Larry Jones + + * sanity.sh (rm-update-message): Remove duplicate code. + +2001-03-30 Derek Price + + * sanity.sh (rm-update-message): New test for local/client-server + warning message discrepency. + +2001-03-30 Larry Jones + + * annotate.c: Move annotate() here from rcs.c, support rannotate. + * Makefile.am, Makefile.in: Add annotate.c. + * main.c (cmds[], cmd_usage[]): Add rannotate. + * rcs.c: Move declarations of rcs_delta_op and RCS_deltas to... + * rcs.h: ... here. + * server.c (serve_rannotate): New. + (requests[]): Add rannotate. + * sanity.sh (ann): New tests for rannotate. + + * log.c (rlog_proc): Remove dead code. + +2001-03-30 Derek Price + + * sanity.sh (join-readonly-conflict): Run more of this through dotest. + +2001-03-30 Larry Jones + + * log.c (log_fileproc): Don't output working file for rlog. + * sanity.sh (log): New tests for rlog. + + * cvs.h (mtype): Add MISC type. + * log.c (cvslog): Support rlog as well as log. + (rlog_proc): New. + * main.c (cmds[], cmd_usage[]): Add rlog. + (main): Remove old rlog warning message. + * server.c (serve_rlog): New. + (requests[]): Add rlog. + +2001-03-29 Derek Price + + * sanity.sh: cd to $TESTDIR once after it is normalized. Make TODO + on history and symlinks more specific. Tested properly this time. + +2001-03-29 Larry Jones + + * main.c (cmds[], lookup_command_attribute, main): Include the + command attributes in the global command table instead of inferring + them from the command names. Change the sense of the + CVS_CMD_IGNORE_ADMROOT attribute to match its name. + +2001-03-29 Derek Price + + * sanity.sh (*, basic2-64): Remove references to TMPPWD. Fix FIXME + at end of script now that $TESTDIR can't be relative. + +2001-03-29 Derek Price + + * sanity.sh: Normalize TESTDIR even when the user set it. + +2001-03-29 Larry Jones + + * client.c (connect_to_pserver, start_tcp_server): Add IP address + to connect failed message. + (connect_to_forked_server, connect_to_pserver, start_tcp_server): Add + trace messages ala start_rsh_server. + (start_rsh_server): Include entire command in trace message for + START_RSH_WITH_POPEN_RW like ! START_RSH_WITH_POPEN_RW does. + +2001-03-29 Derek Price + + * sanity.sh: Global search & replace ${TESTDIR}/cvsroot with + ${CVSROOT_DIRNAME} for consistency. + +2001-03-29 Derek Price + + * sanity.sh (conflicts-12[68].5): Remove sanity hack which has allowed + for a CVS bug since May 96/97. Not sure when the bug went bye-bye, but + the tests broke when $TESTDIR != $TMPPWD. + +2001-03-26 Larry Jones + + * classify.c (Classify_File): Don't report a conflict for a removed + file when piping. Also simplify the code structure. + (Reported by Milos Kleint .) + * sanity.sh (rmadd2-14[abc]): New tests for above. + +2001-03-24 Noel Cragg + + * diff.c: mods to allow `-T' and `-y' options to be passed through + to the diff library. This wasn't allowed earlier because of a + similarly named options that got passed through to the old rcs + programs. We've long since stopped sending `-T' to any rcs + utility and have never used `-y'. Any users of moldly CVS + versions which used to support `-T' have (hopefully) upgraded to + one where that option isn't supported. It seems reasonable to + enable them again and pass them through. (sanity.sh still works + anyways...) + (longopts): add short option equivalents for --initial-tab and + --side-by-side. + (diff): add new short options to getopt string and switch + statement. + +2001-03-22 Larry Jones + + * sanity.sh: Add check for ${DOTSTAR} with large matches. + +2001-03-23 Derek Price + + * sanity.sh: Do the same as below for $keep. + +2001-03-23 Derek Price + + * sanity.sh: Replace 'remote=(yes|no)' with 'remote=(:|false)' since + often 'false' and more often ':' are shell builtins. This makes the + succinct, 'if $remote; then' faster than 'if test $remote = yes; then'. + Alter tests in the rest of the script to match the new usage. Added + a suffix of 'r' to remote test names when it was appropriate and I + remembered. Some reformatting. + +2001-03-22 Larry Jones + + * sanity.sh (diffmerge1_yours, diffmerge1_mine): Check for exact + output instead of using wildcards to avoid buffer overflows in some + versions of expr. + +2001-03-21 Derek Price + + * sanity.sh: cd to '/tmp' again rather than $HOME since HOME was set to + a value inside ${TESTDIR} by the script. + +2001-03-20 Derek Price + + * sanity.sh (diffmerge1): Minor formatting and syntax changes. + + for Jacob Burckhardt + + * sanity.sh (diffmerge1): More merging behavior tests. Specifically, + test some cases which broke before in Karl Tomlinson's diff fix was + checked in today. + +2001-03-20 Derek Price + + * sanity.sh: Don't use unescaped parens in sh outside of quotes. + +2001-03-20 Derek Price + + * sanity.sh: Don't remove ${TESTDIR} when -k (keep) set. + +2001-03-20 Derek Price + + * sanity.sh: Change usage to match the new getopts format and comment. + +2001-03-16 Derek Price + + * sanity.sh (modules2-nestedrename): New test. Verifies behavior of + renames nested under an ampersand module. + (modules2-ampertag): New test. Verifies an error condition which + prevents some ampersand modules from being checked out when a tag + is specified. + +2001-03-16 Derek Price + + * sanity.sh (modules2): Additional test for ampersand module behavior + with '-d'. + + for Greg Klanderman + + * checkout.c (build_one_dir): Fix typo where clauses of two + conditionals were reversed in call to Create_Admin. This caused + the CVS/Tag file to be removed in cases where it should have been + set, and vice-versa. It only surfaced in rare cases as this code + is only invoked when using the -d option to build the path to + check out in. Further, the bug would only matter when checking + out a module containing ampersand modules within it, via + client/server CVS. + +2001-03-16 Derek Price + + * sanity.sh (admin-28-5): Confirm that a missing tag during an + 'admin -n' operation is not a fatal error. + +2001-03-16 Derek Price + + * admin.c (admin_data): Remove 'quiet' member. + (admin_fileproc): Use global 'really_quiet' rather than + admin_data->quiet. + +2001-03-16 Derek Price + + * sanity.sh (admin): Replace hardcoded testdir path with the variable. + +2001-03-15 Derek Price + + * sanity.sh (basica, binfiles, head, admin): Adjust for new messages. + * admin.c (admin_fileproc): Only print messages when not in + really_quiet mode. + + for Stephen Rasku + + * rcs.c (RCS_tag2rev): Make a missing tag a survivable error. + +2001-03-15 Larry Jones + + * subr.c (sleep_past): Fix various bugs that would result in a + negative sleep time if it weren't unsigned; since it is, it would + result in a very large sleep time. Ensure that us is always less + than 1000000. Don't try to sleep for more 1 sec with usleep. + Cast NULL select arguments to correct type just in case. + +2001-03-14 Derek Price + + * subr.c (sleep_past): New function. + * client.c (get_responses_and_close): Use new function. + * commit.c (commit): Ditto. + * update.c (do_update): Ditto. + * cvs.h: Prototype new function. + + * stamp-h2.in: Regenerated. + +2001-03-14 Derek Price + + * Makefile.in: Regenerated. + * stamp-h2.in: Ditto. + +2001-03-14 Larry Jones + + * commit.c (check_fileproc): Allow adding on the trunk when there's + an existing non-Attic RCS file as long as the head revision is dead. + This can happen due to an aborted resurrection. + (commit_fileproc): When resurrecting, consider the dead revision + along with the other files' revisions. + (findmaxrev): Avoid unnecessary work. + (checkaddfile): Only warn if file isn't in Attic as expected. + (Reported by Ross Burton .) + * sanity.sh (basica-r*): New tests for above. + (basica-o4): Update to match. + +2001-03-09 Larry Jones + + * edit.c (edit_fileproc, unedit_fileproc): Some implementations of + asctime/ctime apparently use a leading zero on the date instead + of the space required by the C Standard. Correct for this so that + shared working directories work without hassle. + (Reported by David L. Martin .) + * entries.c (fgetentent): Ditto. + * vers_ts.c (time_stamp_server, time_stamp) Ditto. + +2001-03-07 Larry Jones + + * sanity.sh (basica, binfiles2, head, admin): Update to match + change to admin.c. + +2001-03-06 Larry Jones + + * client.c (recv_bytes): Handle EOF as in recv_line(). + (Reported by Pavel Roskin .) + + * admin.c (admin_fileproc): Change final error message to clarify + that CVS refused to modify the RCS file rather than being unable to. + +2001-02-28 Jim Meyering + + * commit.c (commit_usage): Use `-F logfile' (rather than -F file') in + the description of that option, to be consistent with the `-F logfile' + in the Usage: line. Use spaces instead of TAB characters, and realign. + +2001-03-02 Derek Price + + * sanity.sh (crerepos): Make failed ${CVS_RSH-rsh} attempt print the + name of the command it actually used rather than 'rsh'. + +2001-02-27 Derek Price + + * sanity.sh (modules2-ampermod-*): Added these tests to make sure the + top level directory is created in an ampermodule when '-n' is passed to + checkout. + + original bug report from + Wolfgang Haefelinger + +2001-02-27 Derek Price + + * sanity.sh (version-[12]): replace ' (client/server)' with .* in these + two tests so that 'make check' works with whatever client/server + options the executable was compiled with. + +2001-02-23 Derek Price + + * main.c (main): Only check a cvsroot_t's isremote member when client + support is enabled. + * server.c: Include GSSAPI headers with client support as well as + server support. + +2001-02-21 Larry Jones + + * modules.c, cvs.h (do_module): Add build_dirs argument and use it + instead of run_module_prog. Change all callers. + * tag.c (cvstag): For rtag, don't build directories. + * sanity.sh (modules3): Update to match. + +2001-02-20 Derek Price + + * client.c: Use xgssapi.h. + * server.c: Ditto. + +2001-02-15 Derek Price + + * Makefile.am (cvs_SOURCES): Correct error from yesterday. + * Makefile.in: Regenerated. + +2001-02-14 Derek Price + + * server.c: Include xselect.h. + * update.c (do_update): Use best available sleep function. + +2001-02-14 Derek Price + + * Makefile.am (cvs_SOURCES): Alphabetize and split to one/line. + (cvs_LDADD): Alphabetize and split to one/line. + * Makefile.in: Regenerated. + +2001-02-14 Larry Jones + + * build_src.com: Remove references to rtag.c & rtag.obj. + +2001-02-13 Derek Price + + * main.c (date_to_tm): New function to convert an RCS date string to a + struct tm. + (tm_to_internet): New function to convert a struct tm to a date string + as specified by RFC822 and amended by RFC 1123. + (date_to_internet): Use the above two functions and a struct tm + intermediary for conversion. + * patch.c (patch_fileproc): Answer somebody's comment and use the new + diff_exec API. + * rcs.c (RCS_checkin): Use new diff_exec API. + (RCS_delete_revs): Use new diff_exec API. + (make_file_label): If the file name is DEVNULL, date it the Epoch for + compatibility with the POSIX.2 spec and Larry Wall's patch + implementation. + * rcscmds.c (diff_exec): Accept new label arguments. + * sanity.sh (death2): Update some diff tests to accept the new format. + * update.c (patch_file): Use new diff_exec API. + * diff.c (diff_fileproc): Create header labels appropriate for + compatibility with the Larry Wall version of patch. + (diff): Rename calls to strcat_and_allocate. + (strcat_and_allocate): Rename and move... + * subr.c (xrealloc_and_strcat): here. + * cvs.h: Update prototypes to match. + +2001-02-13 Derek Price + + * Makefile.am (cvs_SOURCES): Remove rtag.c. + +2001-02-07 Larry Jones + + * sanity.sh (directory_cmp): Return status rather than setting ISDIFF. + (basic2): Rewrite using dotest. + +2001-02-06 Larry Jones + + * tag.c, rtag.c: Merge with tag.c being the surviving file. + * Makefile.in: Update to match. + * main.c (cmds): rtag() => cvstag(). + * server.c (serve_rtag): Ditto, and set command name. + +2001-02-06 Derek Price + Rex Jolliff + Shawn Smith + + * add.c: Replace opendir, closedir, & readdir calls with CVS_OPENDIR, + CVS_CLOSEDIR, & CVS_READDIR in support of changes to handle VMS DEC C + 5.7 {open,read,close}dir problems. Check today's entry in the vms + subdir for more. + * filesubr.c: ditto + * find_names.c: ditto + * ignore.c: ditto + * import.c: ditto + * lock.c: ditto + * update.c: ditto + +2001-02-02 Larry Jones + + * error.h: Changed include guard macro from _error_h_ to ERROR_H; + names beginning with underscore are reserved. + * login.c (password_entry_parseline, password_entry_operation, + password_entry_operation_e, password_entry_operation_t): Removed + leading underscore(s). + (password_entry_parseline): Corrected error messages. + (password_entry_operation): Fixed uninitialized variable (password). + (login): Removed unused variable (found_password). + + * rtag.c (rtag_proc): Call lock_tree_for_write() before calling + start_recursion. This fixes a serious problem where do_recursion + was reading and caching RCS files without any locks in place and + that information was subsequently being used to rewrite the file + causing any intermediate changes to be lost. + (rtag_filesdoneproc): Defunct. + (Reported by Karl Tomlinson .) + * tag.c (cvstag, tag_filesdoneproc): Ditto. + * lock.c (lock_tree_for_write): Add which argument, change all + callers to pass W_LOCAL. + * rcs.h: Ditto. + +2001-01-29 Derek Price + + * client.c (get_cvs_port_number): change the prototype to accept a + const cvsroot_t * as input and add a FIXME comment + * cvs.h: new prototypes for get_cvs_port_number & normalize_cvsroot + * login.c (_password_entry_operation): consolidate all the ~/.cvspass + access into a single new function which reads ~/.cvspass in a backwards + compatible manner + (logout): use the new _password_entry_operation function + (login): ditto + (get_cvs_password): ditto + * root.c (normalize_cvsroot): move knowledge of default port & username + values inside + +2001-01-29 Larry Jones + + * subr.c (shell_escape): New function. + * cvs.h: Declare it. + * logmsg.c (logfile_write): Use it to avoid problems with filenames + containing "'". + (Reported by Gerhard Ahuis .) + + * server.c (outbuf_memory_error, pserver_authenticate_connection, + kserver_authenticate_connection): If available, use syslog() to + record some errors. + +2001-01-25 Larry Jones + + * server.c (do_cvs_command): If there's a partial output line left + over and the client doesn't support MT, go ahead and send it in an + M response instead of just dropping it. + (Reported by Milos Kleint .) + + * update.c (update_fileproc): Handle toss_local_changes in the + T_NEEDS_MERGE case. + (Inspired by Noel L Yap .) + * sanity.sh (clean): New tests for above. + +2001-01-23 Derek Price + + * run.c (run_exec): flush, if used, stderr and stdout before exit + * server.c (cvs_flusherr): flush stderr & send a stderr flush command + on the protocol pipe + (cvs_flushout): like above, for stdout + (do_cvs_command): handle flushes properly + * sanity.sh (reserved): make the commitinfo script echo errors to + stderr rather than stdin + +2001-01-18 Larry Jones + + * log.c (option_revlist, revlist, log_usage, cvslog, + log_parse_revlist, log_expand_revlist, log_version_requested): Add + support for :: for exclusive ranges. + * admin.c (admin_usage): Reorder -o to be parallel to log -r. + * sanity.sh (log): New tests for above. + +2001-01-18 Derek Price + + * main.c: Add '2001' to the range of copyright years listed by the + --version option + * version.c.in (version): check current_parsed_root before its isremote + member to avoid a core dump + * sanity.sh (version): add a test for the version command + + * version.c: regenerated + +2001-01-12 Larry Jones + + * rcs.c, rcs.h (RCS_lock, RCS_unlock): Use RCS_gettag to find the + correct revision so that symbolic tags work correctly. (This + requires removing the "const" from the rev parameter since it's + passed to RCS_gettag which might modify it.) + (Reported by irina sturm .) + +2001-01-11 Larry Jones + + * run.c (close_on_exec): Remove check for FD_CLOEXEC. As far as I + can see, it's *never* been defined, which defeats the whole point. + If F_SETFD is defined, it's probably safe to use it. + + * server.c (do_cvs_command): Call close_on_exec on the protocol and + flow control pipes in the child process so they don't get inherited + by any subsidiary processes. + (Reported by Tristan Gingold .) + + * cvs.h (free_cvsroot_t): Spell correctly (was free_CVSroot_t). + +2001-01-10 Derek Price + Rex Jolliff + + * build_src.com: VMS changes + * filesubr.c: replace calls to unlink() with CVS_UNLINK() for VMS + * rcs.c: ditto + +2001-01-10 Derek Price + + * main.c (current_root): explicitly list this as a static global + +2001-01-10 Derek Price + + * cvs.h (get_cvs_port_number): change name & prototype from + get_port_number + * client.c (get_cvs_port_number): new function which returns a port + number based on a cvsroot_t rather than requiring all possible sources + passed in + (connect_to_pserver): use new get_cvs_port_number function + (connect_to_server): ditto + * login.c (get_password): use new get_cvs_port_number function + (login): ditto + (logout): ditto + +2001-01-10 Derek Price + + * Makefile.am ($(srcdir)/version.c): specify $(srcdir) for all subparts + of the build since some systems don't allow mv's across partitions + * Makefile.in: regenerated + +2001-01-10 Derek Price + + * Makefile.am (version.c): specify $(srcdir) explicitly in target rule + so version.c gets built properly for all makes. + (version.o): specify $(srcdir)/version.c explicitly so dependency is + found and built properly + * Makefile.in: regenerated + +2001-01-09 Derek Price + + * version.c: updated timestamp + +2001-01-09 Larry Jones + + * server.c (server): Change to server_temp_dir immediately after + creating it so that any stray files that happen to be created go + there instead of in the server's initial directory, wherever that + may be. + * sanity.sh (modules5-15): Update to match. + + * version.c.in: Update to match Derek's change to version.c. + +2001-01-09 Derek Price + + * cvs.h: Remove the various CVSroot_* bits and replace them with a + single structure of type cvsroot_t (current_parsed_root) + + * root.c (parse_cvsroot): return pointer to a new cvsroot_t rather than + altering global variables + (local_cvsroot): return a pointer to a new cvsroot_t rather than + setting globals. changed the name of this function from + set_local_cvsroot to better explain new functionality + (new_cvsroot_t): new initializer function + (free_cvsroot_t): new function + (others): use current_parsed_root rather than the old CVSroot_* globals + + * add.c: use current_parsed_root rather than the old CVSroot_* globals + * admin.c: ditto + * checkout.c: ditto + * client.c: ditto + * commit.c: ditto + * create_adm.c: ditto + * diff.c: ditto + * edit.c: ditto + * expand_path.c: ditto + * find_names.c: ditto + * history.c: ditto + * ignore.c: ditto + * import.c: ditto + * lock.c: ditto + * log.c: ditto + * login.c: ditto + * logmsg.c: ditto + * main.c: ditto + * mkmodules.c: ditto + * modules.c: ditto + * parseinfo.c: ditto + * patch.c: ditto + * rcs.c: ditto + * recurse.c: ditto + * release.c: ditto + * remove.c: ditto + * repos.c: ditto + * rtag.c: ditto + * server.c: ditto + * status.c: ditto + * tag.c: ditto + * update.c: ditto + * version.c: ditto + * watch.c: ditto + * wrapper.c: ditto + +2001-01-05 Derek Price + + * cvs.h (enum CVSmethod): add null_method + * root.c (method_names): correlate null_method & "undefined" + (parse_cvsroot): make two error cases non fatal + * sanity.sh (crerepos-6b): account for new error message, re above + +2001-01-05 Derek Price + + * src/Makefile.am (cvsbug, cvsbug_EXTRA_DIST, EXTRA_DIST): move cvsbug + target to configure.in - see ../ChangeLog for more + * src/cvsbug.in: Rename from cvsbug.sh + * src/cvsbug.sh: Rename to cvsbug.in + +2001-01-04 Larry Jones + + * Makefile.am (cvsbug): Explicitly list input file ($< is only + valid in inference rules). + * Makefile.in: Ditto. + +2001-01-04 Derek Price + + * sanity.sh: use getopts rather than getopt for portability reasons + +2001-01-03 Derek Price + + * Makefile.am (remotecheck): depend on 'all' + * Makefile.in: regenerated + +2000-12-29 Derek Price + + * sanity.sh: remove explicit "$@" from last checkin and move the 'do' + to the line following the 'for'. Apparently this is more portable. + +2000-12-29 Derek Price + + * sanity.sh: make "$@" explicit in 'for' statement since Solaris 5.6's + implementation of Bourne shell doesn't seem to implement this default + behavior. + +2000-12-27 Derek Price + + * sanity.sh: add a -f option for continuing from a particular test + and shorten --keep to -k so we can use the getopt function. + +2000-12-27 Derek Price + + * Makefile.am (remotecheck): Make remotecheck dependant on all + * Makefile.in: regenerated + +2000-12-26 Derek Price + + * Makefile.in: update timestamp + * stamp-h2.in: ditto + * version.c: ditto + +2000-12-26 Derek Price + + * Makefile.am: new target for version.c + (EXTRA_DIST): add version.c.in & version.c so builds work when + configure doesn't + * Makefile.in: Regenerated + * stamp-h2.in: update timestamp + * version.c: ditto + +2000-12-26 Derek Price + + * Makefile.am (INCLUDES): add zlib + * Makefile.in: Regenerated + +2000-12-22 Derek Price + + * Makefile.am (DISTCLEANFILES): added a few files + (INCLUDES): commented + * Makefile.in: Regenerated + +2000-12-21 Derek Price + + * .cvsignore: Added .deps directory and a new stamp file + * Makefile.am: New file needed by Automake + * Makefile.in: Regenerated + * stamp-h2.in: New stamp file created by Automake + * version.c.in: use configure to generate version.c + +2000-12-16 Derek Price + + * server.c (server_update): Keep the vers structure up to date after + sending a Remove or Remove-entry command to the client + * update.c (update): remove call to server_updated() after + scratch_file() + (scratch_file): in server mode, call server_updated(), otherwise keep + the vers structure up to date + (join_file): add a trace, save the revision to Register() on a remove + before calling server_scratch & server_updated + * sanity.sh (join): Add test for a remove/add caused by an update + to a new branch and a join in the same step. + +2000-12-15 Larry Jones + + * error.c (error): Add %ld and %lu. + + * history.c: Change hrec.idx from int to long, reformat NEXT_BAR + for readability, add hrec_idx. + (fill_hrec): Change initialization to be portable and always set + idx so it can be used as a line number in error messages; improve + parsing and error checking. + (read_hrecs): Initialize hrec_idx, handle embedded NULs, warn about + no newline at end of file. + (select_hrec): Add basic validity checking. + +2000-12-07 Larry Jones + + * history.c (history): Allow multiple -m options as documented. + +2000-11-29 Derek Price + + * root.c (parse_cvsroot): back out yesterday's redundant changes + * main.c (main): fix CVSROOT trace message to look like other trace + messages + * sanity.sh (multiroot2-9): expect new trace message + +2000-11-28 Derek Price + + * root.c (parse_cvsroot): add trace on this function + * client.c (get_port_number): make trace print look like others + +2000-11-16 Derek Price + + * filesubr.c (cvs_temp_file): back out the previous change in the + interests of portability, add an assertion, and fix the header comment + +2000-11-16 Derek Price + + * filesubr.c (cvs_temp_file): refine the exit behavior to notice if + the out param was passed in NULL and, if so, avoid setting it and delete + the temp file for later + +2000-11-16 Derek Price + + * filesubr.c (cvs_temp_file): fixed a garble or two, added some + additional error checking, and added a comment + +2000-11-15 Derek Price + + * filesubr.c (cvs_temp_file): added cvs_temp_file + function to use mkstemp rather than one of the other temp file + generators as gcc keeps complaining I should. + (cvs_temp_name): altered this function to simply wrap cvs_temp_file + and deprecated it + * cvs.h: added prototype for cvs_temp_file + * commit.c (commit): use the new function instead of the old and plug + an old (though related) memory leak. + * import.c (import): use the new function + * login.c (login): Ditto + * logmsg.c (do_editor, do_verify): Ditto + * patch.c (patch_fileproc): Ditto + +2000-11-14 Larry Jones + + * update.c, update.h (do_update): Add xdotemplate parameter. + Change all callers. + (update_dirent_proc): Use dotemplate for Create_Admin, not 1. + * checkout.c (checkout_proc): Don't create CVS/Template if + exporting. + (Reported by Andrey Podkolzin .) + +2000-11-08 Larry Jones + + * admin.c (admin): Use getgroups() to check for membership in + CVS_ADMIN_GROUP if it exists. In any event, check the user's + primary group in addition to any additional groups. + (Reported by Thomas Okken .) + +2000-11-06 Jim Meyering + + Compile with gcc's -Wformat and fix the exposed problems. + * root.c (parse_cvsroot) [! HAVE_KERBEROS]: Provide an argument + for the %s error format spec. + [! HAVE_GSSAPI]: Likewise. + (normalize_cvsroot): Put comment delimiters around token after `#endif'. + +2000-11-03 Larry Jones + + * sanity.sh: Some versions of sed require a space between -e and + the value. + +2000-10-27 Larry Jones + + * checkout.c (checkout): Don't check for a safe location if just + cat'ing the module database. + (Reported by Ilya Martynov .) + Have -s set cat as well as status; it simplifies the code. + +2000-10-26 Larry Jones + + * sanity.sh (join-admin-2): Check output from all commands instead + of (mostly) discarding. (Some of the tests used to produce stray + output in remote mode.) + + * sanity.sh (dotest_line_by_line): Handle empty lines in pattern + (expr doesn't distingish between successfully matching nothing + and failing to match anything). + + * sanity.sh (dotest_internal): Rearrange and use elif to simplify. + +2000-10-24 Jim Meyering + + Fix a bug, introduced with my fix of 2000-07-10, whereby -kk would + sometimes be ignored for some of the files involved in an update. + + * update.c (join_file): Restore the original value of `options' + right after calling checkout_file. + * sanity.sh (join-admin-2): New test for this. + +2000-10-23 Derek Price + James Youngman + + * sanity.sh: it's /gnu/bin, not /gun/bin. Thanks go to James Youngman + for the bug report and patch. + +2000-10-20 Jim Kingdon + + * server.c (switch_to_user): Set CVS_USER. Patch from Sudish + Joseph and popularized by dozens (e.g. mozilla.org, also others). + +2000-10-20 Derek Price + KOIE Hidetaka + + * root.c (normalize_cvsroot): plug a memory leak. Thanks to + KOIE Hidetaka + +2000-10-18 Derek Price + + * client.c (connect_to_pserver): added a close brace the lack of which + was preventing compilation when gssapi was enabled. Removed a + redundant check for HAVE_KERBEROS. + +2000-10-18 Derek Price + + * root.c (normalize_cvsroot): removed references to free_port_s and the + now useless call to free now that port_s is on the stack. Thanks to + Jon Miner. + +2000-10-18 Derek Price + + * root.c (normalize_cvsroot): remove calls to snprintf for + compatibility with M$ Windoze. + +2000-10-18 Derek Price + + * sanity.sh (crerepos-6a, crerepos-6a-r): fix a "?" in a regex & pipe + the output of a test to /dev/null since we don't know what error + messages specific rsh implementations will output. + +2000-10-17 Derek Price + + * cvs.h: added CVSroot_password variable. Provided prototypes for + get_port_number & normalize_cvsroot. + * client.c (get_port_number): Fixed an ANSI prototype I had included + for get_port_number. + * login.c (login, logout): Removed two checks for a non-null + CVSroot_username since parse_cvsroot now supplies a default in pserver + mode. allow for a password in CVSROOT + (get_cvs_passsword): return CVSroot_password if it was supplied + in the CVSROOT. + * root.c (parse_cvsroot): Changed CVSROOT spec from + :method:user@host/port:/cvsroot to + :method:[[user][:password]@]host[:[port]]/cvsroot + Removed the xstrdup function since we'd rather have the error checking + from the version in subr.c anyhow. Moved some error messages which + looked like they would print the wrong error message after a failed + connect_to_gserver call. + (normalize_cvsroot): return a normalized CVSROOT for use in the + .cvspass file. + * sanity.sh (crerepos-6): fix a test which was expecting an old error + message. + + * client.c (connect_to_pserver): Moved some error messages which looked like they + would print the wrong error message after a failed connect_to_gserver + call. + + * login.c (login): Paranoiacly zero a password in memory. + +2000-10-12 Derek Price + + * client.c (auth_server_port_number -> get_port_number, start_pserver, + start_tcp_server): use a port specified in CVSROOT instead of the + default port. Failing that, use the CVS_CLIENT_PORT environment + variable. + * cvs.h: Added global CVSroot_port & renamed auth_server_port_number. + * root.c (parse_cvsroot): Parse the new CVSROOT format properly. + Incidentally reformated some error messages for uniformity and + readability. + * sanity.sh (crerepos): fix two tests which were now expecting the + wrong error message. + +2000-10-11 Larry Jones + + * server.c (pserver_authenticate_connection): Fix stupid mistake + in previous change. + +2000-10-11 Derek Price + + * main.c (main): Dispose old CVSroot when parsing a '-d' option if + free_CVSroot is set. + * root.c (parse_cvsroot): remove references to 'cvsroot_parsed', a + static boolean I expect hasn't been used since CVS learned to handle + multiple CVSROOTs. + +2000-10-10 Larry Jones + + * server.c (print_error): Make up a message if strerror fails. + + * server.c (pserver_authenticate_connection): Give a real error + message for an invalid repository. + +2000-10-06 Derek Price + + * add.c (add): Made quiet mode affect some warning messages as seemed + appropriate. Specifically, some of the messages which a user might + want to ignore so they don't have to be quite so specific on the + command line: files added twice, files already in the repository and + check out properly (i.e. but picked up by 'cvs add *'), & files which + are readded in place of a dead revision or onto a branch. '-q' will + not change the non-zero exit code for the cases where at least one + passed in file name was already in the Entries file. There seems to + be a precedent in remove.c. + * remove.c (cvsremove): switched the "use cvs ci to make these changes + permanent message" to only print w/o '-Q' to match the new behavior of + add. This seems appropriate as '-Q' is defined to restrict messages + to critical errors. + * sanity.sh (adderrmsg): Added some tests for the above behavior. + +2000-10-05 Larry Jones + + * client.c (call_in_directory): Create CVSADM directory if it doesn't + exist in the directory. This makes client/server work more like + standalone when checking out into an existing (non-CVS) directory. + * sanity.sh (dirs2, conflicts3, toplevel): Update to match. + +2000-10-03 Larry Jones + + * filesubr.c (get_homedir): Ignore $HOME when running in server mode. + +2000-10-02 Larry Jones + + * cvs.h: Define (and use) T_PATCH as a valid file classification + even when SERVER_SUPPORT isn't defined -- it simplifies the code. + * classify.c (Classify_File): Ditto. + * commit.c (check_fileproc): Ditto. + * status.c (status_fileproc): Ditto. + * update.c (update_fileproc): Ditto. + * tag.c (check_fileproc): Accept T_PATCH in addition to T_CHECKOUT. + * sanity.sh (tagc-10): Update to match. + +2000-09-29 Larry Jones + + * client.c (get_responses_and_close): Reset server_fd to -1 after + shutting down. + (Reported by Joerg Thoennes .) + +2000-09-27 Larry Jones + + * commit.c (commit): Don't sleep before returning in server mode, + just let the client do it. + * update.c (do_update): Ditto. + + * sanity.sh (find_tool): Correct method of checking for GNU tools. + + * checkout.c (checkout_proc): Match up user directories with + repository directories instead of using Emptydir. + * sanity.sh (cvsadm, emptydir): Update to match. + +2000-09-19 Larry Jones + + * version.c: Push version number to 1.11.0.1. * version.c: Version 1.11. diff --git a/contrib/cvs/src/Makefile.am b/contrib/cvs/src/Makefile.am new file mode 100644 index 0000000..768d4f8 --- /dev/null +++ b/contrib/cvs/src/Makefile.am @@ -0,0 +1,144 @@ +## Process this file with automake to produce Makefile.in +# Makefile for GNU CVS program. +# Copyright (C) 1986, 1988-1990, 2000 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +SHELL = /bin/sh + +# $(includeopt) is CVS specific and set by configure +# FIXME - This includes line is dependant on its order. This means there is +# some namespace hackery going on that maybe shouldn't be. Long term fix is to +# try and remove naming ocnflicts and fix Automake to allow particular includes +# to be attached only to particular object files. Short term fix is either or. +##INCLUDES = -I. -I.. -I$(srcdir) -I$(top_srcdir)/lib +INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/diff -I$(top_srcdir)/zlib $(includeopt) + +bin_PROGRAMS = cvs +bin_SCRIPTS = cvsbug + +# The cvs executable +cvs_SOURCES = \ + add.c \ + admin.c \ + annotate.c \ + buffer.c \ + checkin.c \ + checkout.c \ + classify.c \ + client.c \ + commit.c \ + create_adm.c \ + cvsrc.c diff.c \ + edit.c \ + entries.c \ + error.c \ + expand_path.c \ + fileattr.c \ + filesubr.c \ + find_names.c \ + hardlink.c \ + hash.c \ + history.c \ + ignore.c \ + import.c \ + lock.c \ + log.c \ + login.c \ + logmsg.c \ + main.c \ + mkmodules.c \ + modules.c \ + myndbm.c \ + no_diff.c \ + parseinfo.c \ + patch.c \ + rcs.c \ + rcscmds.c \ + recurse.c \ + release.c \ + remove.c \ + repos.c \ + root.c \ + run.c \ + scramble.c \ + server.c \ + status.c \ + subr.c \ + tag.c \ + update.c \ + vers_ts.c \ + watch.c \ + wrapper.c \ + zlib.c \ + buffer.h \ + client.h \ + cvs.h \ + edit.h \ + error.h \ + fileattr.h \ + hardlink.h \ + hash.h \ + myndbm.h \ + rcs.h \ + server.h \ + update.h \ + watch.h +cvs_LDADD = \ + ../diff/libdiff.a \ + ../lib/libcvs.a \ + ../zlib/libz.a \ + version.o +cvs_EXTRA_DIST = version.c + +# extra clean targets +# wish this could be distclean-hdr-local but it's not part of automake +DISTCLEANFILES = options.h-SAVED check.log check.plog + +# General +EXTRA_DIST = \ + $(cvs_EXTRA_DIST) \ + .cvsignore \ + ChangeLog-9194 \ + ChangeLog-9395 \ + ChangeLog-96 \ + ChangeLog-97 \ + build_src.com \ + sanity.sh \ + version.c \ + version.c.in + +check-local: + $(SHELL) $(srcdir)/sanity.sh `pwd`/cvs + +.PHONY: remotecheck +remotecheck: all + $(SHELL) $(srcdir)/sanity.sh -r `pwd`/cvs + +## MAINTAINER Targets + +# version.c +# - build this here so that we can distribute it +# - version.c needs to be updated only once, since it depends on +# configure.in, not on the results of a 'configure' run. +# - It is guaranteed (with GNU Make) that when the version in configure.in +# is changed, acversion.m4 is built only after the new version number is +# propagated to the Makefile. (Libtool uses the same guarantee.) +# - need the explicit version.o dependency or else make won't match +# $(srcdir)/version.c when looking for a dependency for version.c +version.o: $(srcdir)/version.c +$(srcdir)/version.c: $(srcdir)/version.c.in $(top_srcdir)/configure.in + sed 's,@VERSION\@,$(VERSION),g' $(srcdir)/version.c.in >$(srcdir)/version.tc + mv $(srcdir)/version.tc $(srcdir)/version.c + +# for backwards compatibility with the old makefiles +.PHONY: realclean +realclean: maintainer-clean diff --git a/contrib/cvs/src/Makefile.in b/contrib/cvs/src/Makefile.in index d09b0cb..c80deab 100644 --- a/contrib/cvs/src/Makefile.in +++ b/contrib/cvs/src/Makefile.in @@ -1,6 +1,20 @@ +# Makefile.in generated automatically by automake 1.4e from Makefile.am. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + # Makefile for GNU CVS program. -# Do not use this makefile directly, but only from `../Makefile'. -# Copyright (C) 1986, 1988-1990 Free Software Foundation, Inc. +# Copyright (C) 1986, 1988-1990, 2000 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 @@ -12,182 +26,584 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -SHELL = /bin/sh -srcdir = @srcdir@ +srcdir = @srcdir@ top_srcdir = @top_srcdir@ -VPATH = @srcdir@ - +VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ -# Where to install the executables. bindir = @bindir@ - -# Where to put the system-wide .cvsrc file +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ libdir = @libdir@ - -# Where to put the manual pages. +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@ -# Use cp if you don't have install. INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +AMTAR = @AMTAR@ +AWK = @AWK@ +CC = @CC@ +CSH = @CSH@ +DEPDIR = @DEPDIR@ +ETAGS = @ETAGS@ +ETAGS_INCLUDE_OPTION = @ETAGS_INCLUDE_OPTION@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTALL_STRIP_PROGRAM_ENV = @INSTALL_STRIP_PROGRAM_ENV@ +KRB4 = @KRB4@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +PERL = @PERL@ +PR = @PR@ +PS2PDF = @PS2PDF@ +RANLIB = @RANLIB@ +ROFF = @ROFF@ +STRIP = @STRIP@ +TEXI2DVI = @TEXI2DVI@ +VERSION = @VERSION@ +YACC = @YACC@ +_am_include = @_am_include@ +_am_quote = @_am_quote@ +includeopt = @includeopt@ +install_sh = @install_sh@ -LIBS = @LIBS@ +SHELL = /bin/sh -SOURCES = add.c admin.c buffer.c checkin.c checkout.c classify.c client.c \ -commit.c create_adm.c cvsrc.c diff.c edit.c entries.c error.c expand_path.c \ -fileattr.c find_names.c hardlink.c hash.c history.c ignore.c import.c \ -lock.c log.c login.c logmsg.c main.c mkmodules.c modules.c myndbm.c no_diff.c \ -parseinfo.c patch.c rcs.c rcscmds.c recurse.c release.c remove.c repos.c \ -root.c rtag.c scramble.c server.c status.c subr.c filesubr.c run.c \ -tag.c update.c watch.c wrapper.c vers_ts.c version.c zlib.c +# $(includeopt) is CVS specific and set by configure +# FIXME - This includes line is dependant on its order. This means there is +# some namespace hackery going on that maybe shouldn't be. Long term fix is to +# try and remove naming ocnflicts and fix Automake to allow particular includes +# to be attached only to particular object files. Short term fix is either or. +INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/diff -I$(top_srcdir)/zlib $(includeopt) + +bin_PROGRAMS = cvs +bin_SCRIPTS = cvsbug + +# The cvs executable +cvs_SOURCES = \ + add.c \ + admin.c \ + annotate.c \ + buffer.c \ + checkin.c \ + checkout.c \ + classify.c \ + client.c \ + commit.c \ + create_adm.c \ + cvsrc.c diff.c \ + edit.c \ + entries.c \ + error.c \ + expand_path.c \ + fileattr.c \ + filesubr.c \ + find_names.c \ + hardlink.c \ + hash.c \ + history.c \ + ignore.c \ + import.c \ + lock.c \ + log.c \ + login.c \ + logmsg.c \ + main.c \ + mkmodules.c \ + modules.c \ + myndbm.c \ + no_diff.c \ + parseinfo.c \ + patch.c \ + rcs.c \ + rcscmds.c \ + recurse.c \ + release.c \ + remove.c \ + repos.c \ + root.c \ + run.c \ + scramble.c \ + server.c \ + status.c \ + subr.c \ + tag.c \ + update.c \ + vers_ts.c \ + watch.c \ + wrapper.c \ + zlib.c \ + buffer.h \ + client.h \ + cvs.h \ + edit.h \ + error.h \ + fileattr.h \ + hardlink.h \ + hash.h \ + myndbm.h \ + rcs.h \ + server.h \ + update.h \ + watch.h + +cvs_LDADD = \ + ../diff/libdiff.a \ + ../lib/libcvs.a \ + ../zlib/libz.a \ + version.o + +cvs_EXTRA_DIST = version.c + +# extra clean targets +# wish this could be distclean-hdr-local but it's not part of automake +DISTCLEANFILES = options.h-SAVED check.log check.plog + +# General +EXTRA_DIST = \ + $(cvs_EXTRA_DIST) \ + .cvsignore \ + ChangeLog-9194 \ + ChangeLog-9395 \ + ChangeLog-96 \ + ChangeLog-97 \ + build_src.com \ + sanity.sh \ + version.c \ + version.c.in + +EXEEXT = +OBJEXT = o +subdir = src +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h options.h +CONFIG_CLEAN_FILES = cvsbug +bin_PROGRAMS = cvs$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) + +am_cvs_OBJECTS = add.$(OBJEXT) admin.$(OBJEXT) annotate.$(OBJEXT) \ + buffer.$(OBJEXT) checkin.$(OBJEXT) checkout.$(OBJEXT) \ + classify.$(OBJEXT) client.$(OBJEXT) commit.$(OBJEXT) \ + create_adm.$(OBJEXT) cvsrc.$(OBJEXT) diff.$(OBJEXT) \ + edit.$(OBJEXT) entries.$(OBJEXT) error.$(OBJEXT) \ + expand_path.$(OBJEXT) fileattr.$(OBJEXT) filesubr.$(OBJEXT) \ + find_names.$(OBJEXT) hardlink.$(OBJEXT) hash.$(OBJEXT) \ + history.$(OBJEXT) ignore.$(OBJEXT) import.$(OBJEXT) \ + lock.$(OBJEXT) log.$(OBJEXT) login.$(OBJEXT) logmsg.$(OBJEXT) \ + main.$(OBJEXT) mkmodules.$(OBJEXT) modules.$(OBJEXT) \ + myndbm.$(OBJEXT) no_diff.$(OBJEXT) parseinfo.$(OBJEXT) \ + patch.$(OBJEXT) rcs.$(OBJEXT) rcscmds.$(OBJEXT) \ + recurse.$(OBJEXT) release.$(OBJEXT) remove.$(OBJEXT) \ + repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) scramble.$(OBJEXT) \ + server.$(OBJEXT) status.$(OBJEXT) subr.$(OBJEXT) tag.$(OBJEXT) \ + update.$(OBJEXT) vers_ts.$(OBJEXT) watch.$(OBJEXT) \ + wrapper.$(OBJEXT) zlib.$(OBJEXT) +cvs_OBJECTS = $(am_cvs_OBJECTS) +cvs_DEPENDENCIES = ../diff/libdiff.a ../lib/libcvs.a ../zlib/libz.a \ + version.o +cvs_LDFLAGS = +SCRIPTS = $(bin_SCRIPTS) + +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CFLAGS = @CFLAGS@ +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -OBJECTS = add.o admin.o buffer.o checkin.o checkout.o classify.o client.o \ -commit.o create_adm.o cvsrc.o diff.o edit.o entries.o expand_path.o \ -fileattr.o find_names.o hardlink.o hash.o history.o ignore.o import.o \ -lock.o log.o login.o logmsg.o main.o mkmodules.o modules.o myndbm.o no_diff.o \ -parseinfo.o patch.o rcs.o rcscmds.o recurse.o release.o remove.o repos.o \ -root.o rtag.o scramble.o server.o status.o tag.o update.o \ -watch.o wrapper.o vers_ts.o \ -subr.o filesubr.o run.o version.o error.o zlib.o +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -I. +DEFS = @DEFS@ +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +DIST_SOURCES = $(cvs_SOURCES) +depcomp = $(SHELL) $(top_srcdir)/depcomp +@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/add.Po $(DEPDIR)/admin.Po \ +@AMDEP_TRUE@ $(DEPDIR)/annotate.Po $(DEPDIR)/buffer.Po \ +@AMDEP_TRUE@ $(DEPDIR)/checkin.Po $(DEPDIR)/checkout.Po \ +@AMDEP_TRUE@ $(DEPDIR)/classify.Po $(DEPDIR)/client.Po \ +@AMDEP_TRUE@ $(DEPDIR)/commit.Po $(DEPDIR)/create_adm.Po \ +@AMDEP_TRUE@ $(DEPDIR)/cvsrc.Po $(DEPDIR)/diff.Po \ +@AMDEP_TRUE@ $(DEPDIR)/edit.Po $(DEPDIR)/entries.Po \ +@AMDEP_TRUE@ $(DEPDIR)/error.Po $(DEPDIR)/expand_path.Po \ +@AMDEP_TRUE@ $(DEPDIR)/fileattr.Po $(DEPDIR)/filesubr.Po \ +@AMDEP_TRUE@ $(DEPDIR)/find_names.Po $(DEPDIR)/hardlink.Po \ +@AMDEP_TRUE@ $(DEPDIR)/hash.Po $(DEPDIR)/history.Po \ +@AMDEP_TRUE@ $(DEPDIR)/ignore.Po $(DEPDIR)/import.Po \ +@AMDEP_TRUE@ $(DEPDIR)/lock.Po $(DEPDIR)/log.Po \ +@AMDEP_TRUE@ $(DEPDIR)/login.Po $(DEPDIR)/logmsg.Po \ +@AMDEP_TRUE@ $(DEPDIR)/main.Po $(DEPDIR)/mkmodules.Po \ +@AMDEP_TRUE@ $(DEPDIR)/modules.Po $(DEPDIR)/myndbm.Po \ +@AMDEP_TRUE@ $(DEPDIR)/no_diff.Po $(DEPDIR)/parseinfo.Po \ +@AMDEP_TRUE@ $(DEPDIR)/patch.Po $(DEPDIR)/rcs.Po \ +@AMDEP_TRUE@ $(DEPDIR)/rcscmds.Po $(DEPDIR)/recurse.Po \ +@AMDEP_TRUE@ $(DEPDIR)/release.Po $(DEPDIR)/remove.Po \ +@AMDEP_TRUE@ $(DEPDIR)/repos.Po $(DEPDIR)/root.Po \ +@AMDEP_TRUE@ $(DEPDIR)/run.Po $(DEPDIR)/scramble.Po \ +@AMDEP_TRUE@ $(DEPDIR)/server.Po $(DEPDIR)/status.Po \ +@AMDEP_TRUE@ $(DEPDIR)/subr.Po $(DEPDIR)/tag.Po \ +@AMDEP_TRUE@ $(DEPDIR)/update.Po $(DEPDIR)/vers_ts.Po \ +@AMDEP_TRUE@ $(DEPDIR)/watch.Po $(DEPDIR)/wrapper.Po \ +@AMDEP_TRUE@ $(DEPDIR)/zlib.Po +DIST_COMMON = ./stamp-h2.in ChangeLog Makefile.am Makefile.in cvsbug.in \ + options.h.in +SOURCES = $(cvs_SOURCES) +OBJECTS = $(am_cvs_OBJECTS) + +all: options.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj + +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && \ + CONFIG_HEADERS= CONFIG_LINKS= \ + CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status + +options.h: stamp-h2 + @if test ! -f $@; then \ + rm -f stamp-h2; \ + $(MAKE) stamp-h2; \ + else :; fi +stamp-h2: $(srcdir)/options.h.in $(top_builddir)/config.status + @rm -f stamp-h2 stamp-h2T + @echo timestamp > stamp-h2T 2> /dev/null + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=src/options.h \ + $(SHELL) ./config.status + @mv stamp-h2T stamp-h2 +$(srcdir)/options.h.in: $(srcdir)/./stamp-h2.in + @if test ! -f $@; then \ + rm -f $(srcdir)/./stamp-h2.in; \ + $(MAKE) $(srcdir)/./stamp-h2.in; \ + else :; fi +$(srcdir)/./stamp-h2.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/acconfig.h + @rm -f $(srcdir)/./stamp-h2.in $(srcdir)/./stamp-h2.inT + @echo timestamp > $(srcdir)/./stamp-h2.inT 2> /dev/null + cd $(top_srcdir) && $(AUTOHEADER) + @mv $(srcdir)/./stamp-h2.inT $(srcdir)/./stamp-h2.in + +distclean-hdr: + -rm -f options.h +cvsbug: $(top_builddir)/config.status cvsbug.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$f"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$f; \ + else :; fi; \ + done -HEADERS = buffer.h cvs.h rcs.h hardlink.h hash.h myndbm.h \ - update.h server.h client.h error.h fileattr.h edit.h watch.h +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ + rm -f $(DESTDIR)$(bindir)/$$f; \ + done -TAGFILES = $(HEADERS) options.h.in $(SOURCES) +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +cvs$(EXEEXT): $(cvs_OBJECTS) $(cvs_DEPENDENCIES) + @rm -f cvs$(EXEEXT) + $(LINK) $(cvs_LDFLAGS) $(cvs_OBJECTS) $(cvs_LDADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + f="`echo $$p|sed '$(transform)'`"; \ + if test -f $$p; then \ + echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/$$f"; \ + $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/$$f; \ + elif test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/$$f"; \ + $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/$$f; \ + else :; fi; \ + done -DISTFILES = .cvsignore Makefile.in \ - ChangeLog ChangeLog-97 ChangeLog-96 ChangeLog-9395 ChangeLog-9194 \ - sanity.sh cvsbug.sh $(TAGFILES) build_src.com +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + f="`echo $$p|sed '$(transform)'`"; \ + echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ + rm -f $(DESTDIR)$(bindir)/$$f; \ + done -PROGS = cvs cvsbug +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(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; }'`; \ + mkid -fID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) options.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list @CONFIG@; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)options.h.in$$unique$(LISP)$$tags" \ + || $(ETAGS) $(ETAGS_ARGS) $$tags options.h.in $$unique $(LISP) + +GTAGS: + here=`CDPATH=: && cd $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $$here + +distclean-tags: + -rm -f TAGS ID + +@_am_include@ @_am_quote@$(DEPDIR)/add.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/admin.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/annotate.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/buffer.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/checkin.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/checkout.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/classify.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/client.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/commit.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/create_adm.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/cvsrc.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/diff.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/edit.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/entries.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/error.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/expand_path.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/fileattr.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/filesubr.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/find_names.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/hardlink.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/hash.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/history.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/ignore.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/import.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/lock.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/log.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/login.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/logmsg.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/main.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/mkmodules.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/modules.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/myndbm.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/no_diff.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/parseinfo.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/patch.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/rcs.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/rcscmds.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/recurse.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/release.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/remove.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/repos.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/root.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/run.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/scramble.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/server.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/status.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/subr.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/tag.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/update.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/vers_ts.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/watch.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/wrapper.Po@_am_quote@ +@_am_include@ @_am_quote@$(DEPDIR)/zlib.Po@_am_quote@ + +distclean-depend: + -rm -rf $(DEPDIR) + +CCDEPMODE = @CCDEPMODE@ -DEFS = @DEFS@ @includeopt@ +.c.o: + source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ + depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ + $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(COMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$< + +.c.obj: + source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ + depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ + $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(COMPILE) -c -o $@ `cygpath -w $<` + + +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile $(PROGRAMS) $(SCRIPTS) options.h -CC = @CC@ -CFLAGS = @CFLAGS@ -CPPFLAGS = -LDFLAGS = @LDFLAGS@ +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(bindir) -INCLUDES = -I. -I.. -I$(srcdir) -I$(top_srcdir)/lib -.c.o: - $(CC) $(CPPFLAGS) $(INCLUDES) $(DEFS) $(CFLAGS) -c $< +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am -all: Makefile $(PROGS) -.PHONY: all +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -saber_cvs: - @cd ..; $(MAKE) saber SUBDIRS=src +installcheck: installcheck-am -lint: - @cd ..; $(MAKE) lint SUBDIRS=src +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_PROGRAM_ENV='$(INSTALL_STRIP_PROGRAM_ENV)' install -install: installdirs - @for prog in $(PROGS); do \ - echo Installing $$prog in $(bindir); \ - $(INSTALL) $$prog $(bindir)/$$prog ; \ - done +mostlyclean-generic: -installdirs: - $(SHELL) $(top_srcdir)/mkinstalldirs $(bindir) +clean-generic: -.PHONY: install installdirs +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) -installcheck: - $(SHELL) $(srcdir)/sanity.sh $(bindir)/cvs -.PHONY: installcheck +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -rm -f Makefile.in +clean: clean-am -check: all - $(SHELL) $(srcdir)/sanity.sh `pwd`/cvs -.PHONY: check +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am -# I'm not sure there is any remaining reason for this to be separate from -# `make check'. -remotecheck: all - $(SHELL) $(srcdir)/sanity.sh -r `pwd`/cvs -.PHONY: remotecheck +distclean: distclean-am -tags: $(TAGFILES) - ctags $(TAGFILES) +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-hdr distclean-tags -TAGS: $(TAGFILES) - etags `for i in $(TAGFILES); do echo $(srcdir)/$$i; done` +dvi: -ls: - @echo $(DISTFILES) -.PHONY: ls +dvi-am: -clean: - rm -f $(PROGS) *.o core check.log check.plog -.PHONY: clean +info: -distclean: clean - rm -f tags TAGS Makefile options.h -.PHONY: distclean +info-am: -realclean: distclean -.PHONY: realclean +install-data-am: -dist-dir: - mkdir ${DISTDIR} - for i in ${DISTFILES}; do \ - ln $(srcdir)/$${i} ${DISTDIR}; \ - done -.PHONY: dist-dir +install-exec-am: install-binPROGRAMS install-binSCRIPTS -# Linking rules. +install-info: -$(PROGS): ../lib/libcvs.a ../zlib/libz.a ../diff/libdiff.a +install-man: -cvs: $(OBJECTS) - $(CC) $(OBJECTS) ../lib/libcvs.a ../zlib/libz.a ../diff/libdiff.a $(LIBS) $(LDFLAGS) -o $@ +installcheck-am: -xlint: $(SOURCES) - files= ; \ - for i in $(SOURCES) ; do \ - files="$$files $(srcdir)/$$i" ; \ - done ; \ - sh -c "lint $(DEFS) $(INCLUDES) $$files | grep -v \"possible pointer alignment problem\" \ - | grep -v \"argument closure unused\"" +maintainer-clean: maintainer-clean-am -saber: $(SOURCES) - # load $(CFLAGS) $(SOURCES) - # load ../lib/libcvs.a $(LIBS) +maintainer-clean-am: distclean-am maintainer-clean-generic -cvsbug: cvsbug.sh $(srcdir)/version.c - echo > .fname \ - cvs-`sed < $(srcdir)/version.c \ - -e '/version_string/!d' \ - -e 's/[^0-9.]*\([0-9.]*\).*/\1/' \ - -e q` - sed -e 's,xLIBDIRx,$(libdir)/cvs,g' \ - -e "s,xVERSIONx,`cat .fname`,g" $(srcdir)/$@.sh > $@-t - rm -f .fname - mv $@-t $@ - chmod a+x $@ +mostlyclean: mostlyclean-am -# Compilation rules. +mostlyclean-am: mostlyclean-compile mostlyclean-generic -$(OBJECTS): $(HEADERS) options.h +uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS -rcscmds.o: rcscmds.c $(top_srcdir)/diff/diffrun.h - $(CC) $(CPPFLAGS) $(INCLUDES) -I$(top_srcdir)/diff $(DEFS) $(CFLAGS) -c $(srcdir)/rcscmds.c +.PHONY: all all-am check check-am check-local clean clean-binPROGRAMS \ + clean-generic distclean distclean-compile distclean-depend \ + distclean-generic distclean-hdr distclean-tags distdir dvi \ + dvi-am info info-am install install-am install-binPROGRAMS \ + install-binSCRIPTS install-data install-data-am install-exec \ + install-exec-am install-info install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic tags uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-binSCRIPTS -zlib.o: zlib.c $(top_srcdir)/zlib/zlib.h - $(CC) $(CPPFLAGS) $(INCLUDES) -I$(top_srcdir)/zlib $(DEFS) $(CFLAGS) -c $(srcdir)/zlib.c -subdir = src -Makefile: ../config.status Makefile.in - cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status +check-local: + $(SHELL) $(srcdir)/sanity.sh `pwd`/cvs -options.h: ../config.status options.h.in - cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status +.PHONY: remotecheck +remotecheck: all + $(SHELL) $(srcdir)/sanity.sh -r `pwd`/cvs -#../config.status: ../configure -# cd .. ; $(SHELL) config.status --recheck +# version.c +# - build this here so that we can distribute it +# - version.c needs to be updated only once, since it depends on +# configure.in, not on the results of a 'configure' run. +# - It is guaranteed (with GNU Make) that when the version in configure.in +# is changed, acversion.m4 is built only after the new version number is +# propagated to the Makefile. (Libtool uses the same guarantee.) +# - need the explicit version.o dependency or else make won't match +# $(srcdir)/version.c when looking for a dependency for version.c +version.o: $(srcdir)/version.c +$(srcdir)/version.c: $(srcdir)/version.c.in $(top_srcdir)/configure.in + sed 's,@VERSION\@,$(VERSION),g' $(srcdir)/version.c.in >$(srcdir)/version.tc + mv $(srcdir)/version.tc $(srcdir)/version.c + +# for backwards compatibility with the old makefiles +.PHONY: realclean +realclean: maintainer-clean -#../configure: ../configure.in -# cd $(top_srcdir) ; autoconf +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/cvs/src/add.c b/contrib/cvs/src/add.c index dbefda5..9ec6a3d 100644 --- a/contrib/cvs/src/add.c +++ b/contrib/cvs/src/add.c @@ -93,7 +93,7 @@ add (argc, argv) if (argc <= 0) usage (add_usage); - cvsroot_len = strlen (CVSroot_directory); + cvsroot_len = strlen (current_parsed_root->directory); /* First some sanity checks. I know that the CVS case is (sort of) also handled by add_directory, but we need to check here so the @@ -111,7 +111,8 @@ add (argc, argv) || strcmp (argv[i], "..") == 0 || fncmp (argv[i], CVSADM) == 0) { - error (0, 0, "cannot add special file `%s'; skipping", argv[i]); + if (!quiet) + error (0, 0, "cannot add special file `%s'; skipping", argv[i]); skip_file = 1; } else @@ -147,7 +148,7 @@ add (argc, argv) } #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { int i; @@ -227,7 +228,7 @@ add (argc, argv) repository = Name_Repository (NULL, update_dir); /* don't add stuff to Emptydir */ - if (strncmp (repository, CVSroot_directory, cvsroot_len) == 0 + if (strncmp (repository, current_parsed_root->directory, cvsroot_len) == 0 && ISDIRSEP (repository[cvsroot_len]) && strncmp (repository + cvsroot_len + 1, CVSROOTADM, @@ -323,7 +324,7 @@ add (argc, argv) repository = Name_Repository (NULL, finfo.update_dir); /* don't add stuff to Emptydir */ - if (strncmp (repository, CVSroot_directory, cvsroot_len) == 0 + if (strncmp (repository, current_parsed_root->directory, cvsroot_len) == 0 && ISDIRSEP (repository[cvsroot_len]) && strncmp (repository + cvsroot_len + 1, CVSROOTADM, @@ -356,7 +357,7 @@ add (argc, argv) error (1, errno, "cannot read directory %s", finfo.repository); found_name = NULL; errno = 0; - while ((dp = readdir (dirp)) != NULL) + while ((dp = CVS_READDIR (dirp)) != NULL) { if (cvs_casecmp (dp->d_name, finfo.file) == 0) { @@ -368,7 +369,7 @@ add (argc, argv) } if (errno != 0) error (1, errno, "cannot read directory %s", finfo.repository); - closedir (dirp); + CVS_CLOSEDIR (dirp); if (found_name != NULL) { @@ -448,8 +449,8 @@ add (argc, argv) if (vers->nonbranch) { error (0, 0, - "cannot add file on non-branch tag %s", - vers->tag); + "cannot add file on non-branch tag %s", + vers->tag); ++err; } else @@ -505,18 +506,21 @@ same name already exists in the repository."); } else { - if (vers->tag) - error (0, 0, "\ + 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); - 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, "\ + 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); + finfo.fullname, vers->vn_rcs); + } Register (entries, finfo.file, "0", vers->ts_user, vers->options, vers->tag, NULL, NULL); @@ -542,7 +546,8 @@ re-adding file %s (in place of dead revision %s)", * An entry for a new-born file, ts_rcs is dummy, but that is * inappropriate here */ - error (0, 0, "%s has already been entered", finfo.fullname); + if (!quiet) + error (0, 0, "%s has already been entered", finfo.fullname); err++; } else if (vers->vn_user[0] == '-') @@ -607,9 +612,10 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname); else { /* A normal entry, ts_rcs is valid, so it must already be there */ - error (0, 0, "%s already exists, with version number %s", - finfo.fullname, - vers->vn_user); + if (!quiet) + error (0, 0, "%s already exists, with version number %s", + finfo.fullname, + vers->vn_user); err++; } freevers_ts (&vers); @@ -641,7 +647,7 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname); free (found_name); #endif } - if (added_files) + if (added_files && !really_quiet) error (0, 0, "use '%s commit' to add %s permanently", program_name, (added_files == 1) ? "this file" : "these files"); diff --git a/contrib/cvs/src/admin.c b/contrib/cvs/src/admin.c index 637663a..359bedf 100644 --- a/contrib/cvs/src/admin.c +++ b/contrib/cvs/src/admin.c @@ -46,13 +46,13 @@ static const char *const admin_usage[] = "\t revision on the default branch.\n", "\t-N tag[:[rev]] Same as -n except override existing tag.\n", "\t-o range Delete (outdate) specified range of revisions:\n", + "\t rev1:rev2 Between rev1 and rev2, including rev1 and rev2.\n", "\t rev1::rev2 Between rev1 and rev2, excluding rev1 and rev2.\n", + "\t rev: rev and following revisions on the same branch.\n", "\t rev:: After rev on the same branch.\n", + "\t :rev rev and previous revisions on the same branch.\n", "\t ::rev Before rev on the same branch.\n", "\t rev Just rev.\n", - "\t rev1:rev2 Between rev1 and rev2, including rev1 and rev2.\n", - "\t rev: rev and following revisions on the same branch.\n", - "\t :rev rev and previous revisions on the same branch.\n", "\t-q Run quietly.\n", "\t-s state[:rev] Set revision state (latest revision on branch,\n", "\t latest revision on trunk if omitted).\n", @@ -97,10 +97,6 @@ struct admin_data /* Interactive (-I). Problematic with client/server. */ int interactive; - /* Quiet (-q). Not the same as the global -q option, which is a bit - on the confusing side, perhaps. */ - int quiet; - /* This is the cheesy part. It is a vector with the options which we don't deal with above (e.g. "-afoo" "-abar,baz"). In the future this presumably will be replaced by other variables which break @@ -337,7 +333,15 @@ admin (argc, argv) break; case 'q': - admin_data.quiet = 1; + /* Silently set the global really_quiet flag. This keeps admin in + * sync with the RCS man page and allows us to silently support + * older servers when necessary. + * + * Some logic says we might want to output a deprecation warning + * here, but I'm opting not to in order to stay quietly in sync + * with the RCS man page. + */ + really_quiet = 1; break; case 'x': @@ -372,29 +376,40 @@ admin (argc, argv) argv += optind; #ifdef CVS_ADMIN_GROUP - grp = getgrnam(CVS_ADMIN_GROUP); - /* skip usage right check if group CVS_ADMIN_GROUP does not exist */ - if (grp != NULL) + /* The use of `cvs admin -k' is unrestricted. However, any other + option is restricted if the group CVS_ADMIN_GROUP exists. */ + if (!only_k_option && + (grp = getgrnam(CVS_ADMIN_GROUP)) != NULL) { +#ifdef HAVE_GETGROUPS + gid_t *grps; + int n; + + /* get number of auxiliary groups */ + n = getgroups (0, NULL); + if (n < 0) + error (1, errno, "unable to get number of auxiliary groups"); + grps = (gid_t *) xmalloc((n + 1) * sizeof *grps); + n = getgroups (n, grps); + if (n < 0) + error (1, errno, "unable to get list of auxiliary groups"); + grps[n] = getgid(); + for (i = 0; i <= n; i++) + if (grps[i] == grp->gr_gid) break; + free (grps); + if (i > n) + error (1, 0, "usage is restricted to members of the group %s", + CVS_ADMIN_GROUP); +#else char *me = getcaller(); - char **grnam = grp->gr_mem; - /* The use of `cvs admin -k' is unrestricted. However, any - other option is restricted. */ - int denied = ! only_k_option; + char **grnam; - while (*grnam) - { - if (strcmp(*grnam, me) == 0) - { - denied = 0; - break; - } - grnam++; - } - - if (denied) + for (grnam = grp->gr_mem; *grnam; grnam++) + if (strcmp (*grnam, me) == 0) break; + if (!*grnam && getgid() != grp->gr_gid) error (1, 0, "usage is restricted to members of the group %s", CVS_ADMIN_GROUP); +#endif } #endif @@ -427,7 +442,7 @@ admin (argc, argv) } #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { /* We're the client side. Fire up the remote server. */ start_server (); @@ -470,7 +485,10 @@ admin (argc, argv) } send_to_server ("\012", 1); } - if (admin_data.quiet) + /* Send this for all really_quiets since we know that it will be silently + * ignored when unneeded. This supports old servers. + */ + if (really_quiet) send_arg ("-q"); if (admin_data.kflag != NULL) send_arg (admin_data.kflag); @@ -486,7 +504,7 @@ admin (argc, argv) } #endif /* CLIENT_SUPPORT */ - lock_tree_for_write (argc, argv, 0, 0); + lock_tree_for_write (argc, argv, 0, W_LOCAL, 0); err = start_recursion (admin_fileproc, (FILESDONEPROC) NULL, admin_dirproc, (DIRLEAVEPROC) NULL, (void *)&admin_data, @@ -546,7 +564,7 @@ admin_fileproc (callerdat, finfo) status = 0; - if (!admin_data->quiet) + if (!really_quiet) { cvs_output ("RCS file: ", 0); cvs_output (rcs->path, 0); @@ -767,9 +785,10 @@ admin_fileproc (callerdat, finfo) } else { - error (0, 0, - "%s: Symbolic name or revision %s is undefined", - rcs->path, p); + if (!really_quiet) + error (0, 0, + "%s: Symbolic name or revision %s is undefined.", + rcs->path, p); status = 1; } free (tag); @@ -854,12 +873,10 @@ admin_fileproc (callerdat, finfo) } } - /* TODO: reconcile the weird discrepancies between - admin_data->quiet and quiet. */ if (status == 0) { RCS_rewrite (rcs, NULL, NULL); - if (!admin_data->quiet) + if (!really_quiet) cvs_output ("done\n", 5); } else @@ -868,7 +885,8 @@ admin_fileproc (callerdat, finfo) message has given a more specific error. The point of this additional message is to make it clear that the previous problems caused CVS to forget about the idea of modifying the RCS file. */ - error (0, 0, "cannot modify RCS file for `%s'", finfo->file); + if (!really_quiet) + error (0, 0, "RCS file for `%s' not modified.", finfo->file); RCS_abandon (rcs); } diff --git a/contrib/cvs/src/annotate.c b/contrib/cvs/src/annotate.c new file mode 100644 index 0000000..827619d --- /dev/null +++ b/contrib/cvs/src/annotate.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 1992, Brian Berliner and Jeff Polk + * Copyright (c) 1989-1992, Brian Berliner + * + * You may distribute under the terms of the GNU General Public License as + * specified in the README file that comes with the CVS source distribution. + * + * Show last revision where each line modified + * + * Prints the specified files with each line annotated with the revision + * number where it was last modified. With no argument, annotates all + * all the files in the directory (recursive by default). + */ + +#include "cvs.h" + +/* Options from the command line. */ + +static int force_tag_match = 1; +static char *tag = NULL; +static int tag_validated; +static char *date = NULL; + +static int is_rannotate; + +static int annotate_fileproc PROTO ((void *callerdat, struct file_info *)); +static int rannotate_proc PROTO((int argc, char **argv, char *xwhere, + char *mwhere, char *mfile, int shorten, + int local, char *mname, char *msg)); + +static const char *const annotate_usage[] = +{ + "Usage: %s %s [-lRf] [-r rev] [-D date] [files...]\n", + "\t-l\tLocal directory only, no recursion.\n", + "\t-R\tProcess directories recursively.\n", + "\t-f\tUse head revision if tag/date not found.\n", + "\t-r rev\tAnnotate file as of specified revision/tag.\n", + "\t-D date\tAnnotate file as of specified date.\n", + "(Specify the --help global option for a list of other help options)\n", + NULL +}; + +/* Command to show the revision, date, and author where each line of a + file was modified. */ + +int +annotate (argc, argv) + int argc; + char **argv; +{ + int local = 0; + int err = 0; + int c; + + is_rannotate = (strcmp(command_name, "rannotate") == 0); + + if (argc == -1) + usage (annotate_usage); + + optind = 0; + while ((c = getopt (argc, argv, "+lr:D:fR")) != -1) + { + switch (c) + { + case 'l': + local = 1; + break; + case 'R': + local = 0; + break; + case 'r': + tag = optarg; + break; + case 'D': + date = Make_Date (optarg); + break; + case 'f': + force_tag_match = 0; + break; + case '?': + default: + usage (annotate_usage); + break; + } + } + argc -= optind; + argv += optind; + +#ifdef CLIENT_SUPPORT + if (current_parsed_root->isremote) + { + start_server (); + + if (is_rannotate && !supported_request ("rannotate")) + error (1, 0, "server does not support rannotate"); + + ign_setup (); + + if (local) + send_arg ("-l"); + if (!force_tag_match) + send_arg ("-f"); + option_with_arg ("-r", tag); + if (date) + client_senddate (date); + if (is_rannotate) + { + int i; + for (i = 0; i < argc; i++) + send_arg (argv[i]); + send_to_server ("rannotate\012", 0); + } + else + { + send_files (argc, argv, local, 0, SEND_NO_CONTENTS); + send_file_names (argc, argv, SEND_EXPAND_WILD); + send_to_server ("annotate\012", 0); + } + return get_responses_and_close (); + } +#endif /* CLIENT_SUPPORT */ + + if (is_rannotate) + { + DBM *db; + int i; + db = open_module (); + for (i = 0; i < argc; i++) + { + err += do_module (db, argv[i], MISC, "Annotating", rannotate_proc, + (char *) NULL, 0, 0, 0, 0, (char *) NULL); + } + close_module (db); + } + else + { + err = rannotate_proc (argc + 1, argv - 1, (char *) NULL, + (char *) NULL, (char *) NULL, 0, 0, (char *) NULL, + (char *) NULL); + } + + return err; +} + + +static int +rannotate_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg) + int argc; + char **argv; + char *xwhere; + char *mwhere; + char *mfile; + int shorten; + int local; + char *mname; + char *msg; +{ + /* Begin section which is identical to patch_proc--should this + be abstracted out somehow? */ + char *myargv[2]; + int err = 0; + int which; + char *repository; + char *where; + + if (is_rannotate) + { + 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) + + 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 != NULL) + { + char *cp; + char *path; + + /* 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); + mfile = cp + 1; + } + + /* take care of the rest */ + path = xmalloc (strlen (repository) + strlen (mfile) + 5); + (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); + } + else + { + myargv[0] = argv[0]; + myargv[1] = mfile; + argc = 2; + argv = myargv; + } + free (path); + } + + /* cd to the starting repository */ + if ( CVS_CHDIR (repository) < 0) + { + error (0, errno, "cannot chdir to %s", repository); + 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 + { + where = NULL; + which = W_LOCAL; + repository = ""; + } + + if (tag != NULL && !tag_validated) + { + tag_check_valid (tag, argc - 1, argv + 1, local, 0, repository); + tag_validated = 1; + } + + err = start_recursion (annotate_fileproc, (FILESDONEPROC) NULL, + (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, + argc - 1, argv + 1, local, which, 0, 1, + where, 1); + return err; +} + + +static int +annotate_fileproc (callerdat, finfo) + void *callerdat; + struct file_info *finfo; +{ + char *version; + + if (finfo->rcs == NULL) + return (1); + + if (finfo->rcs->flags & PARTIAL) + RCS_reparsercsfile (finfo->rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); + + version = RCS_getversion (finfo->rcs, tag, date, force_tag_match, + (int *) NULL); + if (version == NULL) + return 0; + + /* Distinguish output for various files if we are processing + several files. */ + cvs_outerr ("Annotations for ", 0); + cvs_outerr (finfo->fullname, 0); + cvs_outerr ("\n***************\n", 0); + + RCS_deltas (finfo->rcs, (FILE *) NULL, (struct rcsbuffer *) NULL, + version, RCS_ANNOTATE, NULL, NULL, NULL, NULL); + free (version); + return 0; +} diff --git a/contrib/cvs/src/checkout.c b/contrib/cvs/src/checkout.c index 1a66b5b..86dc951 100644 --- a/contrib/cvs/src/checkout.c +++ b/contrib/cvs/src/checkout.c @@ -44,7 +44,7 @@ static int checkout_proc PROTO((int argc, char **argv, char *where, static const char *const checkout_usage[] = { - "Usage:\n %s %s [-ANPRcflnps] [-r rev | -D date] [-d dir]\n", + "Usage:\n %s %s [-ANPRcflnps] [-r rev] [-D date] [-d dir]\n", " [-j rev1] [-j rev2] [-k kopt] modules...\n", "\t-A\tReset any sticky tags/date/kopts.\n", "\t-N\tDon't shorten module paths if -d specified.\n", @@ -59,7 +59,7 @@ static const char *const checkout_usage[] = "\t-r rev\tCheck out revision or tag. (implies -P) (is sticky)\n", "\t-D date\tCheck out revisions as of date. (implies -P) (is sticky)\n", "\t-d dir\tCheck out into dir instead of module name.\n", - "\t-k kopt\tUse RCS kopt -k option on checkout.\n", + "\t-k kopt\tUse RCS kopt -k option on checkout. (is sticky)\n", "\t-j rev\tMerge in changes made between current revision and rev.\n", "(Specify the --help global option for a list of other help options)\n", NULL @@ -67,7 +67,7 @@ static const char *const checkout_usage[] = static const char *const export_usage[] = { - "Usage: %s %s [-NRfln] [-r rev | -D date] [-d dir] [-k kopt] module...\n", + "Usage: %s %s [-NRfln] [-r rev] [-D date] [-d dir] [-k kopt] module...\n", "\t-N\tDon't shorten module paths if -d specified.\n", "\t-f\tForce a head revision match if tag/date not found.\n", "\t-l\tLocal directory only, not recursive\n", @@ -190,7 +190,7 @@ checkout (argc, argv) shorten = 1; break; case 's': - status = 1; + cat = status = 1; break; case 'f': force_tag_match = 0; @@ -223,10 +223,10 @@ checkout (argc, argv) if (shorten == -1) shorten = 0; - if ((cat || status) && argc != 0) + if (cat && argc != 0) error (1, 0, "-c and -s must not get any arguments"); - if (!(cat || status) && argc == 0) + if (!cat && argc == 0) error (1, 0, "must specify at least one module or directory"); if (where && pipeout) @@ -248,12 +248,12 @@ checkout (argc, argv) } #endif - if (!safe_location()) { + if (!cat && !safe_location()) { error(1, 0, "Cannot check out files into the repository itself"); } #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { int expand_modules; @@ -269,7 +269,7 @@ checkout (argc, argv) below in !expand_modules), those files (CVS/Checkin.prog or CVS/Update.prog) don't get created. Grrr. */ - expand_modules = (!cat && !status && !pipeout + expand_modules = (!cat && !pipeout && supported_request ("expand-modules")); if (expand_modules) @@ -296,7 +296,7 @@ checkout (argc, argv) if (checkout_prune_dirs && m_type == CHECKOUT) send_arg("-P"); client_prune_dirs = checkout_prune_dirs; - if (cat) + if (cat && !status) send_arg("-c"); if (where != NULL) option_with_arg ("-d", where); @@ -329,7 +329,7 @@ checkout (argc, argv) } #endif /* CLIENT_SUPPORT */ - if (cat || status) + if (cat) { cat_module (status); if (options) @@ -367,7 +367,7 @@ checkout (argc, argv) for (i = 0; i < argc; i++) err += do_module (db, argv[i], m_type, "Updating", checkout_proc, - where, shorten, local, run_module_prog, + where, shorten, local, run_module_prog, !pipeout, (char *) NULL); close_module (db); if (options) @@ -391,13 +391,13 @@ safe_location () /* 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(CVSroot_directory, hardpath, sizeof hardpath - 1); + x = readlink(current_parsed_root->directory, hardpath, sizeof hardpath - 1); #else x = -1; #endif if (x == -1) { - strcpy(hardpath, CVSroot_directory); + strcpy(hardpath, current_parsed_root->directory); } else { @@ -466,8 +466,8 @@ build_one_dir (repository, dirpath, sticky) error (1, 0, "there is no repository %s", repository); if (Create_Admin (".", dirpath, repository, - sticky ? (char *) NULL : tag, - sticky ? (char *) NULL : date, + sticky ? tag : (char *) NULL, + sticky ? date : (char *) NULL, /* FIXME? This is a guess. If it is important for nonbranch to be set correctly here I @@ -529,11 +529,11 @@ checkout_proc (argc, argv, where_orig, mwhere, mfile, shorten, /* Set up the repository (maybe) for the bottom directory. Allocate more space than we need so we don't need to keep reallocating this string. */ - repository = xmalloc (strlen (CVSroot_directory) + repository = xmalloc (strlen (current_parsed_root->directory) + strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile)) + 10); - (void) sprintf (repository, "%s/%s", CVSroot_directory, argv[0]); + (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]); Sanitize_Repository_Name (repository); @@ -709,11 +709,11 @@ checkout_proc (argc, argv, where_orig, mwhere, mfile, shorten, struct dir_to_build *head; char *reposcopy; - if (strncmp (repository, CVSroot_directory, - strlen (CVSroot_directory)) != 0) + if (strncmp (repository, current_parsed_root->directory, + strlen (current_parsed_root->directory)) != 0) error (1, 0, "\ internal error: %s doesn't start with %s in checkout_proc", - repository, CVSroot_directory); + repository, current_parsed_root->directory); /* We always create at least one directory, which corresponds to the entire strings for WHERE and REPOSITORY. */ @@ -798,7 +798,7 @@ internal error: %s doesn't start with %s in checkout_proc", bar -> Emptydir (generated dir -- not in repos) baz -> quux (finally!) */ - if (strcmp (reposcopy, CVSroot_directory) == 0) + if (strcmp (reposcopy, current_parsed_root->directory) == 0) { /* We can't walk up past CVSROOT. Instead, the repository should be Emptydir. */ @@ -806,55 +806,30 @@ internal error: %s doesn't start with %s in checkout_proc", } else { - if ((where_orig != NULL) - && (strcmp (new->dirpath, where_orig) == 0)) - { - /* It's the case that the user specified a - * destination directory with the "-d" flag. The - * repository in this directory should be "." - * since the user's command is equivalent to: - * - * cd ; cvs co blah */ - - strcpy (reposcopy, CVSroot_directory); - goto allocate_repos; - } - else if (mwhere != NULL) - { - /* This is a generated directory, so point to - CVSNULLREPOS. */ - - new->repository = emptydir_name (); - } - else - { - /* It's a directory in the repository! */ + /* It's a directory in the repository! */ - char *rp; + char *rp; - /* We'll always be below CVSROOT, but check for - paranoia's sake. */ - rp = strrchr (reposcopy, '/'); - if (rp == NULL) - error (1, 0, - "internal error: %s doesn't contain a slash", - reposcopy); + /* We'll always be below CVSROOT, but check for + paranoia's sake. */ + rp = strrchr (reposcopy, '/'); + if (rp == NULL) + error (1, 0, + "internal error: %s doesn't contain a slash", + reposcopy); - *rp = '\0'; - - allocate_repos: - new->repository = xmalloc (strlen (reposcopy) + 5); - (void) strcpy (new->repository, reposcopy); + *rp = '\0'; + new->repository = xmalloc (strlen (reposcopy) + 5); + (void) strcpy (new->repository, reposcopy); - if (strcmp (reposcopy, CVSroot_directory) == 0) - { - /* Special case -- the repository name needs - to be "/path/to/repos/." (the trailing dot - is important). We might be able to get rid - of this after the we check out the other - code that handles repository names. */ - (void) strcat (new->repository, "/."); - } + if (strcmp (reposcopy, current_parsed_root->directory) == 0) + { + /* Special case -- the repository name needs + to be "/path/to/repos/." (the trailing dot + is important). We might be able to get rid + of this after the we check out the other + code that handles repository names. */ + (void) strcat (new->repository, "/."); } } } @@ -866,7 +841,7 @@ internal error: %s doesn't start with %s in checkout_proc", int where_is_absolute = isabsolute (where); /* The top-level CVSADM directory should always be - CVSroot_directory. Create it, but only if WHERE is + 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 @@ -880,7 +855,7 @@ internal error: %s doesn't start with %s in checkout_proc", { /* It may be argued that we shouldn't set any sticky bits for the top-level repository. FIXME? */ - build_one_dir (CVSroot_directory, ".", argc <= 1); + build_one_dir (current_parsed_root->directory, ".", argc <= 1); #ifdef SERVER_SUPPORT /* We _always_ want to have a top-level admin @@ -892,7 +867,7 @@ internal error: %s doesn't start with %s in checkout_proc", will be ignored on the client side. */ if (server_active) - server_clear_entstat (".", CVSroot_directory); + server_clear_entstat (".", current_parsed_root->directory); #endif } @@ -1033,7 +1008,7 @@ 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); + preload_update_dir, m_type == CHECKOUT); goto out; } @@ -1089,7 +1064,7 @@ 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); + join_rev2, preload_update_dir, m_type == CHECKOUT); out: free (preload_update_dir); preload_update_dir = oldupdate; @@ -1121,11 +1096,11 @@ emptydir_name () { char *repository; - repository = xmalloc (strlen (CVSroot_directory) + repository = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) + sizeof (CVSNULLREPOS) - + 10); - (void) sprintf (repository, "%s/%s/%s", CVSroot_directory, + + 3); + (void) sprintf (repository, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, CVSNULLREPOS); if (!isfile (repository)) { diff --git a/contrib/cvs/src/classify.c b/contrib/cvs/src/classify.c index b0084a3..9a6489e 100644 --- a/contrib/cvs/src/classify.c +++ b/contrib/cvs/src/classify.c @@ -74,6 +74,7 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp, } else if (RCS_isdead (vers->srcfile, vers->vn_rcs)) { + /* there is an RCS file, but it's dead */ if (vers->ts_user == NULL) ret = T_UPTODATE; else @@ -83,43 +84,17 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp, ret = T_UNKNOWN; } } - else + else if (!pipeout && vers->ts_user && No_Difference (finfo, vers)) { - /* there is an rcs file */ - - if (vers->ts_user == NULL) - { - /* There is no user file; needs checkout */ - ret = T_CHECKOUT; - } - else - { - if (pipeout) - { - /* - * The user file doesn't necessarily have anything - * to do with this. - */ - ret = T_CHECKOUT; - } - /* - * There is a user file; print a warning and add it to the - * conflict list, only if it is indeed different from what we - * plan to extract - */ - else if (No_Difference (finfo, vers)) - { - /* the files were different so it is a conflict */ - if (!really_quiet) - error (0, 0, "move away %s; it is in the way", - finfo->fullname); - ret = T_CONFLICT; - } - else - /* since there was no difference, still needs checkout */ - ret = T_CHECKOUT; - } + /* the files were different so it is a conflict */ + if (!really_quiet) + error (0, 0, "move away %s; it is in the way", + finfo->fullname); + ret = T_CONFLICT; } + else + /* no user file or no difference, just checkout */ + ret = T_CHECKOUT; } else if (strcmp (vers->vn_user, "0") == 0) { @@ -135,44 +110,35 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp, error (0, 0, "warning: new-born %s has disappeared", finfo->fullname); ret = T_REMOVE_ENTRY; } + else if (vers->vn_rcs == NULL || + RCS_isdead (vers->srcfile, vers->vn_rcs)) + /* No RCS file or RCS file revision is dead */ + ret = T_ADDED; else { - /* There is a user file */ - - if (vers->vn_rcs == NULL) - /* There is no RCS file, added file */ - ret = T_ADDED; - else if (RCS_isdead (vers->srcfile, vers->vn_rcs)) - /* we are resurrecting. */ - ret = T_ADDED; + if (vers->srcfile->flags & INATTIC + && vers->srcfile->flags & VALID) + { + /* This file has been added on some branch other than + the one we are looking at. In the branch we are + looking at, the file was already valid. */ + if (!really_quiet) + error (0, 0, + "conflict: %s has been added, but already exists", + finfo->fullname); + } else { - if (vers->srcfile->flags & INATTIC - && vers->srcfile->flags & VALID) - { - /* This file has been added on some branch other than - the one we are looking at. In the branch we are - looking at, the file was already valid. */ - if (!really_quiet) - error (0, 0, - "\ -conflict: %s has been added, but already exists", - finfo->fullname); - } - else - { - /* - * There is an RCS file, so someone else must have checked - * one in behind our back; conflict - */ - if (!really_quiet) - error (0, 0, - "\ -conflict: %s created independently by second party", - finfo->fullname); - } - ret = T_CONFLICT; + /* + * There is an RCS file, so someone else must have checked + * one in behind our back; conflict + */ + if (!really_quiet) + error (0, 0, + "conflict: %s created independently by second party", + finfo->fullname); } + ret = T_CONFLICT; } } else if (vers->vn_user[0] == '-') @@ -193,14 +159,18 @@ conflict: %s created independently by second party", */ ret = T_REMOVE_ENTRY; } - else if (vers->vn_rcs == NULL - ? vers->vn_user[1] == '\0' - : strcmp (vers->vn_rcs, vers->vn_user + 1) == 0) + else if (strcmp (vers->vn_rcs, vers->vn_user + 1) == 0) /* * The RCS file is the same version as the user file was, and * that's OK; remove it */ ret = T_REMOVED; + else if (pipeout) + /* + * The RCS file doesn't match the user's file, but it doesn't + * matter in this case + */ + ret = T_NEEDS_MERGE; else { @@ -227,7 +197,7 @@ conflict: %s created independently by second party", else { /* A normal entry, TS_Rcs is valid */ - if (vers->vn_rcs == NULL) + if (vers->vn_rcs == NULL || RCS_isdead (vers->srcfile, vers->vn_rcs)) { /* There is no RCS file */ @@ -251,30 +221,23 @@ conflict: %s created independently by second party", finfo->fullname); ret = T_REMOVE_ENTRY; } - else + else if (No_Difference (finfo, vers)) { - /* - * The user file has been modified and since it is no longer - * in the repository, a conflict is raised - */ - if (No_Difference (finfo, vers)) - { - /* they are different -> conflict */ - if (!really_quiet) - error (0, 0, + /* they are different -> conflict */ + if (!really_quiet) + error (0, 0, "conflict: %s is modified but no longer in the repository", finfo->fullname); - ret = T_CONFLICT; - } - else - { - /* they weren't really different */ - if (!really_quiet) - error (0, 0, - "warning: %s is not (any longer) pertinent", - finfo->fullname); - ret = T_REMOVE_ENTRY; - } + ret = T_CONFLICT; + } + else + { + /* they weren't really different */ + if (!really_quiet) + error (0, 0, + "warning: %s is not (any longer) pertinent", + finfo->fullname); + ret = T_REMOVE_ENTRY; } } else if (strcmp (vers->vn_rcs, vers->vn_user) == 0) @@ -321,50 +284,39 @@ conflict: %s created independently by second party", ret = T_UPTODATE; } } - else + else if (No_Difference (finfo, vers)) { /* - * The user file appears to have been modified, but we call - * No_Difference to verify that it really has been modified + * they really are different; modified if we aren't + * changing any sticky -k options, else needs merge */ - if (No_Difference (finfo, vers)) - { - - /* - * they really are different; modified if we aren't - * changing any sticky -k options, else needs merge - */ #ifdef XXX_FIXME_WHEN_RCSMERGE_IS_FIXED - if (strcmp (vers->entdata->options ? - vers->entdata->options : "", vers->options) == 0) - ret = T_MODIFIED; - else - ret = T_NEEDS_MERGE; -#else + if (strcmp (vers->entdata->options ? + vers->entdata->options : "", vers->options) == 0) ret = T_MODIFIED; - sticky_ck (finfo, aflag, vers); -#endif - } else - { - /* file has not changed; check out if -k changed */ - if (strcmp (vers->entdata->options ? - vers->entdata->options : "", vers->options) != 0) - { - ret = T_CHECKOUT; - } - else - { + ret = T_NEEDS_MERGE; +#else + ret = T_MODIFIED; + sticky_ck (finfo, aflag, vers); +#endif + } + else if (strcmp (vers->entdata->options ? + vers->entdata->options : "", vers->options) != 0) + { + /* file has not changed; check out if -k changed */ + ret = T_CHECKOUT; + } + else + { - /* - * else -> note that No_Difference will Register the - * file already for us, using the new tag/date. This - * is the desired behaviour - */ - ret = T_UPTODATE; - } - } + /* + * else -> note that No_Difference will Register the + * file already for us, using the new tag/date. This + * is the desired behaviour + */ + ret = T_UPTODATE; } } else @@ -388,7 +340,6 @@ conflict: %s created independently by second party", /* * The user file is still unmodified, so just get it as well */ -#ifdef SERVER_SUPPORT if (strcmp (vers->entdata->options ? vers->entdata->options : "", vers->options) != 0 || (vers->srcfile != NULL @@ -396,31 +347,19 @@ conflict: %s created independently by second party", ret = T_CHECKOUT; else ret = T_PATCH; -#else - ret = T_CHECKOUT; -#endif } + else if (No_Difference (finfo, vers)) + /* really modified, needs to merge */ + ret = T_NEEDS_MERGE; + else if ((strcmp (vers->entdata->options ? + vers->entdata->options : "", vers->options) + != 0) + || (vers->srcfile != NULL + && (vers->srcfile->flags & INATTIC) != 0)) + /* not really modified, check it out */ + ret = T_CHECKOUT; else - { - if (No_Difference (finfo, vers)) - /* really modified, needs to merge */ - ret = T_NEEDS_MERGE; -#ifdef SERVER_SUPPORT - else if ((strcmp (vers->entdata->options ? - vers->entdata->options : "", vers->options) - != 0) - || (vers->srcfile != NULL - && (vers->srcfile->flags & INATTIC) != 0)) - /* not really modified, check it out */ - ret = T_CHECKOUT; - else - ret = T_PATCH; -#else - else - /* not really modified, check it out */ - ret = T_CHECKOUT; -#endif - } + ret = T_PATCH; } } diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c index c451b28..0b57b35 100644 --- a/contrib/cvs/src/client.c +++ b/contrib/cvs/src/client.c @@ -32,6 +32,7 @@ # else /* No winsock.h */ # include # include +# include # include # endif /* No winsock.h */ #endif @@ -77,19 +78,7 @@ static Key_schedule sched; #ifdef HAVE_GSSAPI -#ifdef HAVE_GSSAPI_H -#include -#endif -#ifdef HAVE_GSSAPI_GSSAPI_H -#include -#endif -#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H -#include -#endif - -#ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE -#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name -#endif +# include "xgssapi.h" /* This is needed for GSSAPI encryption. */ static gss_ctx_id_t gcontext; @@ -97,7 +86,7 @@ static gss_ctx_id_t gcontext; static int connect_to_gserver PROTO((int, struct hostent *)); #endif /* HAVE_GSSAPI */ - + static void add_prune_candidate PROTO((char *)); /* All the commands. */ @@ -198,7 +187,7 @@ arg_should_not_be_sent_to_server (arg) 4) the argument lies within one of the paths in dirs_sent_to_server. - 4) */ + */ if (list_isempty (dirs_sent_to_server)) return 0; /* always send it */ @@ -263,8 +252,8 @@ arg_should_not_be_sent_to_server (arg) } /* Now check the value for root. */ - if (this_root && current_root - && (strcmp (this_root, current_root) != 0)) + if (this_root && current_parsed_root + && (strcmp (this_root, current_parsed_root->original) != 0)) { /* Don't send this, since the CVSROOTs don't match. */ free (this_root); @@ -1277,6 +1266,32 @@ warning: server is not creating directories one at a time"); if ( CVS_CHDIR (dir_name) < 0) error (1, errno, "could not chdir to %s", dir_name); } + 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); + } + + Create_Admin (".", ".", repo, (char *)NULL, (char *)NULL, 0, 1, 1); + if (repo != reposdirname) + free (repo); + } if (strcmp (command_name, "export") != 0) { @@ -2282,7 +2297,7 @@ static int is_cvsroot_level (pathname) char *pathname; { - if (strcmp (toplevel_repos, CVSroot_directory) != 0) + if (strcmp (toplevel_repos, current_parsed_root->directory) != 0) return 0; return strchr (pathname, '/') == NULL; @@ -2922,14 +2937,14 @@ send_a_repository (dir, repository, update_dir) from REPOSITORY. If the path elements don't exist in REPOSITORY, or the removal of those path elements mean that we "step above" - CVSroot_directory, set toplevel_repos to - CVSroot_directory. */ + current_parsed_root->directory, set toplevel_repos to + current_parsed_root->directory. */ if ((repository_len > update_dir_len) && (strcmp (repository + repository_len - update_dir_len, update_dir) == 0) - /* TOPLEVEL_REPOS shouldn't be above CVSroot_directory */ + /* TOPLEVEL_REPOS shouldn't be above current_parsed_root->directory */ && ((repository_len - update_dir_len) - > strlen (CVSroot_directory))) + > strlen (current_parsed_root->directory))) { /* The repository name contains UPDATE_DIR. Set toplevel_repos to the repository name without @@ -2943,7 +2958,7 @@ send_a_repository (dir, repository, update_dir) } else { - toplevel_repos = xstrdup (CVSroot_directory); + toplevel_repos = xstrdup (current_parsed_root->directory); } } } @@ -3001,7 +3016,7 @@ client_expand_modules (argc, argv, local) for (i = 0; i < argc; ++i) send_arg (argv[i]); - send_a_repository ("", CVSroot_directory, ""); + send_a_repository ("", current_parsed_root->directory, ""); send_to_server ("expand-modules\012", 0); @@ -3039,13 +3054,13 @@ client_send_expansions (local, where, build_dirs) if (isfile (argv[0])) send_files (1, argv, local, 0, build_dirs ? SEND_BUILD_DIRS : 0); } - send_a_repository ("", CVSroot_directory, ""); + send_a_repository ("", current_parsed_root->directory, ""); } void client_nonexpanded_setup () { - send_a_repository ("", CVSroot_directory, ""); + send_a_repository ("", current_parsed_root->directory, ""); } /* Receive a cvswrappers line from the server; it must be a line @@ -3560,7 +3575,8 @@ get_responses_and_close () { if (shutdown (server_fd, 1) < 0) error (1, 0, "shutting down connection to %s: %s", - CVSroot_hostname, SOCK_STRERROR (SOCK_ERRNO)); + current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO)); + server_fd = -1; /* * This test will always be true because we dup the descriptor */ @@ -3569,7 +3585,7 @@ get_responses_and_close () if (fclose (to_server_fp) != 0) error (1, errno, "closing down connection to %s", - CVSroot_hostname); + current_parsed_root->hostname); } } else @@ -3587,15 +3603,15 @@ get_responses_and_close () #endif /* START_RSH_WITH_POPEN_RW */ { error (1, errno, "closing connection to %s", - CVSroot_hostname); + current_parsed_root->hostname); } } if (! buf_empty_p (from_server) || getc (from_server_fp) != EOF) - error (0, 0, "dying gasps from %s unexpected", CVSroot_hostname); + error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname); else if (ferror (from_server_fp)) - error (0, errno, "reading from %s", CVSroot_hostname); + error (0, errno, "reading from %s", current_parsed_root->hostname); fclose (from_server_fp); #endif /* SHUTDOWN_SERVER */ @@ -3612,8 +3628,7 @@ get_responses_and_close () /* see if we need to sleep before returning to avoid time-stamp races */ if (last_register_time) { - while (time ((time_t *) NULL) == last_register_time) - sleep (1); + sleep_past (last_register_time); } return errs; @@ -3637,7 +3652,8 @@ supported_request (name) return 0; } - + + #if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) static struct hostent *init_sockaddr PROTO ((struct sockaddr_in *, char *, unsigned int)); @@ -3666,22 +3682,86 @@ init_sockaddr (name, hostname, port) #endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) */ -#ifdef AUTH_CLIENT_SUPPORT -static int auth_server_port_number PROTO ((void)); +#ifdef AUTH_CLIENT_SUPPORT + +/* Generic function to do port number lookup tasks. + * + * In order of precedence, will return: + * getenv (envname), if defined + * getservbyname (portname), if defined + * defaultport + */ static int -auth_server_port_number () +get_port_number (envname, portname, defaultport) + const char *envname; + const char *portname; + int defaultport; { - struct servent *s = getservbyname ("cvspserver", "tcp"); + struct servent *s; + char *port_s; - if (s) + if (envname && (port_s = getenv (envname))) + { + int port = atoi (port_s); + if (port <= 0) + { + error (0, 0, "%s must be a positive integer! If you", envname); + error (0, 0, "are trying to force a connection via rsh, please"); + error (0, 0, "put \":server:\" at the beginning of your CVSROOT"); + error (1, 0, "variable."); + } + return port; + } + else if (portname && (s = getservbyname (portname, "tcp"))) return ntohs (s->s_port); else - return CVS_AUTH_PORT; + return defaultport; +} + + + +/* get the port number for a client to connect to based on the port + * and method of a cvsroot_t. + * + * we do this here instead of in parse_cvsroot so that we can keep network + * code confined to a localized area and also to delay the lookup until the + * last possible moment so it remains possible to run cvs client commands that + * skip opening connections to the server (i.e. skip network operations entirely) + * + * and yes, I know none of the the commands do that now, but here's to planning + * for the future, eh? cheers. + * + * FIXME - We could cache the port lookup safely right now as we never change + * it for a single root on the fly, but we'd have to un'const some other + * functions + */ +int +get_cvs_port_number (root) + const cvsroot_t *root; +{ + + if (root->port) return root->port; + + switch (root->method) + { + case gserver_method: + case pserver_method: + return get_port_number ("CVS_CLIENT_PORT", "cvspserver", CVS_AUTH_PORT); +#ifdef HAVE_KERBEROS + case kserver_method: + return get_port_number ("CVS_CLIENT_PORT", "cvs", CVS_PORT); +#endif + default: + error(1, EINVAL, "internal error: get_cvs_port_number called for invalid connection method (%s)", + method_names[root->method]); + break; + } } + /* Read a line from socket SOCK. Result does not include the terminating linefeed. This is only used by the authentication protocol, which we call before we set up all the buffering stuff. @@ -3709,7 +3789,7 @@ recv_line (sock, resultp) int n; n = recv (sock, &ch, 1, 0); if (n <= 0) - error (1, 0, "recv() from server %s: %s", CVSroot_hostname, + error (1, 0, "recv() from server %s: %s", current_parsed_root->hostname, n == 0 ? "EOF" : SOCK_STRERROR (SOCK_ERRNO)); if (ch == '\012') @@ -3747,11 +3827,15 @@ connect_to_forked_server (tofdp, fromfdp) command[0] = getenv ("CVS_SERVER"); if (! command[0]) - command[0] = "cvs"; + command[0] = program_path; command[1] = "server"; command[2] = NULL; + if (trace) + { + fprintf (stderr, " -> Forking server: %s %s\n", command[0], command[1]); + } if (! piped_child (command, tofdp, fromfdp)) error (1, 0, "could not fork server process"); } @@ -3779,20 +3863,29 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi) int tofd, fromfd; #endif int port_number; + char *username; /* the username we use to connect */ struct sockaddr_in client_sai; struct hostent *hostinfo; - char no_passwd = 0; /* gets set if no password found */ + char no_passwd = 0; /* gets set if no password found */ sock = socket (AF_INET, SOCK_STREAM, 0); if (sock == -1) { error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); } - port_number = auth_server_port_number (); - hostinfo = init_sockaddr (&client_sai, CVSroot_hostname, port_number); + port_number = get_cvs_port_number (current_parsed_root); + hostinfo = init_sockaddr (&client_sai, current_parsed_root->hostname, port_number); + if (trace) + { + fprintf (stderr, " -> Connecting to %s(%s):%d\n", + current_parsed_root->hostname, + inet_ntoa (client_sai.sin_addr), port_number); + } if (connect (sock, (struct sockaddr *) &client_sai, sizeof (client_sai)) < 0) - error (1, 0, "connect to %s:%d failed: %s", CVSroot_hostname, + error (1, 0, "connect to %s(%s):%d failed: %s", + current_parsed_root->hostname, + inet_ntoa (client_sai.sin_addr), port_number, SOCK_STRERROR (SOCK_ERRNO)); /* Run the authorization mini-protocol before anything else. */ @@ -3800,7 +3893,12 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi) { #ifdef HAVE_GSSAPI if (! connect_to_gserver (sock, hostinfo)) + { + error (0, 0, + "authorization failed: server %s rejected access to %s", + current_parsed_root->hostname, current_parsed_root->directory); goto rejected; + } #else error (1, 0, "This client does not support GSSAPI authentication"); #endif @@ -3808,11 +3906,9 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi) else { char *begin = NULL; - char *repository = CVSroot_directory; - char *username = CVSroot_username; char *password = NULL; char *end = NULL; - + if (verify_only) { begin = "BEGIN VERIFICATION REQUEST\012"; @@ -3826,7 +3922,8 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi) /* Get the password, probably from ~/.cvspass. */ password = get_cvs_password (); - + username = current_parsed_root->username ? current_parsed_root->username : getcaller(); + /* Send the empty string by default. This is so anonymous CVS access doesn't require client to have done "cvs login". */ if (password == NULL) @@ -3840,7 +3937,7 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi) error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); /* Send the data the server needs. */ - if (send (sock, repository, strlen (repository), 0) < 0) + if (send (sock, current_parsed_root->directory, strlen (current_parsed_root->directory), 0) < 0) error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); if (send (sock, "\012", 1, 0) < 0) error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); @@ -3871,7 +3968,29 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi) if (strcmp (read_buf, "I HATE YOU") == 0) { - /* Authorization not granted. */ + /* Authorization not granted. + * + * This is a little confusing since we can reach this while loop in GSSAPI + * mode, but if GSSAPI authentication failed, we already jumped to the + * rejected label (there is no case where the connect_to_gserver function + * can return 1 and we will not receive "I LOVE YOU" from the server, barring + * broken connections and garbled messages, of course). + * + * i.e. This is a pserver specific error message and shoiuld be since + * GSSAPI doesn't use username. + */ + error (0, 0, + "authorization failed: server %s rejected access to %s for user %s", + current_parsed_root->hostname, current_parsed_root->directory, username); + + /* Output a special error message if authentication was attempted + with no password -- the user should be made aware that they may + have missed a step. */ + if (no_passwd) + { + error (0, 0, + "used empty password; try \"cvs login\" with a real password"); + } goto rejected; } else if (strncmp (read_buf, "E ", 2) == 0) @@ -3909,15 +4028,15 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi) { error (0, 0, "unrecognized auth response from %s: %s", - CVSroot_hostname, read_buf); + current_parsed_root->hostname, read_buf); error (1, 0, "shutdown() failed, server %s: %s", - CVSroot_hostname, + current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO)); } error (1, 0, "unrecognized auth response from %s: %s", - CVSroot_hostname, read_buf); + current_parsed_root->hostname, read_buf); } free (read_buf); } @@ -3926,7 +4045,7 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi) if (verify_only) { if (shutdown (sock, 2) < 0) - error (0, 0, "shutdown() failed, server %s: %s", CVSroot_hostname, + error (0, 0, "shutdown() failed, server %s: %s", current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO)); return; } @@ -3951,24 +4070,11 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi) return; rejected: - error (0, 0, - "authorization failed: server %s rejected access to %s for user %s", - CVSroot_hostname, CVSroot_directory, CVSroot_username); - - /* Output a special error message if authentication was attempted - with no password -- the user should be made aware that they may - have missed a step. */ - if (no_passwd) - { - error (0, 0, - "used empty password; try \"cvs login\" with a real password"); - } - if (shutdown (sock, 2) < 0) { error (0, 0, "shutdown() failed (server %s): %s", - CVSroot_hostname, + current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO)); } @@ -3976,8 +4082,9 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi) } #endif /* AUTH_CLIENT_SUPPORT */ - -#if HAVE_KERBEROS + + +#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 @@ -3999,42 +4106,26 @@ start_tcp_server (tofdp, fromfdp) if (s < 0) error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); - /* Get CVS_CLIENT_PORT or look up cvs/tcp with CVS_PORT as default */ - portenv = getenv ("CVS_CLIENT_PORT"); - if (portenv != NULL) - { - port = atoi (portenv); - if (port <= 0) - { - error (0, 0, "CVS_CLIENT_PORT must be a positive number! If you"); - error (0, 0, "are trying to force a connection via rsh, please"); - error (0, 0, "put \":server:\" at the beginning of your CVSROOT"); - error (1, 0, "variable."); - } - if (trace) - fprintf(stderr, "Using TCP port %d to contact server.\n", port); - } - else - { - struct servent *sp; - - sp = getservbyname ("cvs", "tcp"); - if (sp == NULL) - port = CVS_PORT; - else - port = ntohs (sp->s_port); - } + port = get_cvs_port_number (current_parsed_root); - hp = init_sockaddr (&sin, CVSroot_hostname, port); + hp = init_sockaddr (&sin, current_parsed_root->hostname, port); hname = xmalloc (strlen (hp->h_name) + 1); strcpy (hname, hp->h_name); + if (trace) + { + fprintf (stderr, " -> Connecting to %s(%s):%d\n", + current_parsed_root->hostname, + inet_ntoa (client_sai.sin_addr), port); + } + if (connect (s, (struct sockaddr *) &sin, sizeof sin) < 0) - error (1, 0, "connect to %s:%d failed: %s", CVSroot_hostname, + error (1, 0, "connect to %s(%s):%d failed: %s", + current_parsed_root->hostname, + inet_ntoa (client_sai.sin_addr), port, SOCK_STRERROR (SOCK_ERRNO)); -#ifdef HAVE_KERBEROS { const char *realm; struct sockaddr_in laddr; @@ -4059,7 +4150,6 @@ start_tcp_server (tofdp, fromfdp) krb_get_err_text (status)); memcpy (kblock, cred.session, sizeof (C_Block)); } -#endif /* HAVE_KERBEROS */ server_fd = s; close_on_exec (server_fd); @@ -4088,9 +4178,10 @@ recv_bytes (sock, buf, need) int got; got = recv (sock, buf, need, 0); - if (got < 0) - error (1, 0, "recv() from server %s: %s", CVSroot_hostname, - SOCK_STRERROR (SOCK_ERRNO)); + if (got <= 0) + error (1, 0, "recv() from server %s: %s", current_parsed_root->hostname, + got == 0 ? "EOF" : SOCK_STRERROR (SOCK_ERRNO)); + buf += got; need -= got; } @@ -4183,11 +4274,11 @@ connect_to_gserver (sock, hostinfo) got = recv (sock, buf + 2, sizeof buf - 2, 0); if (got < 0) error (1, 0, "recv() from server %s: %s", - CVSroot_hostname, SOCK_STRERROR (SOCK_ERRNO)); + current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO)); buf[got + 2] = '\0'; if (buf[got + 1] == '\n') buf[got + 1] = '\0'; - error (1, 0, "error from server %s: %s", CVSroot_hostname, + error (1, 0, "error from server %s: %s", current_parsed_root->hostname, buf); } @@ -4239,7 +4330,7 @@ start_server () (*really* slow on a 14.4kbps link); the clean way to have a CVS which supports several ways of connecting is with access methods. */ - switch (CVSroot_method) + switch (current_parsed_root->method) { #ifdef AUTH_CLIENT_SUPPORT @@ -4256,7 +4347,7 @@ start_server () break; #endif -#if HAVE_GSSAPI +#ifdef HAVE_GSSAPI case gserver_method: /* GSSAPI authentication is handled by the pserver. */ connect_to_pserver (&tofd, &fromfd, 0, 1); @@ -4275,8 +4366,8 @@ start_server () case server_method: #if defined(START_SERVER) START_SERVER (&tofd, &fromfd, getcaller (), - CVSroot_username, CVSroot_hostname, - CVSroot_directory); + current_parsed_root->username, current_parsed_root->hostname, + current_parsed_root->directory); # if defined (START_SERVER_RETURNS_SOCKET) && defined (NO_SOCKET_TO_FD) /* This is a system on which we can only write to a socket using send/recv. Therefore its START_SERVER needs to @@ -4407,7 +4498,7 @@ the :server: access method is not supported by this port of CVS"); if (!rootless) { send_to_server ("Root ", 0); - send_to_server (CVSroot_directory, 0); + send_to_server (current_parsed_root->directory, 0); send_to_server ("\012", 1); } @@ -4537,7 +4628,7 @@ the :server: access method is not supported by this port of CVS"); on encryption, bomb out; don't let the user think the data is being encrypted when it is not. */ #ifdef HAVE_KERBEROS - if (CVSroot_method == kserver_method) + if (current_parsed_root->method == kserver_method) { if (! supported_request ("Kerberos-encrypt")) error (1, 0, "This server does not support encryption"); @@ -4552,7 +4643,7 @@ the :server: access method is not supported by this port of CVS"); else #endif /* HAVE_KERBEROS */ #ifdef HAVE_GSSAPI - if (CVSroot_method == gserver_method) + if (current_parsed_root->method == gserver_method) { if (! supported_request ("Gssapi-encrypt")) error (1, 0, "This server does not support encryption"); @@ -4625,7 +4716,7 @@ the :server: access method is not supported by this port of CVS"); ability to decrypt the data stream is itself a form of authentication. */ #ifdef HAVE_GSSAPI - if (CVSroot_method == gserver_method) + if (current_parsed_root->method == gserver_method) { if (! supported_request ("Gssapi-authenticate")) error (1, 0, @@ -4729,13 +4820,13 @@ start_rsh_server (tofdp, fromfdp) #endif /* RSH_NEEDS_BINARY_FLAG */ /* Then we strcat more things on the end one by one. */ - if (CVSroot_username != NULL) + if (current_parsed_root->username != NULL) { rsh_argv[i++] = "-l"; - rsh_argv[i++] = CVSroot_username; + rsh_argv[i++] = current_parsed_root->username; } - rsh_argv[i++] = CVSroot_hostname; + rsh_argv[i++] = current_parsed_root->hostname; rsh_argv[i++] = cvs_server; rsh_argv[i++] = "server"; @@ -4745,6 +4836,8 @@ start_rsh_server (tofdp, fromfdp) if (trace) { fprintf (stderr, " -> Starting server: "); + for (i = 0; rsh_argv[i]; i++) + fprintf (stderr, "%s ", rsh_argv[i]); putc ('\n', stderr); } @@ -4782,7 +4875,7 @@ start_rsh_server (tofdp, fromfdp) versions of rsh that grab switches out of the middle of the command (they're calling the GNU getopt routines incorrectly). */ command = xmalloc (strlen (cvs_server) - + strlen (CVSroot_directory) + + strlen (current_parsed_root->directory) + 50); /* If you are running a very old (Nov 3, 1994, before 1.5) @@ -4796,15 +4889,15 @@ start_rsh_server (tofdp, fromfdp) char **p = argv; *p++ = cvs_rsh; - *p++ = CVSroot_hostname; + *p++ = current_parsed_root->hostname; /* If the login names differ between client and server * pass it on to rsh. */ - if (CVSroot_username != NULL) + if (current_parsed_root->username != NULL) { *p++ = "-l"; - *p++ = CVSroot_username; + *p++ = current_parsed_root->username; } *p++ = command; @@ -5531,7 +5624,7 @@ send_files (argc, argv, local, aflag, flags) * latter case; I don't think toplevel_repos matters for the * former. */ - toplevel_repos = xstrdup (CVSroot_directory); + toplevel_repos = xstrdup (current_parsed_root->directory); send_repository ("", toplevel_repos, "."); } @@ -5650,7 +5743,7 @@ client_import_done () */ /* FIXME: "can't happen" now that we call client_import_setup at the beginning. */ - toplevel_repos = xstrdup (CVSroot_directory); + toplevel_repos = xstrdup (current_parsed_root->directory); send_repository ("", toplevel_repos, "."); } @@ -5830,9 +5923,9 @@ client_senddate (date) void send_init_command () { - /* This is here because we need the CVSroot_directory variable. */ + /* This is here because we need the current_parsed_root->directory variable. */ send_to_server ("init ", 0); - send_to_server (CVSroot_directory, 0); + send_to_server (current_parsed_root->directory, 0); send_to_server ("\012", 0); } diff --git a/contrib/cvs/src/commit.c b/contrib/cvs/src/commit.c index 1c1f71c..149da7c 100644 --- a/contrib/cvs/src/commit.c +++ b/contrib/cvs/src/commit.c @@ -85,13 +85,13 @@ static time_t last_register_time; static const char *const commit_usage[] = { "Usage: %s %s [-nRlf] [-m msg | -F logfile] [-r rev] files...\n", - "\t-n\tDo not run the module program (if any).\n", - "\t-R\tProcess directories recursively.\n", - "\t-l\tLocal directory only (not recursive).\n", - "\t-f\tForce the file to be committed; disables recursion.\n", - "\t-F file\tRead the log message from file.\n", - "\t-m msg\tLog message.\n", - "\t-r rev\tCommit to this branch or trunk revision.\n", + " -n Do not run the module program (if any).\n", + " -R Process directories recursively.\n", + " -l Local directory only (not recursive).\n", + " -f Force the file to be committed; disables recursion.\n", + " -F logfile Read the log message from file.\n", + " -m msg Log message.\n", + " -r rev Commit to this branch or trunk revision.\n", "(Specify the --help global option for a list of other help options)\n", NULL }; @@ -344,7 +344,7 @@ commit (argc, argv) if (geteuid () == (uid_t) 0 # ifdef CLIENT_SUPPORT /* Who we are on the client side doesn't affect logging. */ - && !client_active + && !current_parsed_root->isremote # endif ) { @@ -432,7 +432,7 @@ commit (argc, argv) } #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { struct find_data find_args; @@ -591,8 +591,7 @@ commit (argc, argv) char *fname; FILE *fp; - fname = cvs_temp_name (); - fp = CVS_FOPEN (fname, "w+"); + fp = cvs_temp_file (&fname); if (fp == NULL) error (1, 0, "cannot create temporary file %s", fname); if (fwrite (saved_message, 1, strlen (saved_message), fp) @@ -601,6 +600,7 @@ commit (argc, argv) if (fclose (fp) < 0) error (0, errno, "cannot close temporary file %s", fname); error (0, 0, "saving log message in %s", fname); + free (fname); } return err; } @@ -615,7 +615,7 @@ commit (argc, argv) wrap_setup (); - lock_tree_for_write (argc, argv, local, aflag); + lock_tree_for_write (argc, argv, local, W_LOCAL, aflag); /* * Set up the master update list and hard link list @@ -663,11 +663,15 @@ commit (argc, argv) Lock_Cleanup (); dellist (&mulist); +#ifdef SERVER_SUPPORT + if (server_active) + return err; +#endif + /* see if we need to sleep before returning to avoid time-stamp races */ if (last_register_time) { - while (time ((time_t *) NULL) == last_register_time) - sleep (1); + sleep_past (last_register_time); } return (err); @@ -778,7 +782,7 @@ check_fileproc (callerdat, finfo) struct commit_info *ci; struct logfile_info *li; - size_t cvsroot_len = strlen (CVSroot_directory); + size_t cvsroot_len = strlen (current_parsed_root->directory); if (!finfo->repository) { @@ -786,7 +790,7 @@ check_fileproc (callerdat, finfo) return (1); } - if (strncmp (finfo->repository, CVSroot_directory, cvsroot_len) == 0 + if (strncmp (finfo->repository, current_parsed_root->directory, cvsroot_len) == 0 && ISDIRSEP (finfo->repository[cvsroot_len]) && strncmp (finfo->repository + cvsroot_len + 1, CVSROOTADM, @@ -810,9 +814,7 @@ check_fileproc (callerdat, finfo) switch (status) { case T_CHECKOUT: -#ifdef SERVER_SUPPORT case T_PATCH: -#endif case T_NEEDS_MERGE: case T_CONFLICT: case T_REMOVE_ENTRY: @@ -829,7 +831,7 @@ check_fileproc (callerdat, finfo) * Also, * - if status is T_REMOVED, can't have a numeric tag * - if status is T_ADDED, rcs file must not exist unless on - * a branch + * a branch or head is dead * - if status is T_ADDED, can't have a non-trunk numeric rev * - if status is T_MODIFIED and a Conflict marker exists, don't * allow the commit if timestamp is identical or if we find @@ -926,29 +928,17 @@ warning: file `%s' seems to still contain conflict indicators", { if (vers->tag == NULL) { - char *rcs; - - rcs = xmalloc (strlen (finfo->repository) - + strlen (finfo->file) - + sizeof RCSEXT - + 5); - - /* Don't look in the attic; if it exists there we - will move it back out in checkaddfile. */ - sprintf(rcs, "%s/%s%s", finfo->repository, finfo->file, - RCSEXT); - if (isreadable (rcs)) + if (finfo->rcs != NULL && + !RCS_isdead (finfo->rcs, finfo->rcs->head)) { error (0, 0, "cannot add file `%s' when RCS file `%s' already exists", - finfo->fullname, rcs); + finfo->fullname, finfo->rcs->path); freevers_ts (&vers); - free (rcs); return (1); } - free (rcs); } - if (vers->tag && isdigit ((unsigned char) *vers->tag) && + else if (isdigit ((unsigned char) *vers->tag) && numdots (vers->tag) > 1) { error (0, 0, @@ -1311,6 +1301,12 @@ commit_fileproc (callerdat, finfo) /* find the max major rev number in this directory */ maxrev = 0; (void) walklist (finfo->entries, findmaxrev, NULL); + if (finfo->rcs->head) { + /* resurrecting: include dead revision */ + int thisrev = atoi (finfo->rcs->head); + if (thisrev > maxrev) + maxrev = thisrev; + } if (maxrev == 0) maxrev = 1; xrev = xmalloc (20); @@ -1430,12 +1426,12 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries) { char *p; - if (strncmp (CVSroot_directory, repository, - strlen (CVSroot_directory)) != 0) + if (strncmp (current_parsed_root->directory, repository, + strlen (current_parsed_root->directory)) != 0) error (0, 0, "internal error: repository (%s) doesn't begin with root (%s)", - repository, CVSroot_directory); - p = repository + strlen (CVSroot_directory); + repository, current_parsed_root->directory); + p = repository + strlen (current_parsed_root->directory); if (*p == '/') ++p; if (strcmp ("CVSROOT", p) == 0 @@ -1596,19 +1592,13 @@ findmaxrev (p, closure) Node *p; void *closure; { - char *cp; int thisrev; Entnode *entdata; entdata = (Entnode *) p->data; if (entdata->type != ENT_FILE) return (0); - cp = strchr (entdata->version, '.'); - if (cp != NULL) - *cp = '\0'; thisrev = atoi (entdata->version); - if (cp != NULL) - *cp = '.'; if (thisrev > maxrev) maxrev = thisrev; return (0); @@ -1956,10 +1946,8 @@ checkaddfile (file, repository, tag, options, rcsnode) Attic. */ if (!(rcsfile->flags & INATTIC)) { - error (0, 0, "internal error: confused about attic for %s", + error (0, 0, "warning: expected %s to be in Attic", rcsfile->path); - retval = 1; - goto out; } sprintf (rcs, "%s/%s%s", repository, file, RCSEXT); diff --git a/contrib/cvs/src/create_adm.c b/contrib/cvs/src/create_adm.c index 878b058..1ab0f28 100644 --- a/contrib/cvs/src/create_adm.c +++ b/contrib/cvs/src/create_adm.c @@ -84,7 +84,7 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn, /* record the current cvs root for later use */ - Create_Root (dir, CVSroot_original); + Create_Root (dir, current_parsed_root->original); if (dir != NULL) (void) sprintf (tmp, "%s/%s", dir, CVSADM_REP); else @@ -106,7 +106,7 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn, spend the time making sure all of the code can handle it if we don't do it. */ - if (strcmp (reposcopy, CVSroot_directory) == 0) + if (strcmp (reposcopy, current_parsed_root->directory) == 0) { reposcopy = xrealloc (reposcopy, strlen (reposcopy) + 3); strcat (reposcopy, "/."); @@ -119,14 +119,13 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn, * If the Repository file is to hold a relative path, try to strip off * the leading CVSroot argument. */ - if (CVSroot_directory != NULL) { - char *path = xmalloc (strlen (CVSroot_directory) + 10); + char *path = xmalloc (strlen (current_parsed_root->directory) + 2); - (void) sprintf (path, "%s/", CVSroot_directory); - if (strncmp (cp, path, strlen (path)) == 0) - cp += strlen (path); - free (path); + (void) sprintf (path, "%s/", current_parsed_root->directory); + if (strncmp (cp, path, strlen (path)) == 0) + cp += strlen (path); + free (path); } #endif diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h index 0277c86..b4e3fa1 100644 --- a/contrib/cvs/src/cvs.h +++ b/contrib/cvs/src/cvs.h @@ -314,7 +314,7 @@ typedef struct entnode Entnode; /* The type of request that is being done in do_module() */ enum mtype { - CHECKOUT, TAG, PATCH, EXPORT + CHECKOUT, TAG, PATCH, EXPORT, MISC }; /* @@ -366,28 +366,34 @@ extern mode_t cvsumask; /* Access method specified in CVSroot. */ typedef enum { - local_method, server_method, pserver_method, kserver_method, gserver_method, + null_method, local_method, server_method, pserver_method, kserver_method, gserver_method, ext_method, fork_method } CVSmethod; extern char *method_names[]; /* change this in root.c if you change the enum above */ +typedef struct cvsroot_s { + char *original; /* the complete source CVSroot string */ + CVSmethod method; /* one of the enum values above */ + char *username; /* the username or NULL if method == local */ + char *password; /* the username or NULL if method == local */ + char *hostname; /* the hostname or NULL if method == local */ + int port; /* the port or zero if method == local */ + char *directory; /* the directory name */ +#ifdef CLIENT_SUPPORT + unsigned char isremote; /* nonzero if we are doing remote access */ +#endif /* CLIENT_SUPPORT */ +} cvsroot_t; + /* This global variable holds the global -d option. It is NULL if -d was not used, which means that we must get the CVSroot information from the CVSROOT environment variable or from a CVS/Root file. */ extern char *CVSroot_cmdline; -extern char *CVSroot_original; /* the active, complete CVSroot string */ -extern int client_active; /* nonzero if we are doing remote access */ -extern CVSmethod CVSroot_method; /* one of the enum values above */ -extern char *CVSroot_username; /* the username or NULL if method == local */ -extern char *CVSroot_hostname; /* the hostname or NULL if method == local */ -extern char *CVSroot_directory; /* the directory name */ - /* These variables keep track of all of the CVSROOT directories that have been seen by the client and the current one of those selected. */ extern List *root_directories; -extern char *current_root; +extern cvsroot_t *current_parsed_root; extern char *emptydir_name PROTO ((void)); extern int safe_location PROTO ((void)); @@ -422,8 +428,9 @@ extern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile, char *rev1, char *rev2, char *label1, char *label2, char *workfile)); -extern int diff_exec PROTO ((char *file1, char *file2, char *options, - char *out)); +extern int diff_exec PROTO ((char *file1, char *file2, + char *label1, char *label2, + char *options, char *out)); extern int diff_execv PROTO ((char *file1, char *file2, char *label1, char *label2, char *options, char *out)); @@ -443,15 +450,18 @@ void Subdir_Deregister PROTO((List *, const char *, const char *)); char *Make_Date PROTO((char *rawdate)); char *date_from_time_t PROTO ((time_t)); -void date_to_internet PROTO ((char *, char *)); +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)); void Sanitize_Repository_Name PROTO((char *repository)); char *Name_Root PROTO((char *dir, char *update_dir)); -int parse_cvsroot PROTO((char *CVSroot)); -void set_local_cvsroot PROTO((char *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)); void root_allow_add PROTO ((char *)); void root_allow_free PROTO ((void)); @@ -465,6 +475,7 @@ char *time_stamp PROTO((char *file)); void *xmalloc PROTO((size_t bytes)); void *xrealloc PROTO((void *ptr, size_t bytes)); void expand_string PROTO ((char **, size_t *, size_t)); +void allocate_and_strcat PROTO ((char **, size_t *, const char *)); char *xstrdup PROTO((const char *str)); void strip_trailing_newlines PROTO((char *str)); int pathname_levels PROTO ((char *path)); @@ -487,6 +498,7 @@ char *xreadlink PROTO((const char *link)); char *last_component PROTO((char *path)); char *get_homedir PROTO ((void)); char *cvs_temp_name PROTO ((void)); +FILE *cvs_temp_file PROTO ((char **filename)); int numdots PROTO((const char *s)); char *increment_revnum PROTO ((const char *)); @@ -510,7 +522,8 @@ void Lock_Cleanup PROTO((void)); /* Writelock an entire subtree, well the part specified by ARGC, ARGV, LOCAL, and AFLAG, anyway. */ -void lock_tree_for_write PROTO ((int argc, char **argv, int local, int aflag)); +void lock_tree_for_write PROTO ((int argc, char **argv, int local, int which, + int aflag)); /* See lock.c for description. */ extern void lock_dir_for_write PROTO ((char *)); @@ -547,7 +560,6 @@ void make_directories PROTO((const char *name)); void make_directory PROTO((const char *name)); extern int mkdir_if_needed PROTO ((char *name)); void rename_file PROTO((const char *from, const char *to)); -char *backup_file PROTO((const char *file, const char *suffix)); /* 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 conventions regarding wildcard syntax. It might be desirable to change the @@ -627,7 +639,8 @@ extern int init PROTO ((int argc, char **argv)); 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, char *extra_arg)); + 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)); int start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc, @@ -645,7 +658,10 @@ char *make_message_rcslegal PROTO((char *message)); 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 *)); +extern char *shell_escape PROTO((char *buf, const char *str)); +char *backup_file PROTO((const char *file, const char *suffix)); 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 */ @@ -775,9 +791,7 @@ enum classify_type T_REMOVED, /* R (removed file) list */ T_REMOVE_ENTRY, /* W (removed entry) list */ T_UPTODATE, /* File is up-to-date */ -#ifdef SERVER_SUPPORT T_PATCH, /* P Like C, but can patch */ -#endif T_TITLE /* title for node type */ }; typedef enum classify_type Ctype; @@ -867,6 +881,8 @@ char *descramble PROTO ((char *str)); #ifdef AUTH_CLIENT_SUPPORT char *get_cvs_password PROTO((void)); +int get_cvs_port_number PROTO((const cvsroot_t *root)); +char *normalize_cvsroot PROTO((const cvsroot_t *root)); #endif /* AUTH_CLIENT_SUPPORT */ extern void tag_check_valid PROTO ((char *, int, char **, int, int, char *)); diff --git a/contrib/cvs/src/cvsbug.in b/contrib/cvs/src/cvsbug.in new file mode 100755 index 0000000..8a8dc0d --- /dev/null +++ b/contrib/cvs/src/cvsbug.in @@ -0,0 +1,526 @@ +#! /bin/sh +# Submit a problem report to a GNATS site. +# Copyright (C) 1993 Free Software Foundation, Inc. +# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a +# version written by Heinz G. Seidl (hgs@ide.com). +# +# This file is part of GNU GNATS. +# Modified by Berliner for CVS. +# +# GNU GNATS is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU GNATS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# The version of this send-pr. +VERSION=3.2 + +# The submitter-id for your site. +SUBMITTER=net + +## # Where the GNATS directory lives, if at all. +## [ -z "$GNATS_ROOT" ] && +## GNATS_ROOT=/usr/local/lib/gnats/gnats-db + +# The default mail address for PR submissions. +GNATS_ADDR=bug-cvs@gnu.org + +## # Where the gnats category tree lives. +## DATADIR=/usr/local/lib + +## # If we've been moved around, try using GCC_EXEC_PREFIX. +## [ ! -d $DATADIR/gnats -a -d "$GCC_EXEC_PREFIX" ] && DATADIR=${GCC_EXEC_PREFIX}.. + +# The default release for this host. +DEFAULT_RELEASE="@VERSION@" + +# The default organization. +DEFAULT_ORGANIZATION="net" + +## # The default site to look for. +## GNATS_SITE=unknown + +## # Newer config information? +## [ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config + +# 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 +MAILER=`echo $MAIL_AGENT | sed -e 's, .*,,'` +if [ ! -f "$MAILER" ] ; then + echo "$COMMAND: Cannot file mail program \"$MAILER\"." + echo "$COMMAND: Please fix the MAIL_AGENT entry in the $COMMAND file." + exit 1 +fi + +if test "`echo -n foo`" = foo ; then + ECHON=bsd +elif test "`echo 'foo\c'`" = foo ; then + ECHON=sysv +else + ECHON=none +fi + +if [ $ECHON = bsd ] ; then + ECHON1="echo -n" + ECHON2= +elif [ $ECHON = sysv ] ; then + ECHON1=echo + ECHON2='\c' +else + ECHON1=echo + ECHON2= +fi + +# + +[ -z "$TMPDIR" ] && TMPDIR=/tmp + +TEMP=$TMPDIR/p$$ +BAD=$TMPDIR/pbad$$ +REF=$TMPDIR/pf$$ + +if [ -z "$LOGNAME" -a -n "$USER" ]; then + LOGNAME=$USER +fi + +FROM="$LOGNAME" +REPLY_TO="$LOGNAME" + +# Find out the name of the originator of this PR. +if [ -n "$NAME" ]; then + ORIGINATOR="$NAME" +elif [ -f $HOME/.fullname ]; then + ORIGINATOR="`sed -e '1q' $HOME/.fullname`" +elif [ -f /bin/domainname ]; then + if [ "`/bin/domainname`" != "" -a -f /usr/bin/ypcat ]; then + # Must use temp file due to incompatibilities in quoting behavior + # and to protect shell metacharacters in the expansion of $LOGNAME + /usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" | + cut -f5 -d':' | sed -e 's/,.*//' > $TEMP + ORIGINATOR="`cat $TEMP`" + rm -f $TEMP + fi +fi + +if [ "$ORIGINATOR" = "" ]; then + grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP + ORIGINATOR="`cat $TEMP`" + rm -f $TEMP +fi + +if [ -n "$ORGANIZATION" ]; then + if [ -f "$ORGANIZATION" ]; then + ORGANIZATION="`cat $ORGANIZATION`" + fi +else + if [ -n "$DEFAULT_ORGANIZATION" ]; then + ORGANIZATION="$DEFAULT_ORGANIZATION" + elif [ -f $HOME/.organization ]; then + ORGANIZATION="`cat $HOME/.organization`" + elif [ -f $HOME/.signature ]; then + ORGANIZATION="`cat $HOME/.signature`" + fi +fi + +# If they don't have a preferred editor set, then use +if [ -z "$VISUAL" ]; then + if [ -z "$EDITOR" ]; then + EDIT=vi + else + EDIT="$EDITOR" + fi +else + EDIT="$VISUAL" +fi + +# Find out some information. +SYSTEM=`( [ -f /bin/uname ] && /bin/uname -a ) || \ + ( [ -f /usr/bin/uname ] && /usr/bin/uname -a ) || echo ""` +ARCH=`[ -f /bin/arch ] && /bin/arch` +MACHINE=`[ -f /bin/machine ] && /bin/machine` + +COMMAND=`echo $0 | sed -e 's,.*/,,'` +## USAGE="Usage: $COMMAND [-PVL] [-t address] [-f filename] [--request-id] +USAGE="Usage: $COMMAND [-PVL] +[--version]" +REMOVE= +BATCH= + +while [ $# -gt 0 ]; do + case "$1" in + -r) ;; # Ignore for backward compat. +## -t | --to) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi +## shift ; GNATS_ADDR="$1" +## EXPLICIT_GNATS_ADDR=true +## ;; +## -f | --file) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi +## shift ; IN_FILE="$1" +## if [ "$IN_FILE" != "-" -a ! -r "$IN_FILE" ]; then +## echo "$COMMAND: cannot read $IN_FILE" +## exit 1 +## fi +## ;; + -b | --batch) BATCH=true ;; + -p | -P | --print) PRINT=true ;; + -L | --list) FORMAT=norm ;; + -l | -CL | --lisp) FORMAT=lisp ;; +## --request-id) REQUEST_ID=true ;; + -h | --help) echo "$USAGE"; exit 0 ;; + -V | --version) echo "$VERSION"; exit 0 ;; + -*) echo "$USAGE" ; exit 1 ;; + *) echo "$USAGE" ; exit 1 +## if [ -z "$USER_GNATS_SITE" ]; then +## if [ ! -r "$DATADIR/gnats/$1" ]; then +## echo "$COMMAND: the GNATS site $1 does not have a categories list." +## exit 1 +## else +## # The site name is the alias they'll have to have created. +## USER_GNATS_SITE=$1 +## fi +## else +## echo "$USAGE" ; exit 1 +## fi + ;; + esac + shift +done + +if [ -n "$USER_GNATS_SITE" ]; then + GNATS_SITE=$USER_GNATS_SITE + GNATS_ADDR=$USER_GNATS_SITE-gnats +fi + +if [ "$SUBMITTER" = "unknown" -a -z "$REQUEST_ID" -a -z "$IN_FILE" ]; then + cat << '__EOF__' +It seems that send-pr is not installed with your unique submitter-id. +You need to run + + install-sid YOUR-SID + +where YOUR-SID is the identification code you received with `send-pr'. +`send-pr' will automatically insert this value into the template field +`>Submitter-Id'. If you've downloaded `send-pr' from the Net, use `net' +for this value. If you do not know your id, run `send-pr --request-id' to +get one from your support site. +__EOF__ + exit 1 +fi + +## if [ -r "$DATADIR/gnats/$GNATS_SITE" ]; then +## CATEGORIES=`grep -v '^#' $DATADIR/gnats/$GNATS_SITE | sort` +## else +## echo "$COMMAND: could not read $DATADIR/gnats/$GNATS_SITE for categories list." +## exit 1 +## fi +CATEGORIES="contrib cvs doc pcl-cvs portability" + +if [ -z "$CATEGORIES" ]; then + echo "$COMMAND: the categories list for $GNATS_SITE was empty!" + exit 1 +fi + +case "$FORMAT" in + lisp) echo "$CATEGORIES" | \ + awk 'BEGIN {printf "( "} + {printf "(\"%s\") ",$0} + END {printf ")\n"}' + exit 0 + ;; + norm) l=`echo "$CATEGORIES" | \ + awk 'BEGIN {max = 0; } + { if (length($0) > max) { max = length($0); } } + END {print max + 1;}'` + c=`expr 70 / $l` + if [ $c -eq 0 ]; then c=1; fi + echo "$CATEGORIES" | \ + awk 'BEGIN {print "Known categories:"; i = 0 } + { printf ("%-'$l'.'$l's", $0); if ((++i % '$c') == 0) { print "" } } + END { print ""; }' + exit 0 + ;; +esac + +ORIGINATOR_C='' +ORGANIZATION_C='' +CONFIDENTIAL_C='<[ yes | no ] (one line)>' +SYNOPSIS_C='' +SEVERITY_C='<[ non-critical | serious | critical ] (one line)>' +PRIORITY_C='<[ low | medium | high ] (one line)>' +CATEGORY_C='' +CLASS_C='<[ sw-bug | doc-bug | change-request | support ] (one line)>' +RELEASE_C='' +ENVIRONMENT_C='' +DESCRIPTION_C='' +HOW_TO_REPEAT_C='' +FIX_C='' + +# Catch some signals. ($xs kludge needed by Sun /bin/sh) +xs=0 +trap 'rm -f $REF $TEMP; exit $xs' 0 +trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15 + +# If they told us to use a specific file, then do so. +if [ -n "$IN_FILE" ]; then + if [ "$IN_FILE" = "-" ]; then + # The PR is coming from the standard input. + if [ -n "$EXPLICIT_GNATS_ADDR" ]; then + sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" > $TEMP + else + cat > $TEMP + fi + else + # Use the file they named. + if [ -n "$EXPLICIT_GNATS_ADDR" ]; then + sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" $IN_FILE > $TEMP + else + cat $IN_FILE > $TEMP + fi + fi +else + + if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then + # If their PR_FORM points to a bogus entry, then bail. + if [ ! -f "$PR_FORM" -o ! -r "$PR_FORM" -o ! -s "$PR_FORM" ]; then + echo "$COMMAND: can't seem to read your template file (\`$PR_FORM'), ignoring PR_FORM" + sleep 1 + PRINT_INTERN=bad_prform + fi + fi + + if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then + cp $PR_FORM $TEMP || + ( echo "$COMMAND: could not copy $PR_FORM" ; xs=1; exit ) + else + for file in $TEMP $REF ; do + cat > $file << '__EOF__' +SEND-PR: -*- send-pr -*- +SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as +SEND-PR: will all comments (text enclosed in `<' and `>'). +SEND-PR: +SEND-PR: Choose from the following categories: +SEND-PR: +__EOF__ + + # Format the categories so they fit onto lines. + l=`echo "$CATEGORIES" | \ + awk 'BEGIN {max = 0; } + { if (length($0) > max) { max = length($0); } } + END {print max + 1;}'` + c=`expr 61 / $l` + if [ $c -eq 0 ]; then c=1; fi + echo "$CATEGORIES" | \ + awk 'BEGIN {printf "SEND-PR: "; i = 0 } + { printf ("%-'$l'.'$l's", $0); + if ((++i % '$c') == 0) { printf "\nSEND-PR: " } } + END { printf "\nSEND-PR:\n"; }' >> $file + + cat >> $file << __EOF__ +To: $GNATS_ADDR +Subject: +From: $FROM +Reply-To: $REPLY_TO +X-send-pr-version: $VERSION + + +>Submitter-Id: $SUBMITTER +>Originator: $ORIGINATOR +>Organization: +${ORGANIZATION-$ORGANIZATION_C} +>Confidential: $CONFIDENTIAL_C +>Synopsis: $SYNOPSIS_C +>Severity: $SEVERITY_C +>Priority: $PRIORITY_C +>Category: $CATEGORY_C +>Class: $CLASS_C +>Release: ${DEFAULT_RELEASE-$RELEASE_C} +>Environment: + $ENVIRONMENT_C +`[ -n "$SYSTEM" ] && echo System: $SYSTEM` +`[ -n "$ARCH" ] && echo Architecture: $ARCH` +`[ -n "$MACHINE" ] && echo Machine: $MACHINE` +>Description: + $DESCRIPTION_C +>How-To-Repeat: + $HOW_TO_REPEAT_C +>Fix: + $FIX_C +__EOF__ + done + fi + + if [ "$PRINT" = true -o "$PRINT_INTERN" = true ]; then + cat $TEMP + xs=0; exit + fi + + chmod u+w $TEMP + if [ -z "$REQUEST_ID" ]; then + eval $EDIT $TEMP + else + ed -s $TEMP << '__EOF__' +/^Subject/s/^Subject:.*/Subject: request for a customer id/ +/^>Category/s/^>Category:.*/>Category: send-pr/ +w +q +__EOF__ + fi + + if cmp -s $REF $TEMP ; then + echo "$COMMAND: problem report not filled out, therefore not sent" + xs=1; exit + fi +fi + +# +# Check the enumeration fields + +# This is a "sed-subroutine" with one keyword parameter +# (with workaround for Sun sed bug) +# +SED_CMD=' +/$PATTERN/{ +s||| +s|<.*>|| +s|^[ ]*|| +s|[ ]*$|| +p +q +}' + + +while [ -z "$REQUEST_ID" ]; do + CNT=0 + + # 1) Confidential + # + PATTERN=">Confidential:" + CONFIDENTIAL=`eval sed -n -e "\"$SED_CMD\"" $TEMP` + case "$CONFIDENTIAL" in + ""|yes|no) CNT=`expr $CNT + 1` ;; + *) echo "$COMMAND: \`$CONFIDENTIAL' is not a valid value for \`Confidential'." ;; + esac + # + # 2) Severity + # + PATTERN=">Severity:" + SEVERITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` + case "$SEVERITY" in + ""|non-critical|serious|critical) CNT=`expr $CNT + 1` ;; + *) echo "$COMMAND: \`$SEVERITY' is not a valid value for \`Severity'." + esac + # + # 3) Priority + # + PATTERN=">Priority:" + PRIORITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` + case "$PRIORITY" in + ""|low|medium|high) CNT=`expr $CNT + 1` ;; + *) echo "$COMMAND: \`$PRIORITY' is not a valid value for \`Priority'." + esac + # + # 4) Category + # + PATTERN=">Category:" + CATEGORY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` + FOUND= + for C in $CATEGORIES + do + if [ "$C" = "$CATEGORY" ]; then FOUND=true ; break ; fi + done + if [ -n "$FOUND" ]; then + CNT=`expr $CNT + 1` + else + if [ -z "$CATEGORY" ]; then + echo "$COMMAND: you must include a Category: field in your report." + else + echo "$COMMAND: \`$CATEGORY' is not a known category." + fi + fi + # + # 5) Class + # + PATTERN=">Class:" + CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP` + case "$CLASS" in + ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;; + *) echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'." + esac + + [ $CNT -lt 5 -a -z "$BATCH" ] && + echo "Errors were found with the problem report." + + while true; do + if [ -z "$BATCH" ]; then + $ECHON1 "a)bort, e)dit or s)end? $ECHON2" + read input + else + if [ $CNT -eq 5 ]; then + input=s + else + input=a + fi + fi + case "$input" in + a*) + if [ -z "$BATCH" ]; then + echo "$COMMAND: the problem report remains in $BAD and is not sent." + mv $TEMP $BAD + else + echo "$COMMAND: the problem report is not sent." + fi + xs=1; exit + ;; + e*) + eval $EDIT $TEMP + continue 2 + ;; + s*) + break 2 + ;; + esac + done +done +# +# Remove comments and send the problem report +# (we have to use patterns, where the comment contains regex chars) +# +# /^>Originator:/s;$ORIGINATOR;; +sed -e " +/^SEND-PR:/d +/^>Organization:/,/^>[A-Za-z-]*:/s;$ORGANIZATION_C;; +/^>Confidential:/s;<.*>;; +/^>Synopsis:/s;$SYNOPSIS_C;; +/^>Severity:/s;<.*>;; +/^>Priority:/s;<.*>;; +/^>Category:/s;$CATEGORY_C;; +/^>Class:/s;<.*>;; +/^>Release:/,/^>[A-Za-z-]*:/s;$RELEASE_C;; +/^>Environment:/,/^>[A-Za-z-]*:/s;$ENVIRONMENT_C;; +/^>Description:/,/^>[A-Za-z-]*:/s;$DESCRIPTION_C;; +/^>How-To-Repeat:/,/^>[A-Za-z-]*:/s;$HOW_TO_REPEAT_C;; +/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;; +" $TEMP > $REF + +if $MAIL_AGENT < $REF; then + echo "$COMMAND: problem report sent" + xs=0; exit +else + echo "$COMMAND: mysterious mail failure." + if [ -z "$BATCH" ]; then + echo "$COMMAND: the problem report remains in $BAD and is not sent." + mv $REF $BAD + else + echo "$COMMAND: the problem report is not sent." + fi + xs=1; exit +fi diff --git a/contrib/cvs/src/diff.c b/contrib/cvs/src/diff.c index e98938d..9732f5d 100644 --- a/contrib/cvs/src/diff.c +++ b/contrib/cvs/src/diff.c @@ -117,7 +117,7 @@ static struct option const longopts[] = {"ignore-matching-lines", 1, 0, 'I'}, {"label", 1, 0, 'L'}, {"new-file", 0, 0, 'N'}, - {"initial-tab", 0, 0, 148}, + {"initial-tab", 0, 0, 'T'}, {"width", 1, 0, 'W'}, {"text", 0, 0, 'a'}, {"ignore-space-change", 0, 0, 'b'}, @@ -138,7 +138,7 @@ static struct option const longopts[] = {"report-identical-files", 0, 0, 's'}, {"expand-tabs", 0, 0, 't'}, {"ignore-all-space", 0, 0, 'w'}, - {"side-by-side", 0, 0, 147}, + {"side-by-side", 0, 0, 'y'}, {"unified", 2, 0, 146}, {"left-column", 0, 0, 129}, {"suppress-common-lines", 0, 0, 130}, @@ -186,28 +186,6 @@ static struct option const longopts[] = mostly to ignore -q. Maybe this should be fixed, but I think it's a larger issue than the changes included here. */ -static void strcat_and_allocate PROTO ((char **, size_t *, const char *)); - -/* *STR is a pointer to a malloc'd string. *LENP is its allocated - length. Add SRC to the end of it, reallocating if necessary. */ -static void -strcat_and_allocate (str, lenp, src) - char **str; - size_t *lenp; - const char *src; -{ - size_t new_size; - - new_size = strlen (*str) + strlen (src) + 1; - if (*str == NULL || new_size >= *lenp) - { - while (new_size >= *lenp) - *lenp *= 2; - *str = xrealloc (*str, *lenp); - } - strcat (*str, src); -} - int diff (argc, argv) int argc; @@ -246,18 +224,19 @@ diff (argc, argv) optind = 0; while ((c = getopt_long (argc, argv, - "+abcdefhilnpstuw0123456789BHNRC:D:F:I:L:U:V:W:k:r:", + "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:V:W:k:r:", longopts, &option_index)) != -1) { switch (c) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h': case 'i': case 'n': case 'p': case 's': case 't': - case 'u': case 'w': case '0': case '1': case '2': - case '3': case '4': case '5': case '6': case '7': case '8': - case '9': case 'B': case 'H': + case 'u': case 'w': case 'y': + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case 'B': case 'H': case 'T': (void) sprintf (tmp, " -%c", (char) c); - strcat_and_allocate (&opts, &opts_allocated, tmp); + allocate_and_strcat (&opts, &opts_allocated, tmp); break; case 'L': if (have_rev1_label++) @@ -267,32 +246,31 @@ diff (argc, argv) break; } - strcat_and_allocate (&opts, &opts_allocated, " -L"); - strcat_and_allocate (&opts, &opts_allocated, optarg); + allocate_and_strcat (&opts, &opts_allocated, " -L"); + allocate_and_strcat (&opts, &opts_allocated, optarg); break; case 'C': case 'F': case 'I': case 'U': case 'V': case 'W': (void) sprintf (tmp, " -%c", (char) c); - strcat_and_allocate (&opts, &opts_allocated, tmp); - strcat_and_allocate (&opts, &opts_allocated, optarg); + allocate_and_strcat (&opts, &opts_allocated, tmp); + allocate_and_strcat (&opts, &opts_allocated, optarg); break; case 131: /* --ifdef. */ - strcat_and_allocate (&opts, &opts_allocated, " --ifdef="); - strcat_and_allocate (&opts, &opts_allocated, optarg); + allocate_and_strcat (&opts, &opts_allocated, " --ifdef="); + allocate_and_strcat (&opts, &opts_allocated, optarg); break; case 129: case 130: case 132: case 133: case 134: case 135: case 136: case 137: case 138: case 139: case 140: case 141: case 142: case 143: case 144: case 145: case 146: - case 147: case 148: - strcat_and_allocate (&opts, &opts_allocated, " --"); - strcat_and_allocate (&opts, &opts_allocated, + allocate_and_strcat (&opts, &opts_allocated, " --"); + allocate_and_strcat (&opts, &opts_allocated, longopts[option_index].name); if (longopts[option_index].has_arg == 1 || (longopts[option_index].has_arg == 2 && optarg != NULL)) { - strcat_and_allocate (&opts, &opts_allocated, "="); - strcat_and_allocate (&opts, &opts_allocated, optarg); + allocate_and_strcat (&opts, &opts_allocated, "="); + allocate_and_strcat (&opts, &opts_allocated, optarg); } break; case 'R': @@ -341,7 +319,7 @@ diff (argc, argv) options = xstrdup (""); #ifdef CLIENT_SUPPORT - if (client_active) { + if (current_parsed_root->isremote) { /* We're the client side. Fire up the remote server. */ start_server (); @@ -422,6 +400,8 @@ diff_fileproc (callerdat, finfo) char *tmp; char *tocvsPath; char *fname; + char *label1; + char *label2; /* Initialize these solely to avoid warnings from gcc -Wall about variables that might be used uninitialized. */ @@ -632,24 +612,53 @@ diff_fileproc (callerdat, finfo) copy_file (tocvsPath, finfo->file); } + /* Set up file labels appropriate for compatibility with the Larry Wall + * implementation of patch if the user didn't specify. This is irrelevant + * according to the POSIX.2 specification. + */ + label1 = NULL; + label2 = NULL; + if (!have_rev1_label) + { + if (empty_file == DIFF_ADDED) + label1 = + make_file_label (DEVNULL, NULL, NULL); + else + label1 = + make_file_label (finfo->fullname, use_rev1, vers ? vers->srcfile : NULL); + } + + if (!have_rev2_label) + { + if (empty_file == DIFF_REMOVED) + label2 = + make_file_label (DEVNULL, NULL, NULL); + else + label2 = + make_file_label (finfo->fullname, use_rev2, vers ? vers->srcfile : NULL); + } + if (empty_file == DIFF_ADDED || empty_file == DIFF_REMOVED) { - /* This is file, not fullname, because it is the "Index:" line which - is supposed to contain the directory. */ + /* This is fullname, not file, possibly despite the POSIX.2 + * specification, because that's the way all the Larry Wall + * implementations of patch (are there other implementations?) want + * things and the POSIX.2 spec appears to leave room for this. + */ cvs_output ("\ ===================================================================\n\ RCS file: ", 0); - cvs_output (finfo->file, 0); + cvs_output (finfo->fullname, 0); cvs_output ("\n", 1); cvs_output ("diff -N ", 0); - cvs_output (finfo->file, 0); + cvs_output (finfo->fullname, 0); cvs_output ("\n", 1); if (empty_file == DIFF_ADDED) { if (use_rev2 == NULL) - status = diff_exec (DEVNULL, finfo->file, opts, RUN_TTY); + status = diff_exec (DEVNULL, finfo->file, label1, label2, opts, RUN_TTY); else { int retcode; @@ -668,7 +677,7 @@ RCS file: ", 0); return err; } - status = diff_exec (DEVNULL, tmp, opts, RUN_TTY); + status = diff_exec (DEVNULL, tmp, label1, label2, opts, RUN_TTY); } } else @@ -687,22 +696,11 @@ RCS file: ", 0); return err; } - status = diff_exec (tmp, DEVNULL, opts, RUN_TTY); + status = diff_exec (tmp, DEVNULL, label1, label2, opts, RUN_TTY); } } else { - char *label1 = NULL; - char *label2 = NULL; - - if (!have_rev1_label) - label1 = - make_file_label (finfo->fullname, use_rev1, vers->srcfile); - - if (!have_rev2_label) - label2 = - make_file_label (finfo->fullname, use_rev2, vers->srcfile); - status = RCS_exec_rcsdiff (vers->srcfile, opts, *options ? options : vers->options, use_rev1, use_rev2, diff --git a/contrib/cvs/src/edit.c b/contrib/cvs/src/edit.c index df649b6..b627105 100644 --- a/contrib/cvs/src/edit.c +++ b/contrib/cvs/src/edit.c @@ -81,7 +81,7 @@ watch_onoff (argc, argv) argv += optind; #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { start_server (); @@ -98,7 +98,7 @@ watch_onoff (argc, argv) setting_default = (argc <= 0); - lock_tree_for_write (argc, argv, local, 0); + lock_tree_for_write (argc, argv, local, W_LOCAL, 0); err = start_recursion (onoff_fileproc, onoff_filesdoneproc, (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, @@ -235,7 +235,7 @@ send_notifications (argc, argv, local) /* OK, we've done everything which needs to happen on the client side. Now we can try to contact the server; if we fail, then the notifications stay in CVSADM_NOTIFY to be sent next time. */ - if (client_active) + if (current_parsed_root->isremote) { if (strcmp (command_name, "release") != 0) { @@ -259,7 +259,7 @@ send_notifications (argc, argv, local) { /* Local. */ - lock_tree_for_write (argc, argv, local, 0); + lock_tree_for_write (argc, argv, local, W_LOCAL, 0); err += start_recursion (ncheck_fileproc, (FILESDONEPROC) NULL, (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, argc, argv, local, W_LOCAL, 0, 0, (char *)NULL, @@ -301,6 +301,8 @@ edit_fileproc (callerdat, finfo) (void) time (&now); ascnow = asctime (gmtime (&now)); ascnow[24] = '\0'; + /* Fix non-standard format. */ + if (ascnow[8] == '0') ascnow[8] = ' '; fprintf (fp, "E%s\t%s GMT\t%s\t%s\t", finfo->file, ascnow, hostname, CurDir); if (setting_tedit) @@ -493,6 +495,8 @@ unedit_fileproc (callerdat, finfo) (void) time (&now); ascnow = asctime (gmtime (&now)); ascnow[24] = '\0'; + /* Fix non-standard format. */ + if (ascnow[8] == '0') ascnow[8] = ' '; fprintf (fp, "U%s\t%s GMT\t%s\t%s\t\n", finfo->file, ascnow, hostname, CurDir); @@ -869,11 +873,11 @@ notify_do (type, filename, who, val, watches, repository) size_t line_len = 0; args.notifyee = NULL; - usersname = xmalloc (strlen (CVSroot_directory) + usersname = xmalloc (strlen (current_parsed_root->directory) + sizeof CVSROOTADM + sizeof CVSROOTADM_USERS + 20); - strcpy (usersname, CVSroot_directory); + strcpy (usersname, current_parsed_root->directory); strcat (usersname, "/"); strcat (usersname, CVSROOTADM); strcat (usersname, "/"); @@ -1114,7 +1118,7 @@ editors (argc, argv) argv += optind; #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { start_server (); ign_setup (); diff --git a/contrib/cvs/src/entries.c b/contrib/cvs/src/entries.c index 14163bb..686244d 100644 --- a/contrib/cvs/src/entries.c +++ b/contrib/cvs/src/entries.c @@ -381,7 +381,9 @@ fgetentent(fpin, cmd, sawdir) if (strlen (ts) > 30 && CVS_STAT (user, &sb) == 0) { char *c = ctime (&sb.st_mtime); - + /* Fix non-standard format. */ + if (c[8] == '0') c[8] = ' '; + if (!strncmp (ts + 25, c, 24)) ts = time_stamp (user); else diff --git a/contrib/cvs/src/error.c b/contrib/cvs/src/error.c index fe5877f..9655a97 100644 --- a/contrib/cvs/src/error.c +++ b/contrib/cvs/src/error.c @@ -121,7 +121,9 @@ error (status, errnum, message, va_alist) char *q; char *str; int num; + long lnum; unsigned int unum; + unsigned long ulnum; int ch; char buf[100]; @@ -157,6 +159,21 @@ error (status, errnum, message, va_alist) sprintf (buf, "%d", num); cvs_outerr (buf, strlen (buf)); break; + case 'l': + if (q[2] == 'd') + { + lnum = va_arg (args, long); + sprintf (buf, "%ld", lnum); + } + else if (q[2] == 'u') + { + ulnum = va_arg (args, unsigned long); + sprintf (buf, "%lu", ulnum); + } + else goto bad; + cvs_outerr (buf, strlen (buf)); + q++; + break; case 'x': unum = va_arg (args, unsigned int); sprintf (buf, "%x", unum); @@ -171,6 +188,7 @@ error (status, errnum, message, va_alist) cvs_outerr ("%", 1); break; default: + bad: cvs_outerr (msg, sizeof (msg) - 1); /* Don't just keep going, because q + 1 might point to the terminating '\0'. */ diff --git a/contrib/cvs/src/error.h b/contrib/cvs/src/error.h index e0fde4a..c7268ce 100644 --- a/contrib/cvs/src/error.h +++ b/contrib/cvs/src/error.h @@ -11,8 +11,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -#ifndef _error_h_ -#define _error_h_ +#ifndef ERROR_H +#define ERROR_H /* Add prototype support. Normally this is done in cvs.h, but that doesn't get included from lib/savecwd.c. */ @@ -54,4 +54,4 @@ extern void error_exit PROTO ((void)); process and packages up its stderr in the protocol. */ extern int error_use_protocol; -#endif /* _error_h_ */ +#endif /* ERROR_H */ diff --git a/contrib/cvs/src/expand_path.c b/contrib/cvs/src/expand_path.c index 25e561c..f46b39b 100644 --- a/contrib/cvs/src/expand_path.c +++ b/contrib/cvs/src/expand_path.c @@ -272,7 +272,7 @@ expand_variable (name, file, line) int line; { if (strcmp (name, CVSROOT_ENV) == 0) - return CVSroot_original; + return current_parsed_root->original; else if (strcmp (name, "RCSBIN") == 0) { error (0, 0, "RCSBIN internal variable is no longer supported"); diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c index 3a800a9..28575a3 100644 --- a/contrib/cvs/src/filesubr.c +++ b/contrib/cvs/src/filesubr.c @@ -17,6 +17,7 @@ definitions under operating systems (like, say, Windows NT) with different file system semantics. */ +#include #include "cvs.h" static int deep_remove_dir PROTO((const char *path)); @@ -413,12 +414,12 @@ unlink_file (f) const char *f; { if (trace) - (void) fprintf (stderr, "%s-> unlink(%s)\n", + (void) fprintf (stderr, "%s-> unlink_file(%s)\n", CLIENT_SERVER_STR, f); if (noexec) return (0); - return (unlink (f)); + return (CVS_UNLINK (f)); } /* @@ -464,7 +465,7 @@ unlink_file_dir (f) else if (S_ISDIR (sb.st_mode)) return deep_remove_dir (f); - return unlink (f); + return CVS_UNLINK (f); } /* Remove a directory and everything it contains. Returns 0 for @@ -487,14 +488,14 @@ deep_remove_dir (path) returns 87). */ || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87)) { - if ((dirp = opendir (path)) == NULL) + if ((dirp = CVS_OPENDIR (path)) == NULL) /* If unable to open the directory return * an error */ return -1; errno = 0; - while ((dp = readdir (dirp)) != NULL) + while ((dp = CVS_READDIR (dirp)) != NULL) { char *buf; @@ -512,16 +513,16 @@ deep_remove_dir (path) { if (deep_remove_dir(buf)) { - closedir(dirp); + CVS_CLOSEDIR(dirp); free (buf); return -1; } } else { - if (unlink (buf) != 0) + if (CVS_UNLINK (buf) != 0) { - closedir(dirp); + CVS_CLOSEDIR(dirp); free (buf); return -1; } @@ -533,11 +534,11 @@ deep_remove_dir (path) if (errno != 0) { int save_errno = errno; - closedir (dirp); + CVS_CLOSEDIR (dirp); errno = save_errno; return -1; } - closedir (dirp); + CVS_CLOSEDIR (dirp); return rmdir (path); } else @@ -684,53 +685,167 @@ xcmp (file1, file2) } /* Generate a unique temporary filename. Returns a pointer to a newly - malloc'd string containing the name. Returns successfully or not at - all. */ -/* There are at least three functions for generating temporary - filenames. We use tempnam (SVID 3) if possible, else mktemp (BSD - 4.3), and as last resort tmpnam (POSIX). Reason is that tempnam and - mktemp both allow to specify the directory in which the temporary - file will be created. */ -#ifdef HAVE_TEMPNAM + * malloc'd string containing the name. Returns successfully or not at + * all. + * + * THIS FUNCTION IS DEPRECATED!!! USE cvs_temp_file INSTEAD!!! + * + * and yes, I know about the way the rcs commands use temp files. I think + * they should be converted too but I don't have time to look into it right + * now. + */ char * cvs_temp_name () { - char *retval; + char *fn; + FILE *fp; - retval = tempnam (Tmpdir, "cvs"); - if (retval == NULL) - error (1, errno, "cannot generate temporary filename"); - /* tempnam returns a pointer to a newly malloc'd string, so there's - no need for a xstrdup */ - return retval; + fp = cvs_temp_file (&fn); + if (fp == NULL) + error (1, errno, "Failed to create temporary file"); + if (fclose (fp) == EOF) + error (0, errno, "Failed to close temporary file %s", fn); + return fn; } -#else -char * -cvs_temp_name () + +/* Generate a unique temporary filename and return an open file stream + * to the truncated file by that name + * + * INPUTS + * filename where to place the pointer to the newly allocated file + * name string + * + * OUTPUTS + * filename dereferenced, will point to the newly allocated file + * name string. This value is undefined if the function + * returns an error. + * + * RETURNS + * An open file pointer to a read/write mode empty temporary file with the + * unique file name or NULL on failure. + * + * ERRORS + * on error, errno will be set to some value either by CVS_FOPEN or + * whatever system function is called to generate the temporary file name + */ +/* There are at least four functions for generating temporary + * filenames. We use mkstemp (BSD 4.3) if possible, else tempnam (SVID 3), + * else mktemp (BSD 4.3), and as last resort tmpnam (POSIX). Reason is that + * mkstemp, tempnam, and mktemp both allow to specify the directory in which + * the temporary file will be created. + * + * And the _correct_ way to use the deprecated functions probably involves + * opening file descriptors using O_EXCL & O_CREAT and even doing the annoying + * NFS locking thing, but until I hear of more problems, I'm not going to + * bother. + */ +FILE *cvs_temp_file (filename) + char **filename; { -# ifdef HAVE_MKTEMP - char *value; - char *retval; - - value = xmalloc (strlen (Tmpdir) + 40); - sprintf (value, "%s/%s", Tmpdir, "cvsXXXXXX" ); - retval = mktemp (value); - - if (retval == NULL) - error (1, errno, "cannot generate temporary filename"); - return value; -# else - char value[L_tmpnam + 1]; - char *retval; - - retval = tmpnam (value); - if (retval == NULL) - error (1, errno, "cannot generate temporary filename"); - return xstrdup (value); -# endif -} + char *fn; + FILE *fp; + + /* FIXME - I'd like to be returning NULL here in noexec mode, but I think + * some of the rcs & diff functions which rely on a temp file run in + * noexec mode too. + */ + + assert (filename != NULL); + +#ifdef HAVE_MKSTEMP + + { + int fd; + + fn = xmalloc (strlen (Tmpdir) + 11); + sprintf (fn, "%s/%s", Tmpdir, "cvsXXXXXX" ); + fd = mkstemp (fn); + + /* a NULL return will be interpreted by callers as an error and + * errno should still be set + */ + 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 + */ + int save_errno = errno; + if (close (fd)) + error (0, errno, "Failed to close temporary file %s", fn); + if (CVS_UNLINK (fn)) + error (0, errno, "Failed to unlink temporary file %s", fn); + errno = save_errno; + } + + if (fp == NULL) free (fn); + /* mkstemp is defined to open mode 0600 using glibc 2.0.7+ */ + /* FIXME - configure can probably tell us which version of glibc we are + * linking to and not chmod for 2.0.7+ + */ + else chmod (fn, 0600); + + } + +#elif HAVE_TEMPNAM + + /* tempnam has been deprecated due to under-specification */ + + fn = tempnam (Tmpdir, "cvs"); + if (fn == NULL) fp = NULL; + else if ((fp = CVS_FOPEN (fn, "w+")) == NULL) free (fn); + else chmod (fn, 0600); + + /* tempnam returns a pointer to a newly malloc'd string, so there's + * no need for a xstrdup + */ + +#elif HAVE_MKTEMP + + /* mktemp has been deprecated due to the BSD 4.3 specification specifying + * that XXXXXX will be replaced by a PID and a letter, creating only 26 + * possibilities, a security risk, and a race condition. + */ + + { + char *ifn; + + ifn = xmalloc (strlen (Tmpdir) + 11); + sprintf (ifn, "%s/%s", Tmpdir, "cvsXXXXXX" ); + fn = mktemp (ifn); + + if (fn == NULL) fp = NULL; + else fp = CVS_FOPEN (fn, "w+"); + + if (fp == NULL) free (ifn); + else chmod (fn, 0600); + + } + +#else /* use tmpnam if all else fails */ + + /* tmpnam is deprecated */ + + { + char ifn[L_tmpnam + 1]; + + fn = tmpnam (ifn); + + if (fn == NULL) fp = NULL; + else if ((fp = CVS_FOPEN (ifn, "w+")) != NULL) + { + fn = xstrdup (ifn); + chmod (fn, 0600); + } + + } + #endif - + + *filename = fn; + return fp; +} + /* Return non-zero iff FILENAME is absolute. Trivial under Unix, but more complicated under other systems. */ int @@ -819,13 +934,17 @@ char * get_homedir () { static char *home = NULL; - char *env = getenv ("HOME"); + char *env; struct passwd *pw; if (home != NULL) return home; - if (env) + if ( +#ifdef SERVER_SUPPORT + !server_active && +#endif + (env = getenv ("HOME")) != NULL) home = env; else if ((pw = (struct passwd *) getpwuid (getuid ())) && pw->pw_dir) @@ -932,7 +1051,7 @@ fopen_case (name, mode, fp, pathp) } } errno = 0; - while ((dp = readdir (dirp)) != NULL) + while ((dp = CVS_READDIR (dirp)) != NULL) { if (cvs_casecmp (dp->d_name, fname) == 0) { @@ -944,7 +1063,7 @@ fopen_case (name, mode, fp, pathp) } if (errno != 0) error (1, errno, "cannot read directory %s", dir); - closedir (dirp); + CVS_CLOSEDIR (dirp); if (found_name == NULL) { diff --git a/contrib/cvs/src/find_names.c b/contrib/cvs/src/find_names.c index 6fb927b..e34232e 100644 --- a/contrib/cvs/src/find_names.c +++ b/contrib/cvs/src/find_names.c @@ -269,7 +269,7 @@ find_rcs (dir, list) /* read the dir, grabbing the ,v files */ errno = 0; - while ((dp = readdir (dirp)) != NULL) + while ((dp = CVS_READDIR (dirp)) != NULL) { if (CVS_FNMATCH (RCSPAT, dp->d_name, 0) == 0) { @@ -288,11 +288,11 @@ find_rcs (dir, list) if (errno != 0) { int save_errno = errno; - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); errno = save_errno; return 1; } - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); return (0); } @@ -321,9 +321,9 @@ find_dirs (dir, list, checkadm, entries) Emptydir. Except in the CVSNULLREPOS case, Emptydir is just a normal directory name. */ if (isabsolute (dir) - && strncmp (dir, CVSroot_directory, strlen (CVSroot_directory)) == 0 - && ISDIRSEP (dir[strlen (CVSroot_directory)]) - && strcmp (dir + strlen (CVSroot_directory) + 1, CVSROOTADM) == 0) + && strncmp (dir, current_parsed_root->directory, strlen (current_parsed_root->directory)) == 0 + && ISDIRSEP (dir[strlen (current_parsed_root->directory)]) + && strcmp (dir + strlen (current_parsed_root->directory) + 1, CVSROOTADM) == 0) skip_emptydir = 1; /* set up to read the dir */ @@ -332,7 +332,7 @@ find_dirs (dir, list, checkadm, entries) /* read the dir, grabbing sub-dirs */ errno = 0; - while ((dp = readdir (dirp)) != NULL) + while ((dp = CVS_READDIR (dirp)) != NULL) { if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0 || @@ -414,11 +414,11 @@ find_dirs (dir, list, checkadm, entries) if (errno != 0) { int save_errno = errno; - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); errno = save_errno; return 1; } - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); if (tmp != NULL) free (tmp); return (0); diff --git a/contrib/cvs/src/history.c b/contrib/cvs/src/history.c index 9f66e86..4979398 100644 --- a/contrib/cvs/src/history.c +++ b/contrib/cvs/src/history.c @@ -131,7 +131,7 @@ * -p repository - Only records in which the "repository" string is a * prefix of the "repos" field are considered. * - * -m modulename - Only records which contain "modulename" in the + * -n modulename - Only records which contain "modulename" in the * "module" field are considered. * * @@ -191,8 +191,9 @@ static struct hrec char *end; /* Ptr into repository to copy at end of workdir */ char *mod; /* The module within which the file is contained */ time_t date; /* Calculated from date stored in record */ - int idx; /* Index of record, for "stable" sort. */ + long idx; /* Index of record, for "stable" sort. */ } *hrec_head; +static long hrec_idx; static void fill_hrec PROTO((char *line, struct hrec * hr)); @@ -439,8 +440,8 @@ history (argc, argv) save_file ("", optarg, (char *) NULL); break; case 'm': /* Full module report */ - report_count++; - module_report++; + if (!module_report++) report_count++; + /* fall through */ case 'n': /* Look for specified module */ save_module (optarg); break; @@ -538,7 +539,7 @@ history (argc, argv) error (1, 0, "Only one report type allowed from: \"-Tcomxe\"."); #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { struct file_list_str *f1; char **mod; @@ -669,9 +670,9 @@ history (argc, argv) fname = xstrdup (histfile); else { - fname = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM) + fname = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) + sizeof (CVSROOTADM_HISTORY) + 10); - (void) sprintf (fname, "%s/%s/%s", CVSroot_directory, + (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, CVSROOTADM_HISTORY); } @@ -715,9 +716,9 @@ history_write (type, update_dir, revs, name, repository) return; if ( strchr(logHistory, type) == NULL ) return; - fname = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM) - + sizeof (CVSROOTADM_HISTORY) + 10); - (void) sprintf (fname, "%s/%s/%s", CVSroot_directory, + fname = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) + + sizeof (CVSROOTADM_HISTORY) + 3); + (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, CVSROOTADM_HISTORY); /* turn off history logging if the history file does not exist */ @@ -984,7 +985,12 @@ expand_modules () * */ -#define NEXT_BAR(here) do { while (isspace(*line)) line++; hr->here = line; while ((c = *line++) && c != '|') ; if (!c) return; *(line - 1) = '\0'; } while (0) +#define NEXT_BAR(here) do { \ + while (isspace(*line)) line++; \ + hr->here = line; \ + while ((c = *line++) && c != '|') ; \ + if (!c) return; line[-1] = '\0'; \ + } while (0) static void fill_hrec (line, hr) @@ -993,37 +999,31 @@ fill_hrec (line, hr) { char *cp; int c; - int off; - static int idx = 0; - unsigned long date; - memset ((char *) hr, 0, sizeof (*hr)); + hr->type = hr->user = hr->dir = hr->repos = hr->rev = hr->file = + hr->end = hr->mod = NULL; + hr->date = -1; + hr->idx = ++hrec_idx; while (isspace ((unsigned char) *line)) line++; hr->type = line++; - (void) sscanf (line, "%lx", &date); - hr->date = date; - while (*line && strchr ("0123456789abcdefABCDEF", *line)) - line++; - if (*line == '\0') + hr->date = strtoul (line, &cp, 16); + if (cp == line || *cp != '|') return; - - line++; + line = cp + 1; NEXT_BAR (user); NEXT_BAR (dir); if ((cp = strrchr (hr->dir, '*')) != NULL) { *cp++ = '\0'; - (void) sscanf (cp, "%x", &off); - hr->end = line + off; + hr->end = line + strtoul (cp, NULL, 16); } else hr->end = line - 1; /* A handy pointer to '\0' */ NEXT_BAR (repos); NEXT_BAR (rev); - hr->idx = idx++; if (strchr ("FOET", *(hr->type))) hr->mod = line; @@ -1055,7 +1055,7 @@ static void read_hrecs (fname) char *fname; { - unsigned char *cpstart, *cp, *nl; + unsigned char *cpstart, *cpend, *cp, *nl; char *hrline; int i; int fd; @@ -1072,21 +1072,22 @@ read_hrecs (fname) cpstart = xmalloc (2 * STAT_BLOCKSIZE(st_buf)); cpstart[0] = '\0'; - cp = cpstart; + cp = cpend = cpstart; hrec_max = HREC_INCREMENT; hrec_head = xmalloc (hrec_max * sizeof (struct hrec)); + hrec_idx = 0; for (;;) { - for (nl = cp; *nl && *nl != '\n'; nl++) + for (nl = cp; nl < cpend && *nl != '\n'; nl++) if (!isprint(*nl)) *nl = ' '; - if (!*nl) + if (nl >= cpend) { if (nl - cp >= STAT_BLOCKSIZE(st_buf)) { - error(1, 0, "history line too long (> %lu)", + error(1, 0, "history line %ld too long (> %lu)", hrec_idx + 1, (unsigned long) STAT_BLOCKSIZE(st_buf)); } if (nl > cp) @@ -1096,13 +1097,14 @@ read_hrecs (fname) i = read (fd, nl, STAT_BLOCKSIZE(st_buf)); if (i > 0) { - nl[i] = '\0'; + cpend = nl + i; + *cpend = '\0'; continue; } if (i < 0) error (1, errno, "error reading history file"); if (nl == cp) break; - nl[1] = '\0'; + error (0, 0, "warning: no newline at end of history file"); } *nl = '\0'; @@ -1192,6 +1194,14 @@ select_hrec (hr) struct file_list_str *fl; int count; + /* basic validity checking */ + if (!hr->type || !hr->user || !hr->dir || !hr->repos || !hr->rev || + !hr->file || !hr->end) + { + error (0, 0, "warning: history line %ld invalid", hr->idx); + return (0); + } + /* "Since" checking: The argument parser guarantees that only one of the * following four choices is set: * diff --git a/contrib/cvs/src/ignore.c b/contrib/cvs/src/ignore.c index 4ea61ad..b52632b 100644 --- a/contrib/cvs/src/ignore.c +++ b/contrib/cvs/src/ignore.c @@ -68,13 +68,13 @@ ign_setup () processing, and only if !ign_inhibit_server), letting the server know about the files and letting it decide whether to ignore them based on CVSROOOTADM_IGNORE. */ - if (!client_active) + if (!current_parsed_root->isremote) #endif { - char *file = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM) + char *file = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) + sizeof (CVSROOTADM_IGNORE) + 10); /* Then add entries found in repository, if it exists */ - (void) sprintf (file, "%s/%s/%s", CVSroot_directory, + (void) sprintf (file, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, CVSROOTADM_IGNORE); ign_add_file (file, 0); free (file); @@ -379,6 +379,8 @@ ignore_files (ilist, entries, update_dir, proc) struct stat sb; char *file; char *xdir; + List *files; + Node *p; /* Set SUBDIRS if we have subdirectory information in ENTRIES. */ if (entries == NULL) @@ -407,14 +409,16 @@ ignore_files (ilist, entries, update_dir, proc) ign_add_file (CVSDOTIGNORE, 1); wrap_add_file (CVSDOTWRAPPER, 1); - errno = 0; - while ((dp = readdir (dirp)) != NULL) + /* Make a list for the files. */ + files = getlist (); + + while (errno = 0, (dp = CVS_READDIR (dirp)) != NULL) { file = dp->d_name; if (strcmp (file, ".") == 0 || strcmp (file, "..") == 0) - goto continue_loop; + continue; if (findnode_fn (ilist, file) != NULL) - goto continue_loop; + continue; if (subdirs) { Node *node; @@ -435,14 +439,14 @@ ignore_files (ilist, entries, update_dir, proc) dir = isdir (p); free (p); if (dir) - goto continue_loop; + continue; } } /* We could be ignoring FIFOs and other files which are neither regular files nor directories here. */ if (ign_name (file)) - goto continue_loop; + continue; if ( #ifdef DT_DIR @@ -469,7 +473,7 @@ ignore_files (ilist, entries, update_dir, proc) if (isdir (temp)) { free (temp); - goto continue_loop; + continue; } free (temp); } @@ -484,16 +488,22 @@ ignore_files (ilist, entries, update_dir, proc) #endif ) { - goto continue_loop; + continue; } #endif - } + } - (*proc) (file, xdir); - continue_loop: - errno = 0; + p = getnode (); + p->type = FILES; + p->key = xstrdup (file); + (void) addnode (files, p); } if (errno != 0) error (0, errno, "error reading current directory"); - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); + + sortlist (files, fsortcmp); + for (p = files->list->next; p != files->list; p = p->next) + (*proc) (p->key, xdir); + dellist (&files); } diff --git a/contrib/cvs/src/import.c b/contrib/cvs/src/import.c index e1fb460..6bd6abd 100644 --- a/contrib/cvs/src/import.c +++ b/contrib/cvs/src/import.c @@ -171,16 +171,17 @@ import (argc, argv) if (! isabsolute (argv[0]) && pathname_levels (argv[0]) == 0) { - if (CVSroot_directory == NULL) + if (current_parsed_root == NULL) { error (0, 0, "missing CVSROOT environment variable\n"); error (1, 0, "Set it or specify the '-d' option to %s.", program_name); } - repository = xmalloc (strlen (CVSroot_directory) + strlen (argv[0]) - + 10); - (void) sprintf (repository, "%s/%s", CVSroot_directory, argv[0]); - repos_len = strlen (CVSroot_directory); + repository = xmalloc (strlen (current_parsed_root->directory) + + strlen (argv[0]) + + 2); + (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]); + repos_len = strlen (current_parsed_root->directory); } else { @@ -207,7 +208,7 @@ import (argc, argv) *cp = '\0'; #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { /* For rationale behind calling start_server before do_editor, see commit.c */ @@ -236,7 +237,7 @@ import (argc, argv) } #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { int err; @@ -290,8 +291,7 @@ import (argc, argv) make_directories (repository); /* Create the logfile that will be logged upon completion */ - tmpfile = cvs_temp_name (); - if ((logfp = CVS_FOPEN (tmpfile, "w+")) == NULL) + if ((logfp = cvs_temp_file (&tmpfile)) == NULL) error (1, errno, "cannot create temporary file `%s'", tmpfile); /* On systems where we can unlink an open file, do so, so it will go away no matter how we exit. FIXME-maybe: Should be checking for @@ -425,7 +425,7 @@ import_descend (message, vtag, targc, targv) else { errno = 0; - while ((dp = readdir (dirp)) != NULL) + while ((dp = CVS_READDIR (dirp)) != NULL) { if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0) goto one_more_time_boys; @@ -476,7 +476,7 @@ import_descend (message, vtag, targc, targv) else { #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) err += client_process_import_file (message, dp->d_name, vtag, targc, targv, repository, @@ -496,7 +496,7 @@ import_descend (message, vtag, targc, targv) error (0, errno, "cannot read directory"); ++err; } - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); } if (dirlist != NULL) @@ -1567,7 +1567,7 @@ import_descend_dir (message, dir, vtag, targc, targv) } #ifdef CLIENT_SUPPORT - if (!quiet && !client_active) + if (!quiet && !current_parsed_root->isremote) #else if (!quiet) #endif @@ -1582,7 +1582,7 @@ import_descend_dir (message, dir, vtag, targc, targv) goto out; } #ifdef CLIENT_SUPPORT - if (!client_active && !isdir (repository)) + if (!current_parsed_root->isremote && !isdir (repository)) #else if (!isdir (repository)) #endif diff --git a/contrib/cvs/src/lock.c b/contrib/cvs/src/lock.c index 1b98180..c05b83e 100644 --- a/contrib/cvs/src/lock.c +++ b/contrib/cvs/src/lock.c @@ -172,12 +172,13 @@ lock_name (repository, name) /* The interesting part of the repository is the part relative to CVSROOT. */ - assert (CVSroot_directory != NULL); - assert (strncmp (repository, CVSroot_directory, - strlen (CVSroot_directory)) == 0); - short_repos = repository + strlen (CVSroot_directory) + 1; + assert (current_parsed_root != NULL); + assert (current_parsed_root->directory != NULL); + assert (strncmp (repository, current_parsed_root->directory, + strlen (current_parsed_root->directory)) == 0); + short_repos = repository + strlen (current_parsed_root->directory) + 1; - if (strcmp (repository, CVSroot_directory) == 0) + if (strcmp (repository, current_parsed_root->directory) == 0) short_repos = "."; else assert (short_repos[-1] == '/'); @@ -633,7 +634,7 @@ again: error (1, 0, "cannot open directory %s", repository); errno = 0; - while ((dp = readdir (dirp)) != NULL) + while ((dp = CVS_READDIR (dirp)) != NULL) { if (CVS_FNMATCH (CVSRFLPAT, dp->d_name, 0) == 0) { @@ -654,7 +655,7 @@ again: */ if (now >= (sb.st_ctime + CVSLCKAGE) && CVS_UNLINK (line) != -1) { - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); free (line); goto again; } @@ -680,7 +681,7 @@ again: if (errno != 0) error (0, errno, "error reading directory %s", repository); - closedir (dirp); + CVS_CLOSEDIR (dirp); return (ret); } @@ -890,10 +891,11 @@ lock_filesdoneproc (callerdat, err, repository, update_dir, entries) } void -lock_tree_for_write (argc, argv, local, aflag) +lock_tree_for_write (argc, argv, local, which, aflag) int argc; char **argv; int local; + int which; int aflag; { int err; @@ -904,7 +906,7 @@ lock_tree_for_write (argc, argv, local, aflag) lock_tree_list = getlist (); err = start_recursion ((FILEPROC) NULL, lock_filesdoneproc, (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, argc, - argv, local, W_LOCAL, aflag, 0, (char *) NULL, 0); + argv, local, which, aflag, 0, (char *) NULL, 0); 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 2e230e3..1930ae5 100644 --- a/contrib/cvs/src/log.c +++ b/contrib/cvs/src/log.c @@ -30,6 +30,8 @@ struct option_revlist /* Nonzero if there was a trailing `.', which means to print only the head revision of a branch. */ int branchhead; + /* Nonzero if first and last are inclusive. */ + int inclusive; }; /* This structure holds information derived from option_revlist given @@ -46,6 +48,8 @@ struct revlist /* The number of fields in these revisions (one more than numdots). */ int fields; + /* Whether first & last are to be included or excluded. */ + int inclusive; }; /* This structure holds information parsed from the -d option. */ @@ -105,6 +109,9 @@ struct log_data_and_rcs RCSNode *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)); @@ -131,6 +138,9 @@ static void log_version PROTO ((struct log_data *, struct revlist *, static int log_branch PROTO ((Node *, void *)); static int version_compare PROTO ((const char *, const char *, int)); +static struct log_data log_data; +static int is_rlog; + static const char *const log_usage[] = { "Usage: %s %s [-lRhtNb] [-r[revisions]] [-d dates] [-s states]\n", @@ -142,6 +152,15 @@ static const char *const log_usage[] = "\t-N\tDo not list tags.\n", "\t-b\tOnly list revisions on the default branch.\n", "\t-r[revisions]\tSpecify revision(s)s to list.\n", + "\t rev1:rev2 Between rev1 and rev2, including rev1 and rev2.\n", + "\t rev1::rev2 Between rev1 and rev2, excluding rev1 and rev2.\n", + "\t rev: rev and following revisions on the same branch.\n", + "\t rev:: After rev on the same branch.\n", + "\t :rev rev and previous revisions on the same branch.\n", + "\t ::rev Before rev on the same branch.\n", + "\t rev Just rev.\n", + "\t branch All revisions on the branch.\n", + "\t branch. The last revision on the branch.\n", "\t-d dates\tSpecify dates (D1isremote) { struct datelist *p; struct option_revlist *rp; @@ -264,7 +286,10 @@ cvslog (argc, argv) /* We're the local client. Fire up the remote server. */ start_server (); - + + if (is_rlog && !supported_request ("rlog")) + error (1, 0, "server does not support rlog"); + ign_setup (); if (log_data.default_branch) @@ -332,6 +357,8 @@ cvslog (argc, argv) if (rp->first != NULL) send_to_server (rp->first, 0); send_to_server (":", 1); + if (!rp->inclusive) + send_to_server (":", 1); if (rp->last != NULL) send_to_server (rp->last, 0); } @@ -347,10 +374,19 @@ cvslog (argc, argv) send_arg_list ("-w", log_data.authorlist); dellist (&log_data.authorlist); - send_files (argc - optind, argv + optind, local, 0, SEND_NO_CONTENTS); - send_file_names (argc - optind, argv + optind, SEND_EXPAND_WILD); - - send_to_server ("log\012", 0); + if (is_rlog) + { + int i; + for (i = 0; i < argc; i++) + send_arg (argv[i]); + send_to_server ("rlog\012", 0); + } + else + { + send_files (argc, argv, local, 0, SEND_NO_CONTENTS); + send_file_names (argc, argv, SEND_EXPAND_WILD); + send_to_server ("log\012", 0); + } err = get_responses_and_close (); return err; } @@ -361,11 +397,24 @@ cvslog (argc, argv) if (findnode (log_data.authorlist, "@@MYSELF") != NULL) log_parse_list (&log_data.authorlist, getcaller ()); - err = start_recursion (log_fileproc, (FILESDONEPROC) NULL, log_dirproc, - (DIRLEAVEPROC) NULL, (void *) &log_data, - argc - optind, argv + optind, local, - W_LOCAL | W_REPOS | W_ATTIC, 0, 1, - (char *) NULL, 1); + if (is_rlog) + { + DBM *db; + int i; + db = open_module (); + for (i = 0; i < argc; i++) + { + err += do_module (db, argv[i], MISC, "Logging", rlog_proc, + (char *) NULL, 0, 0, 0, 0, (char *) NULL); + } + close_module (db); + } + else + { + err = rlog_proc (argc + 1, argv - 1, (char *) NULL, + (char *) NULL, (char *) NULL, 0, 0, (char *) NULL, + (char *) NULL); + } while (log_data.revlist) { @@ -403,6 +452,99 @@ cvslog (argc, argv) return (err); } + +static int +rlog_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg) + int argc; + char **argv; + char *xwhere; + char *mwhere; + char *mfile; + int shorten; + int local; + char *mname; + char *msg; +{ + /* Begin section which is identical to patch_proc--should this + be abstracted out somehow? */ + char *myargv[2]; + int err = 0; + int which; + char *repository; + char *where; + + if (is_rlog) + { + 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) + + 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 != NULL) + { + char *cp; + char *path; + + /* 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); + mfile = cp + 1; + } + + /* take care of the rest */ + path = xmalloc (strlen (repository) + strlen (mfile) + 5); + (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); + } + else + { + myargv[0] = argv[0]; + myargv[1] = mfile; + argc = 2; + argv = myargv; + } + free (path); + } + + /* cd to the starting repository */ + if ( CVS_CHDIR (repository) < 0) + { + error (0, errno, "cannot chdir to %s", repository); + free (repository); + return (1); + } + free (repository); + /* End section which is identical to patch_proc. */ + + which = W_REPOS | W_ATTIC; + } + else + { + where = NULL; + which = W_LOCAL | W_REPOS | W_ATTIC; + } + + err = start_recursion (log_fileproc, (FILESDONEPROC) NULL, log_dirproc, + (DIRLEAVEPROC) NULL, (void *) &log_data, + argc - 1, argv + 1, local, which, 0, 1, + where, 1); + return err; +} + + /* * Parse a revision list specification. */ @@ -442,10 +584,16 @@ log_parse_revlist (argstring) r->branchhead = 0; r->last = strchr (copy, ':'); if (r->last != NULL) + { *r->last++ = '\0'; + r->inclusive = (*r->last != ':'); + if (!r->inclusive) + r->last++; + } else { r->last = r->first; + r->inclusive = 1; if (r->first[0] != '\0' && r->first[strlen (r->first) - 1] == '.') { r->branchhead = 1; @@ -689,15 +837,15 @@ log_fileproc (callerdat, finfo) cvs_output ("RCS file: ", 0); cvs_output (rcsfile->path, 0); - cvs_output ("\nWorking file: ", 0); - if (finfo->update_dir[0] == '\0') - cvs_output (finfo->file, 0); - else + if (!is_rlog) { - cvs_output (finfo->update_dir, 0); - cvs_output ("/", 0); + cvs_output ("\nWorking file: ", 0); + if (finfo->update_dir[0] != '\0') + { + cvs_output (finfo->update_dir, 0); + cvs_output ("/", 0); + } cvs_output (finfo->file, 0); - } cvs_output ("\nhead:", 0); @@ -860,6 +1008,7 @@ log_expand_revlist (rcs, revlist, default_branch) struct revlist *nr; nr = (struct revlist *) xmalloc (sizeof *nr); + nr->inclusive = r->inclusive; if (r->first == NULL && r->last == NULL) { @@ -1023,6 +1172,7 @@ log_expand_revlist (rcs, revlist, default_branch) } nr->last = xstrdup (nr->first); nr->fields = numdots (nr->first) + 1; + nr->inclusive = 1; nr->next = NULL; *pr = nr; @@ -1137,9 +1287,12 @@ log_version_requested (log_data, revlist, rcs, vnode) vfields = numdots (v) + 1; for (r = revlist; r != NULL; r = r->next) { - if (vfields == r->fields + (r->fields & 1) - && version_compare (v, r->first, r->fields) >= 0 - && version_compare (v, r->last, r->fields) <= 0) + if (vfields == r->fields + (r->fields & 1) && + (r->inclusive ? + version_compare (v, r->first, r->fields) >= 0 + && version_compare (v, r->last, r->fields) <= 0 : + version_compare (v, r->first, r->fields) > 0 + && version_compare (v, r->last, r->fields) < 0)) { return 1; } diff --git a/contrib/cvs/src/login.c b/contrib/cvs/src/login.c index 1a774e0..9289737 100644 --- a/contrib/cvs/src/login.c +++ b/contrib/cvs/src/login.c @@ -85,26 +85,183 @@ construct_cvspass_filename () return passfile; } -static const char *const login_usage[] = + + +/* + * static char * + * password_entry_parseline ( + * const char *cvsroot_canonical, + * const unsigned char warn, + * const int linenumber, + * char *linebuf + * ); + * + * Internal function used by password_entry_operation. Parse a single line + * from a ~/.cvsroot password file and return a pointer to the password if the + * line refers to the same cvsroot as cvsroot_canonical + * + * INPUTS + * cvsroot_canonical the root we are looking for + * warn Boolean: print warnings for invalid lines? + * linenumber the line number for error messages + * linebuf the current line + * + * RETURNS + * NULL if the line doesn't match + * char *password as a pointer into linebuf + * + * NOTES + * This function temporarily alters linebuf, so it isn't thread safe when + * called on the same linebuf + */ +static char * +password_entry_parseline (cvsroot_canonical, warn, linenumber, linebuf) + const char *cvsroot_canonical; + const unsigned char warn; + const int linenumber; + char *linebuf; { - "Usage: %s %s\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; + char *password = NULL; + char *p; -/* Prompt for a password, and store it in the file "CVS/.cvspass". + /* look for '^/' */ + if (*linebuf == '/') + { + /* Yes: slurp '^/\d+\D' and parse the rest of the line according to version number */ + char *q; + unsigned long int entry_version; + + if (isspace(*(linebuf + 1))) + /* special case since strtoul ignores leading white space */ + entry_version = 0; + else + entry_version = strtoul (linebuf + 1, &q, 10); + + if (q == linebuf + 1) + /* no valid digits found by strtoul */ + entry_version = 0; + else + /* assume a delimiting seperator */ + q++; + + switch (entry_version) + { + case 1: + /* this means the same normalize_cvsroot we are using was + * used to create this entry. strcmp is good enough for + * us. + */ + p = strchr (q, ' '); + if (p == NULL) + { + if (warn && !really_quiet) + error (0, 0, "warning: skipping invalid entry in password file at line %d", + linenumber); + } + else + { + *p = '\0'; + if (strcmp (cvsroot_canonical, q) == 0) + password = p + 1; + *p = ' '; + } + break; + case ULONG_MAX: + if (warn && !really_quiet) + { + error (0, errno, "warning: unable to convert version number in password file at line %d", + linenumber); + error (0, 0, "skipping entry"); + } + break; + case 0: + if (warn && !really_quiet) + error (0, 0, "warning: skipping entry with invalid version string in password file at line %d", + linenumber); + break; + default: + if (warn && !really_quiet) + error (0, 0, "warning: skipping entry with unknown version (%lu) in password file at line %d", + entry_version, linenumber); + break; + } + } + else + { + /* No: assume: + * + * ^cvsroot Aencoded_password$ + * + * as header comment specifies and parse accordingly + */ + cvsroot_t *tmp_root; + char *tmp_root_canonical; + + p = strchr (linebuf, ' '); + if (p == NULL) + { + if (warn && !really_quiet) + error (0, 0, "warning: skipping invalid entry in password file at line %d", linenumber); + return NULL;; + } + + *p = '\0'; + if ((tmp_root = parse_cvsroot (linebuf)) == NULL) + { + if (warn && !really_quiet) + error (0, 0, "warning: skipping invalid entry in password file at line %d", linenumber); + *p = ' '; + return NULL; + } + *p = ' '; + tmp_root_canonical = normalize_cvsroot (tmp_root); + if (strcmp (cvsroot_canonical, tmp_root_canonical) == 0) + password = p + 1; + + free (tmp_root_canonical); + free_cvsroot_t (tmp_root); + } + + return password; +} + + + +/* + * static char * + * password_entry_operation ( + * password_entry_operation_t operation, + * cvsroot_t *root, + * char *newpassword + * ); + * + * Search the password file and depending on the value of operation: + * + * 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 * * Because the user might be accessing multiple repositories, with * different passwords for each one, the format of ~/.cvspass is: * - * user@host:/path Acleartext_password - * user@host:/path Acleartext_password + * [user@]host:[port]/path Aencoded_password + * [user@]host:[port]/path Aencoded_password * ... * - * Of course, the "user@" might be left off -- it's just based on the - * value of CVSroot. + * New entries are always of the form: + * + * /1 user@host:port/path Aencoded_password * - * The "A" before "cleartext_password" is a literal capital A. It's a + * but the old format is supported for backwards compatibility. + * The entry version string wasn't strictly necessary, but it avoids the + * overhead of parsing some entries since we know it is already in canonical + * form and allows room for expansion later, say, if we want to allow spaces + * and/or other characters to be escaped in the string. Also, the new entries + * would have been ignored by old versions of CVS anyhow since those versions + * didn't know how to parse a port number. + * + * The "A" before "encoded_password" is a literal capital A. It's a * version number indicating which form of scrambling we're doing on * the password -- someday we might provide something more secure than * the trivial encoding we do now, and when that day comes, it would @@ -114,201 +271,318 @@ static const char *const login_usage[] = * it from being read by others. Unlike .netrc, we will not be * fascist about it, at most issuing a warning, and never refusing to * work. + * + * INPUTS + * operation operation to perform + * root cvsroot_t to look up + * newpassword prescrambled new password, for password_entry_add_mode + * + * RETURNS + * -1 if password_entry_lookup_mode not specified + * NULL on failed lookup + * pointer to a copy of the password string otherwise, which the caller is + * responsible for disposing of */ -int -login (argc, argv) - int argc; - char **argv; + +typedef enum password_entry_operation_e { + password_entry_lookup, + password_entry_delete, + password_entry_add +} password_entry_operation_t; + +static char * +password_entry_operation (operation, root, newpassword) + password_entry_operation_t operation; + cvsroot_t *root; + char *newpassword; { char *passfile; FILE *fp; - char *typed_password, *found_password; - char *linebuf = (char *) NULL; - size_t linebuf_len; - int root_len, already_entered = 0; + char *cvsroot_canonical = NULL; + char *password = NULL; int line_length; + long line; + char *linebuf = NULL; + size_t linebuf_len; + char *p; + int save_errno = 0; - if (argc < 0) - usage (login_usage); + if (root->method != pserver_method) + { + error (0, 0, "internal error: can only call password_entry_operation with pserver method"); + error (1, 0, "CVSROOT: %s", root->original); + } + + /* Yes, the method below reads the user's password file twice when we have + * to delete an entry. It's inefficient, but we're not talking about a gig of + * data here. + */ - if (CVSroot_method != pserver_method) + passfile = construct_cvspass_filename (); + fp = CVS_FOPEN (passfile, "r"); + if (fp == NULL) { - error (0, 0, "can only use pserver method with `login' command"); - error (1, 0, "CVSROOT: %s", CVSroot_original); + error (0, errno, "failed to open %s for reading", passfile); + goto error_exit; } - if (! CVSroot_username) + cvsroot_canonical = normalize_cvsroot (root); + + /* Check each line to see if we have this entry already. */ + line = 0; + while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0) + { + line++; + password = password_entry_parseline(cvsroot_canonical, 1, line, linebuf); + if (password != NULL) + /* this is it! break out and deal with linebuf */ + break; + } + if (line_length < 0 && !feof (fp)) { - error (0, 0, "CVSROOT \"%s\" is not fully-qualified.", - CVSroot_original); - error (1, 0, "Please make sure to specify \"user@host\"!"); + error (0, errno, "cannot read %s", passfile); + goto error_exit; } + if (fclose (fp) < 0) + /* not fatal, unless it cascades */ + error (0, errno, "cannot close %s", passfile); + fp = NULL; - printf ("(Logging in to %s@%s)\n", CVSroot_username, CVSroot_hostname); - fflush (stdout); + /* Utter, total, raving paranoia, I know. */ + chmod (passfile, 0600); - passfile = construct_cvspass_filename (); - typed_password = GETPASS ("CVS password: "); - typed_password = scramble (typed_password); + /* a copy to return or keep around so we can reuse linebuf */ + if (password != NULL) + { + /* chomp the EOL */ + p = strchr (password, '\n'); + if (p != NULL) + *p = '\0'; + password = xstrdup (password); + } - /* Force get_cvs_password() to use this one (when the client - * confirms the new password with the server), instead of - * consulting the file. We make a new copy because cvs_password - * will get zeroed by connect_to_server(). */ + /* might as well return now */ + if (operation == password_entry_lookup) + goto out; - cvs_password = xstrdup (typed_password); + /* same here */ + if (operation == password_entry_delete && password == NULL) + { + error (0, 0, "Entry not found."); + goto out; + } - connect_to_pserver (NULL, NULL, 1, 0); + /* okay, file errors can simply be fatal from now on since we don't do + * anything else if we're in lookup mode + */ - /* IF we have a password for this "[user@]host:/path" already - * THEN - * IF it's the same as the password we read from the prompt - * THEN - * do nothing - * ELSE - * replace the old password with the new one - * ELSE - * append new entry to the end of the file. + /* copy the file with the entry deleted unless we're in add + * mode and the line we found contains the same password we're supposed to + * add */ + if (!noexec && password != NULL && (operation == password_entry_delete + || (operation == password_entry_add && strcmp (password, newpassword)))) + { + long found_at = line; + char *tmp_name; + FILE *tmp_fp; - root_len = strlen (CVSroot_original); + /* open the original file again */ + fp = CVS_FOPEN (passfile, "r"); + if (fp == NULL) + error (1, errno, "failed to open %s for reading", passfile); - /* Yes, the method below reads the user's password file twice. It's - inefficient, but we're not talking about a gig of data here. */ + /* create and open a temp file */ + if ((tmp_fp = cvs_temp_file (&tmp_name)) == NULL) + error (1, errno, "unable to open temp file %s", tmp_name); - fp = CVS_FOPEN (passfile, "r"); - /* FIXME: should be printing a message if fp == NULL and not - existence_error (errno). */ - if (fp != NULL) - { - /* Check each line to see if we have this entry already. */ + line = 0; while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0) - { - if (strncmp (CVSroot_original, linebuf, root_len) == 0) - { - already_entered = 1; - break; - } - } + { + line++; + if (line < found_at + || (line != found_at + && !password_entry_parseline(cvsroot_canonical, 0, line, linebuf))) + { + if (fprintf (tmp_fp, "%s", linebuf) == EOF) + { + /* try and clean up anyhow */ + error (0, errno, "fatal error: cannot write %s", tmp_name); + if (fclose (tmp_fp) == EOF) + error (0, errno, "cannot close %s", tmp_name); + /* call CVS_UNLINK instead of unlink_file since the file + * got created in noexec mode + */ + if (CVS_UNLINK (tmp_name) < 0) + error (0, errno, "cannot remove %s", tmp_name); + /* but quit so we don't remove all the entries from a + * user's password file accidentally + */ + error (1, 0, "exiting"); + } + } + } + if (line_length < 0 && !feof (fp)) + { + error (0, errno, "cannot read %s", passfile); + goto error_exit; + } if (fclose (fp) < 0) + /* not fatal, unless it cascades */ error (0, errno, "cannot close %s", passfile); - } - else if (!existence_error (errno)) - error (0, errno, "cannot open %s", passfile); - - if (already_entered) - { - /* This user/host has a password in the file already. */ - - strtok (linebuf, " "); - found_password = strtok (NULL, "\n"); - if (strcmp (found_password, typed_password)) - { - /* typed_password and found_password don't match, so we'll - * have to update passfile. We replace the old password - * with the new one by writing a tmp file whose contents are - * exactly the same as passfile except that this one entry - * gets typed_password instead of found_password. Then we - * rename the tmp file on top of passfile. + if (fclose (tmp_fp) < 0) + /* not fatal, unless it cascades */ + /* FIXME - does copy_file return correct results if the file wasn't + * closed? should this be fatal? */ - char *tmp_name; - FILE *tmp_fp; - - tmp_name = cvs_temp_name (); - if ((tmp_fp = CVS_FOPEN (tmp_name, "w")) == NULL) - { - error (1, errno, "unable to open temp file %s", tmp_name); - return 1; - } - chmod (tmp_name, 0600); - - fp = CVS_FOPEN (passfile, "r"); - if (fp == NULL) - { - error (1, errno, "unable to open %s", passfile); - if (linebuf) - free (linebuf); - return 1; - } - /* I'm not paranoid, they really ARE out to get me: */ - chmod (passfile, 0600); - - while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0) - { - if (strncmp (CVSroot_original, linebuf, root_len)) - { - if (fprintf (tmp_fp, "%s", linebuf) == EOF) - error (0, errno, "cannot write %s", tmp_name); - } - else - { - if (fprintf (tmp_fp, "%s %s\n", CVSroot_original, - typed_password) == EOF) - error (0, errno, "cannot write %s", tmp_name); - } - } - if (line_length < 0 && !feof (fp)) - error (0, errno, "cannot read %s", passfile); - if (linebuf) - free (linebuf); - if (fclose (tmp_fp) < 0) - error (0, errno, "cannot close %s", tmp_name); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", passfile); - - /* FIXME: rename_file would make more sense (e.g. almost - always faster). */ - copy_file (tmp_name, passfile); - if (unlink_file (tmp_name) < 0) - error (0, errno, "cannot remove %s", tmp_name); - chmod (passfile, 0600); - - free (tmp_name); - } + error (0, errno, "cannot close %s", tmp_name); + + /* FIXME: rename_file would make more sense (e.g. almost + * always faster). + * + * I don't think so, unless we change the way rename_file works to + * attempt a cp/rm sequence when rename fails since rename doesn't + * work across file systems and it isn't uncommon to have /tmp + * on its own partition. + * + * For that matter, it's probably not uncommon to have a home + * directory on an NFS mount. + */ + copy_file (tmp_name, passfile); + if (CVS_UNLINK (tmp_name) < 0) + error (0, errno, "cannot remove %s", tmp_name); + free (tmp_name); } - else + + /* in add mode, if we didn't find an entry or found an entry with a + * different password, append the new line + */ + if (!noexec && operation == password_entry_add + && (password == NULL || strcmp (password, newpassword))) { - if (linebuf) - free (linebuf); if ((fp = CVS_FOPEN (passfile, "a")) == NULL) - { - error (1, errno, "could not open %s", passfile); - free (passfile); - return 1; - } - - if (fprintf (fp, "%s %s\n", CVSroot_original, typed_password) == EOF) - error (0, errno, "cannot write %s", passfile); + error (1, errno, "could not open %s for writing", passfile); + + if (fprintf (fp, "/1 %s %s\n", cvsroot_canonical, newpassword) == EOF) + error (1, errno, "cannot write %s", passfile); if (fclose (fp) < 0) error (0, errno, "cannot close %s", passfile); } /* Utter, total, raving paranoia, I know. */ chmod (passfile, 0600); + + if (password) + { + free (password); + password = NULL; + } + if (linebuf) + free (linebuf); + +out: + free (cvsroot_canonical); + free (passfile); + return password; + +error_exit: + /* just exit when we're not in lookup mode */ + if (operation != password_entry_lookup) + error (1, 0, "fatal error: exiting"); + /* clean up and exit in lookup mode so we can try a login with a NULL + * password anyhow in case that's what we would have found + */ + save_errno = errno; + if (fp != NULL) + { + /* Utter, total, raving paranoia, I know. */ + chmod (passfile, 0600); + if(fclose (fp) < 0) + error (0, errno, "cannot close %s", passfile); + } + if (linebuf) + free (linebuf); + if (cvsroot_canonical) + free (cvsroot_canonical); + free (passfile); + errno = save_errno; + return NULL; +} + + + +/* Prompt for a password, and store it in the file "CVS/.cvspass". + */ + +static const char *const login_usage[] = +{ + "Usage: %s %s\n", + "(Specify the --help global option for a list of other help options)\n", + NULL +}; + +int +login (argc, argv) + int argc; + char **argv; +{ + char *typed_password; + char *cvsroot_canonical; + + if (argc < 0) + usage (login_usage); + + if (current_parsed_root->method != pserver_method) + { + error (0, 0, "can only use `login' command with the 'pserver' method"); + error (1, 0, "CVSROOT: %s", current_parsed_root->original); + } + + cvsroot_canonical = normalize_cvsroot(current_parsed_root); + printf ("Logging in to %s\n", cvsroot_canonical); + fflush (stdout); + + if (current_parsed_root->password) + { + typed_password = scramble (current_parsed_root->password); + } + else + { + char *tmp; + tmp = GETPASS ("CVS password: "); + typed_password = scramble (tmp); + memset (tmp, 0, strlen (tmp)); + } + + /* Force get_cvs_password() to use this one (when the client + * confirms the new password with the server), instead of + * consulting the file. We make a new copy because cvs_password + * will get zeroed by connect_to_server(). */ + cvs_password = xstrdup (typed_password); + + connect_to_pserver (NULL, NULL, 1, 0); + + password_entry_operation (password_entry_add, current_parsed_root, typed_password); + memset (typed_password, 0, strlen (typed_password)); free (typed_password); - free (passfile); free (cvs_password); + free (cvsroot_canonical); cvs_password = NULL; + return 0; } /* Returns the _scrambled_ password. The server must descramble before hashing and comparing. If password file not found, or - password not found in the file, just return NULL. */ + password not found in the file, just return NULL. */ char * get_cvs_password () { - int found_it = 0; - int root_len; - char *password = NULL; - char *linebuf = NULL; - size_t linebuf_len; - FILE *fp; - char *passfile; - int line_length; - + if (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 password. */ @@ -318,76 +592,24 @@ get_cvs_password () if (getenv ("CVS_PASSWORD") != NULL) { /* In previous versions of CVS one could specify a password in - CVS_PASSWORD. This is a bad idea, because in BSD variants - of unix anyone can see the environment variable with 'ps'. - But for users who were using that feature we want to at - least let them know what is going on. After printing this - warning, we should fall through to the regular error where - we tell them to run "cvs login" (unless they already ran - it, of course). */ - error (0, 0, "CVS_PASSWORD is no longer supported; ignored"); + * CVS_PASSWORD. This is a bad idea, because in BSD variants + * of unix anyone can see the environment variable with 'ps'. + * But for users who were using that feature we want to at + * least let them know what is going on. After printing this + * warning, we should fall through to the regular error where + * we tell them to run "cvs login" (unless they already ran + * it, of course). + */ + error (0, 0, "CVS_PASSWORD is no longer supported; ignored"); } - /* Else get it from the file. First make sure that the CVSROOT - variable has the appropriate fields filled in. */ - - if (CVSroot_method != pserver_method) + if (current_parsed_root->method != pserver_method) { - error (0, 0, "can only call GET_CVS_PASSWORD with pserver method"); - error (1, 0, "CVSROOT: %s", CVSroot_original); + error (0, 0, "can only call get_cvs_password with pserver method"); + error (1, 0, "CVSROOT: %s", current_parsed_root->original); } - if (! CVSroot_username) - { - error (0, 0, "CVSROOT \"%s\" is not fully-qualified.", - CVSroot_original); - error (1, 0, "Please make sure to specify \"user@host\"!"); - } - - passfile = construct_cvspass_filename (); - fp = CVS_FOPEN (passfile, "r"); - if (fp == NULL) - { - free (passfile); - return NULL; - } - - root_len = strlen (CVSroot_original); - - /* Check each line to see if we have this entry already. */ - while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0) - { - if (strncmp (CVSroot_original, linebuf, root_len) == 0) - { - /* This is it! So break out and deal with linebuf. */ - found_it = 1; - break; - } - } - if (line_length < 0 && !feof (fp)) - error (0, errno, "cannot read %s", passfile); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", passfile); - - if (found_it) - { - /* linebuf now contains the line with the password. */ - char *tmp; - - strtok (linebuf, " "); - tmp = strtok (NULL, "\n"); - if (tmp == NULL) - error (1, 0, "bad entry in %s for %s", passfile, CVSroot_original); - - /* Give it permanent storage. */ - password = xstrdup (tmp); - memset (tmp, 0, strlen (password)); - } - - if (linebuf) - free (linebuf); - free (passfile); - return password; + return password_entry_operation (password_entry_lookup, current_parsed_root, NULL); } static const char *const logout_usage[] = @@ -403,29 +625,15 @@ logout (argc, argv) int argc; char **argv; { - char *passfile; - FILE *fp; - char *tmp_name = NULL; - FILE *tmp_fp; - char *linebuf = (char *) NULL; - size_t linebuf_len; - int root_len, found = 0; - int line_length; + char *cvsroot_canonical; if (argc < 0) usage (logout_usage); - if (CVSroot_method != pserver_method) + if (current_parsed_root->method != pserver_method) { error (0, 0, "can only use pserver method with `logout' command"); - error (1, 0, "CVSROOT: %s", CVSroot_original); - } - - if (! CVSroot_username) - { - error (0, 0, "CVSROOT \"%s\" is not fully-qualified.", - CVSroot_original); - error (1, 0, "Please make sure to specify \"user@host\"!"); + error (1, 0, "CVSROOT: %s", current_parsed_root->original); } /* Hmm. Do we want a variant of this command which deletes _all_ @@ -436,73 +644,15 @@ logout (argc, argv) of security, in that it wouldn't delete entries from any .cvspass files but the current one. */ - printf ("(Logging out of %s@%s)\n", CVSroot_username, CVSroot_hostname); - fflush (stdout); - - /* IF we have a password for this "[user@]host:/path" already - * THEN - * drop the entry - * ELSE - * do nothing - */ - - passfile = construct_cvspass_filename (); - /* FIXME: This should not be in /tmp; that is almost surely a security - hole. Probably should just keep it in memory. */ - tmp_name = cvs_temp_name (); - if ((tmp_fp = CVS_FOPEN (tmp_name, "w")) == NULL) + if (!quiet) { - error (1, errno, "unable to open temp file %s", tmp_name); - return 1; - } - chmod (tmp_name, 0600); - - root_len = strlen (CVSroot_original); - - fp = CVS_FOPEN (passfile, "r"); - if (fp == NULL) - error (1, errno, "Error opening %s", passfile); - - /* Check each line to see if we have this entry. */ - /* Copy only those lines that do not match this entry */ - while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0) - { - if (strncmp (CVSroot_original, linebuf, root_len)) - { - if (fprintf (tmp_fp, "%s", linebuf) == EOF) - error (0, errno, "cannot write %s", tmp_name); - } - else - found = 1; - } - if (line_length < 0 && !feof (fp)) - error (0, errno, "cannot read %s", passfile); - - if (linebuf) - free (linebuf); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", passfile); - if (fclose (tmp_fp) < 0) - error (0, errno, "cannot close %s", tmp_name); - - if (! found) - { - printf ("Entry not found for %s\n", CVSroot_original); - if (unlink_file (tmp_name) < 0) - error (0, errno, "cannot remove %s", tmp_name); - } - else - { - /* FIXME: rename_file would make more sense (e.g. almost - always faster). */ - copy_file (tmp_name, passfile); - if (unlink_file (tmp_name) < 0) - error (0, errno, "cannot remove %s", tmp_name); - chmod (passfile, 0600); + cvsroot_canonical = normalize_cvsroot(current_parsed_root); + printf ("Logging out of %s\n", cvsroot_canonical); + fflush (stdout); + free (cvsroot_canonical); } - if (tmp_name) - free (tmp_name); + password_entry_operation (password_entry_delete, current_parsed_root, NULL); return 0; } diff --git a/contrib/cvs/src/logmsg.c b/contrib/cvs/src/logmsg.c index cb08cdf..d2ef806 100644 --- a/contrib/cvs/src/logmsg.c +++ b/contrib/cvs/src/logmsg.c @@ -190,8 +190,10 @@ do_editor (dir, messagep, repository, changes) if (strcmp (Editor, "") == 0 && !editinfo_editor) error(1, 0, "no editor defined, must use -e or -m"); - /* Create a temporary file */ + /* FIXME - It's possible we should be relying on cvs_temp_file to open + * the file here - we get race conditions otherwise. + */ fname = cvs_temp_name (); again: if ((fp = CVS_FOPEN (fname, "w+")) == NULL) @@ -205,8 +207,6 @@ do_editor (dir, messagep, repository, changes) (*messagep)[strlen (*messagep) - 1] != '\n') (void) fprintf (fp, "\n"); } - else - (void) fprintf (fp, "\n"); if (repository != NULL) /* tack templates on if necessary */ @@ -272,7 +272,7 @@ do_editor (dir, messagep, repository, changes) free (editinfo_editor); editinfo_editor = (char *) NULL; #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) ; /* nothing, leave editinfo_editor NULL */ else #endif @@ -396,7 +396,7 @@ do_verify (message, repository) int retcode = 0; #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) /* The verification will happen on the server. */ return; #endif @@ -414,13 +414,10 @@ do_verify (message, repository) return; } - /* Get a temp filename, open a temporary file, write the message to the + /* open a temporary file, write the message to the temp file, and close the file. */ - fname = cvs_temp_name (); - - fp = fopen (fname, "w"); - if (fp == NULL) + if ((fp = cvs_temp_file (&fname)) == NULL) error (1, errno, "cannot create temporary file %s", fname); else { @@ -792,16 +789,16 @@ logfile_write (repository, filter, message, logfp, changes) srepos = Short_Repository (repository); - prog = xmalloc ((fmt_percent - filter) + strlen (srepos) - + strlen (str_list) + strlen (fmt_continue) + prog = cp = xmalloc ((fmt_percent - filter) + 2 * strlen (srepos) + + 2 * strlen (str_list) + strlen (fmt_continue) + 10); - (void) strncpy (prog, filter, fmt_percent - filter); - prog[fmt_percent - filter] = '\0'; - (void) strcat (prog, "'"); - (void) strcat (prog, srepos); - (void) strcat (prog, str_list); - (void) strcat (prog, "'"); - (void) strcat (prog, fmt_continue); + (void) memcpy (cp, filter, fmt_percent - filter); + cp += fmt_percent - filter; + *cp++ = '"'; + cp = shell_escape (cp, srepos); + cp = shell_escape (cp, str_list); + *cp++ = '"'; + (void) strcpy (cp, fmt_continue); /* To be nice, free up some memory. */ diff --git a/contrib/cvs/src/main.c b/contrib/cvs/src/main.c index 86913e1..3a21916 100644 --- a/contrib/cvs/src/main.c +++ b/contrib/cvs/src/main.c @@ -64,8 +64,12 @@ char *Editor = EDITOR_DFLT; List *root_directories = NULL; /* We step through the above values. This variable is set to reflect - the currently active value. */ -char *current_root = NULL; + * the currently active value. + * + * Now static. FIXME - this variable should be removable (well, localizable) + * with a little more work. + */ +static char *current_root = NULL; static const struct cmd @@ -96,47 +100,50 @@ static const struct cmd char *nick2; int (*func) (); /* Function takes (argc, argv) arguments. */ + unsigned long attr; /* Attributes. */ } cmds[] = { - { "add", "ad", "new", add }, - { "admin", "adm", "rcs", admin }, - { "annotate", "ann", NULL, annotate }, - { "checkout", "co", "get", checkout }, - { "commit", "ci", "com", commit }, - { "diff", "di", "dif", diff }, - { "edit", NULL, NULL, edit }, - { "editors", NULL, NULL, editors }, - { "export", "exp", "ex", checkout }, - { "history", "hi", "his", history }, - { "import", "im", "imp", import }, - { "init", NULL, NULL, init }, + { "add", "ad", "new", add, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, + { "admin", "adm", "rcs", admin, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, + { "annotate", "ann", NULL, annotate, CVS_CMD_USES_WORK_DIR }, + { "checkout", "co", "get", checkout, 0 }, + { "commit", "ci", "com", commit, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, + { "diff", "di", "dif", diff, CVS_CMD_USES_WORK_DIR }, + { "edit", NULL, NULL, edit, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, + { "editors", NULL, NULL, editors, CVS_CMD_USES_WORK_DIR }, + { "export", "exp", "ex", checkout, CVS_CMD_USES_WORK_DIR }, + { "history", "hi", "his", history, CVS_CMD_USES_WORK_DIR }, + { "import", "im", "imp", import, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR | CVS_CMD_IGNORE_ADMROOT}, + { "init", NULL, NULL, init, CVS_CMD_MODIFIES_REPOSITORY }, #if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT) - { "kserver", NULL, NULL, server }, /* placeholder */ + { "kserver", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, /* placeholder */ #endif - { "log", "lo", "rlog", cvslog }, + { "log", "lo", NULL, cvslog, CVS_CMD_USES_WORK_DIR }, #ifdef AUTH_CLIENT_SUPPORT - { "login", "logon", "lgn", login }, - { "logout", NULL, NULL, logout }, + { "login", "logon", "lgn", login, 0 }, + { "logout", NULL, NULL, logout, 0 }, #endif /* AUTH_CLIENT_SUPPORT */ #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT) - { "pserver", NULL, NULL, server }, /* placeholder */ + { "pserver", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, /* placeholder */ #endif - { "rdiff", "patch", "pa", patch }, - { "release", "re", "rel", release }, - { "remove", "rm", "delete", cvsremove }, - { "rtag", "rt", "rfreeze", rtag }, + { "rannotate","rann", "ra", annotate, 0 }, + { "rdiff", "patch", "pa", patch, 0 }, + { "release", "re", "rel", release, 0 }, + { "remove", "rm", "delete", cvsremove, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, + { "rlog", "rl", NULL, cvslog, 0 }, + { "rtag", "rt", "rfreeze", cvstag, CVS_CMD_MODIFIES_REPOSITORY }, #ifdef SERVER_SUPPORT - { "server", NULL, NULL, server }, + { "server", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, #endif - { "status", "st", "stat", cvsstatus }, - { "tag", "ta", "freeze", cvstag }, - { "unedit", NULL, NULL, unedit }, - { "update", "up", "upd", update }, - { "version", "ve", "ver", version }, - { "watch", NULL, NULL, watch }, - { "watchers", NULL, NULL, watchers }, - { NULL, NULL, NULL, NULL }, + { "status", "st", "stat", cvsstatus, CVS_CMD_USES_WORK_DIR }, + { "tag", "ta", "freeze", cvstag, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, + { "unedit", NULL, NULL, unedit, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, + { "update", "up", "upd", update, CVS_CMD_USES_WORK_DIR }, + { "version", "ve", "ver", version, 0 }, + { "watch", NULL, NULL, watch, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, + { "watchers", NULL, NULL, watchers, CVS_CMD_USES_WORK_DIR }, + { NULL, NULL, NULL, NULL, 0 }, }; static const char *const usg[] = @@ -211,9 +218,11 @@ static const char *const cmd_usage[] = #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT) " pserver Password server mode\n", #endif + " rannotate Show last revision where each line of module was modified\n", " rdiff Create 'patch' format diffs between releases\n", " release Indicate that a Module is no longer in use\n", " remove Remove an entry from the repository\n", + " rlog Print out history information for a module\n", " rtag Add a symbolic tag to a module\n", #ifdef SERVER_SUPPORT " server Server mode\n", @@ -222,6 +231,7 @@ static const char *const cmd_usage[] = " tag Add a symbolic tag to checked out version of files\n", " unedit Undo an edit command\n", " update Bring work tree in sync with repository\n", + " version Show current CVS version(s)\n", " watch Set watches\n", " watchers See who is watching a file\n", "(Specify the --help option for a list of other help options)\n", @@ -315,51 +325,14 @@ unsigned long int lookup_command_attribute (cmd_name) char *cmd_name; { - unsigned long int ret = 0; - - if (strcmp (cmd_name, "import") != 0) - { - ret |= CVS_CMD_IGNORE_ADMROOT; - } - - - /* The following commands do not use a checked-out working - directory. We conservatively assume that everything else does. - Feel free to add to this list if you are _certain_ something - something doesn't use the WD. */ - if ((strcmp (cmd_name, "checkout") != 0) && - (strcmp (cmd_name, "init") != 0) && - (strcmp (cmd_name, "login") != 0) && - (strcmp (cmd_name, "logout") != 0) && - (strcmp (cmd_name, "rdiff") != 0) && - (strcmp (cmd_name, "release") != 0) && - (strcmp (cmd_name, "rtag") != 0)) - { - ret |= CVS_CMD_USES_WORK_DIR; - } - + const struct cmd *cm; - /* The following commands do not modify the repository; we - conservatively assume that everything else does. Feel free to - add to this list if you are _certain_ something is safe. */ - if ((strcmp (cmd_name, "annotate") != 0) && - (strcmp (cmd_name, "checkout") != 0) && - (strcmp (cmd_name, "diff") != 0) && - (strcmp (cmd_name, "rdiff") != 0) && - (strcmp (cmd_name, "update") != 0) && - (strcmp (cmd_name, "editors") != 0) && - (strcmp (cmd_name, "export") != 0) && - (strcmp (cmd_name, "history") != 0) && - (strcmp (cmd_name, "log") != 0) && - (strcmp (cmd_name, "noop") != 0) && - (strcmp (cmd_name, "watchers") != 0) && - (strcmp (cmd_name, "release") != 0) && - (strcmp (cmd_name, "status") != 0)) + for (cm = cmds; cm->fullname; cm++) { - ret |= CVS_CMD_MODIFIES_REPOSITORY; + if (strcmp (cmd_name, cm->fullname) == 0) + break; } - - return ret; + return cm->attr; } @@ -570,7 +543,7 @@ main (argc, argv) version (0, (char **) NULL); (void) fputs ("\n", stdout); (void) fputs ("\ -Copyright (c) 1989-2000 Brian Berliner, david d `zoo' zuhn, \n\ +Copyright (c) 1989-2001 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); @@ -601,6 +574,8 @@ Copyright (c) 1989-2000 Brian Berliner, david d `zoo' zuhn, \n\ if (CVSroot_cmdline != NULL) free (CVSroot_cmdline); CVSroot_cmdline = xstrdup (optarg); + if (free_CVSroot) + free (CVSroot); CVSroot = xstrdup (optarg); free_CVSroot = 1; cvs_update_env = 1; /* need to update environment */ @@ -676,15 +651,6 @@ Copyright (c) 1989-2000 Brian Berliner, david d `zoo' zuhn, \n\ else command_name = cm->fullname; /* Global pointer for later use */ - /* This should probably remain a warning, rather than an error, - for quite a while. For one thing the version of VC distributed - with GNU emacs 19.34 invokes 'cvs rlog' instead of 'cvs log'. */ - if (strcmp (argv[0], "rlog") == 0) - { - error (0, 0, "warning: the rlog command is deprecated"); - error (0, 0, "use the synonymous log command instead"); - } - if (help) { argc = -1; /* some functions only check for this */ @@ -833,8 +799,7 @@ Copyright (c) 1989-2000 Brian Berliner, david d `zoo' zuhn, \n\ specify a different repository than the one we are importing to. */ - if ((lookup_command_attribute (command_name) - & CVS_CMD_IGNORE_ADMROOT) + if (!(cm->attr & CVS_CMD_IGNORE_ADMROOT) /* -d overrides CVS/Root, so don't give an error if the latter points to a nonexistent repository. */ @@ -926,25 +891,29 @@ Copyright (c) 1989-2000 Brian Berliner, david d `zoo' zuhn, \n\ variable. Parse it to see if we're supposed to do remote accesses or use a special access method. */ - if (parse_cvsroot (current_root)) + if (current_parsed_root != NULL) + free_cvsroot_t (current_parsed_root); + if ((current_parsed_root = parse_cvsroot (current_root)) == NULL) error (1, 0, "Bad CVSROOT."); if (trace) - error (0, 0, "notice: main loop with CVSROOT=%s", - current_root); + fprintf (stderr, "%s-> main loop with CVSROOT=%s\n", + CLIENT_SERVER_STR, current_root); /* * Check to see if the repository exists. */ - if (!client_active) +#ifdef CLIENT_SUPPORT + if (!current_parsed_root->isremote) +#endif /* CLIENT_SUPPORT */ { char *path; int save_errno; - path = xmalloc (strlen (CVSroot_directory) + path = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) - + 20); - (void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM); + + 2); + (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM); if (!isaccessible (path, R_OK | X_OK)) { save_errno = errno; @@ -989,7 +958,7 @@ Copyright (c) 1989-2000 Brian Berliner, david d `zoo' zuhn, \n\ && !server_active #endif #ifdef CLIENT_SUPPORT - && !client_active + && !current_parsed_root->isremote #endif ) { @@ -997,11 +966,15 @@ Copyright (c) 1989-2000 Brian Berliner, david d `zoo' zuhn, \n\ already printed an error. We keep going. Why? Because if we didn't, then there would be no way to check in a new CVSROOT/config file to fix the broken one! */ - parse_config (CVSroot_directory); + parse_config (current_parsed_root->directory); } #ifdef CLIENT_SUPPORT - if (client_active) + /* Need to check for current_parsed_root != NULL here since + * we could still be in server mode before the server function + * gets called below and sets the root + */ + if (current_parsed_root != NULL && current_parsed_root->isremote) { /* Create a new list for directory names that we've sent to the server. */ @@ -1119,31 +1092,55 @@ date_from_time_t (unixtime) void date_to_internet (dest, source) char *dest; - char *source; + const char *source; { - int year, month, day, hour, minute, second; + struct tm date; - /* Just to reiterate, these strings are from RFC822 and do not vary - according to locale. */ - static const char *const month_names[] = - {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + date_to_tm (&date, source); + tm_to_internet (dest, &date); +} +void +date_to_tm (dest, source) + struct tm *dest; + const char *source; +{ if (sscanf (source, SDATEFORM, - &year, &month, &day, &hour, &minute, &second) - != 6) + &dest->tm_year, &dest->tm_mon, &dest->tm_mday, + &dest->tm_hour, &dest->tm_min, &dest->tm_sec) + != 6) /* Is there a better way to handle errors here? I made this non-fatal in case we are called from the code which can't deal with fatal errors. */ error (0, 0, "internal error: bad date %s", source); - /* Always send a four digit year. */ - if (year < 100) - year += 1900; + if (dest->tm_year > 100) + dest->tm_year -= 1900; + + dest->tm_mon -= 1; +} + +/* Convert a date to RFC822/1123 format. This is used in contexts like + dates to send in the protocol; it should not vary based on locale or + other such conventions for users. We should have another routine which + does that kind of thing. - sprintf (dest, "%d %s %d %02d:%02d:%02d -0000", day, - month < 1 || month > 12 ? "???" : month_names[month - 1], - year, hour, minute, second); + The SOURCE date is a pointer to a struct tm. DEST should point to + storage managed by the caller, at least MAXDATELEN characters. */ +void +tm_to_internet (dest, source) + char *dest; + const struct tm *source; +{ + /* Just to reiterate, these strings are from RFC822 and do not vary + according to locale. */ + static const char *const month_names[] = + {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + + sprintf (dest, "%d %s %d %02d:%02d:%02d -0000", source->tm_mday, + source->tm_mon < 0 || source->tm_mon > 11 ? "???" : month_names[source->tm_mon], + source->tm_year + 1900, source->tm_hour, source->tm_min, source->tm_sec); } void diff --git a/contrib/cvs/src/mkmodules.c b/contrib/cvs/src/mkmodules.c index 4e4b5d0..d1f7ac7 100644 --- a/contrib/cvs/src/mkmodules.c +++ b/contrib/cvs/src/mkmodules.c @@ -848,7 +848,7 @@ init (argc, argv) usage (init_usage); #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { start_server (); @@ -862,12 +862,10 @@ init (argc, argv) old cvsinit.sh script did. Few utilities do that, and a non-existent parent directory is as likely to be a typo as something which needs to be created. */ - mkdir_if_needed (CVSroot_directory); + mkdir_if_needed (current_parsed_root->directory); - adm = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM) + 10); - strcpy (adm, CVSroot_directory); - strcat (adm, "/"); - strcat (adm, CVSROOTADM); + adm = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) + 2); + sprintf (adm, "%s/%s", current_parsed_root->directory, CVSROOTADM); mkdir_if_needed (adm); /* This is needed because we pass "fileptr->filename" not "info" diff --git a/contrib/cvs/src/modules.c b/contrib/cvs/src/modules.c index 0381ec9..d349530 100644 --- a/contrib/cvs/src/modules.c +++ b/contrib/cvs/src/modules.c @@ -65,14 +65,15 @@ open_module () char *mfile; DBM *retval; - if (CVSroot_original == NULL) + if (current_parsed_root == NULL) { error (0, 0, "must set the CVSROOT environment variable"); error (1, 0, "or specify the '-d' global option"); } - mfile = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM) - + sizeof (CVSROOTADM_MODULES) + 20); - (void) sprintf (mfile, "%s/%s/%s", CVSroot_directory, + mfile = xmalloc (strlen (current_parsed_root->directory) + + sizeof (CVSROOTADM) + + sizeof (CVSROOTADM_MODULES) + 3); + (void) sprintf (mfile, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, CVSROOTADM_MODULES); retval = dbm_open (mfile, O_RDONLY, 0666); free (mfile); @@ -96,8 +97,8 @@ close_module (db) * 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, extra_arg) +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; @@ -107,6 +108,7 @@ do_module (db, mname, m_type, msg, callback_proc, where, int shorten; int local_specified; int run_module_prog; + int build_dirs; char *extra_arg; { char *checkin_prog = NULL; @@ -211,19 +213,21 @@ do_module (db, mname, m_type, msg, callback_proc, where, int is_found = 0; /* check to see if mname is a directory or file */ - file = xmalloc (strlen (CVSroot_directory) + strlen (mname) + 10); - (void) sprintf (file, "%s/%s", CVSroot_directory, mname); - attic_file = xmalloc (strlen (CVSroot_directory) + strlen (mname) - + sizeof (CVSATTIC) + sizeof (RCSEXT) + 15); + file = xmalloc (strlen (current_parsed_root->directory) + + strlen (mname) + sizeof(RCSEXT) + 2); + (void) sprintf (file, "%s/%s", current_parsed_root->directory, mname); + attic_file = xmalloc (strlen (current_parsed_root->directory) + + strlen (mname) + + sizeof (CVSATTIC) + sizeof (RCSEXT) + 3); if ((acp = strrchr (mname, '/')) != NULL) { *acp = '\0'; - (void) sprintf (attic_file, "%s/%s/%s/%s%s", CVSroot_directory, + (void) sprintf (attic_file, "%s/%s/%s/%s%s", current_parsed_root->directory, mname, CVSATTIC, acp + 1, RCSEXT); *acp = '/'; } else - (void) sprintf (attic_file, "%s/%s/%s%s", CVSroot_directory, + (void) sprintf (attic_file, "%s/%s/%s%s", current_parsed_root->directory, CVSATTIC, mname, RCSEXT); if (isdir (file)) @@ -400,7 +404,7 @@ do_module (db, mname, m_type, msg, callback_proc, where, */ /* Put the value on a line with XXX prepended for getopt to eat */ - line = xmalloc (strlen (value) + 10); + line = xmalloc (strlen (value) + 5); strcpy(line, "XXX "); strcpy(line + 4, value); @@ -502,7 +506,7 @@ do_module (db, mname, m_type, msg, callback_proc, where, else err += do_module (db, modargv[i], m_type, msg, callback_proc, where, shorten, local_specified, - run_module_prog, extra_arg); + run_module_prog, build_dirs, extra_arg); } goto do_module_return; } @@ -530,9 +534,7 @@ module `%s' is a request for a file in a module which is not a directory", */ char *dir; - /* XXX - XXX - MAJOR HACK - DO NOT SHIP - this needs to - be !pipeout, but we don't know that here yet */ - if (!run_module_prog) + if (!build_dirs) goto do_special; dir = where ? where : (mwhere ? mwhere : mname); @@ -643,7 +645,7 @@ module `%s' is a request for a file in a module which is not a directory", else err += do_module (db, spec_opt, m_type, msg, callback_proc, (char *) NULL, 0, local_specified, - run_module_prog, extra_arg); + run_module_prog, build_dirs, extra_arg); spec_opt = next_opt; } diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c index 0bf6d3c..7efd638 100644 --- a/contrib/cvs/src/parseinfo.c +++ b/contrib/cvs/src/parseinfo.c @@ -37,7 +37,7 @@ Parse_Info (infofile, repository, callproc, all) char *cp, *exp, *value, *srepos, bad; const char *regex_err; - if (CVSroot_original == NULL) + if (current_parsed_root == NULL) { /* XXX - should be error maybe? */ error (0, 0, "CVSROOT variable not set"); @@ -45,11 +45,11 @@ Parse_Info (infofile, repository, callproc, all) } /* find the info file and open it */ - infopath = xmalloc (strlen (CVSroot_directory) + infopath = xmalloc (strlen (current_parsed_root->directory) + strlen (infofile) + sizeof (CVSROOTADM) - + 10); - (void) sprintf (infopath, "%s/%s/%s", CVSroot_directory, + + 3); + (void) sprintf (infopath, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, infofile); fp_info = CVS_FOPEN (infopath, "r"); if (fp_info == NULL) @@ -204,7 +204,7 @@ 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 (CVSroot_directory might not be + CVSROOT is the $CVSROOT directory (current_parsed_root->directory might not be set yet). Returns 0 for success, negative value for failure. Call diff --git a/contrib/cvs/src/patch.c b/contrib/cvs/src/patch.c index 9aa26f3..5a20877 100644 --- a/contrib/cvs/src/patch.c +++ b/contrib/cvs/src/patch.c @@ -12,6 +12,7 @@ * release as either a date or a revision number. */ +#include #include "cvs.h" #include "getline.h" @@ -189,7 +190,7 @@ patch (argc, argv) options = xstrdup (""); #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { /* We're the client side. Fire up the remote server. */ start_server (); @@ -252,7 +253,7 @@ patch (argc, argv) db = open_module (); for (i = 0; i < argc; i++) err += do_module (db, argv[i], PATCH, "Patching", patch_proc, - (char *) NULL, 0, 0, 0, (char *) NULL); + (char *) NULL, 0, 0, 0, 0, (char *) NULL); close_module (db); free (options); patch_cleanup (); @@ -282,11 +283,11 @@ patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified, char *repository; char *where; - repository = xmalloc (strlen (CVSroot_directory) + strlen (argv[0]) - + (mfile == NULL ? 0 : strlen (mfile)) + 30); - (void) sprintf (repository, "%s/%s", CVSroot_directory, argv[0]); - where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile)) - + 10); + 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) + + 1); (void) strcpy (where, argv[0]); /* if mfile isn't null, we need to set up to do only part of the module */ @@ -307,7 +308,7 @@ patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified, } /* take care of the rest */ - path = xmalloc (strlen (repository) + strlen (mfile) + 5); + path = xmalloc (strlen (repository) + strlen (mfile) + 2); (void) sprintf (path, "%s/%s", repository, mfile); if (isdir (path)) { @@ -502,10 +503,15 @@ patch_fileproc (callerdat, finfo) } /* Create 3 empty files. I'm not really sure there is any advantage - to doing so now rather than just waiting until later. */ - tmpfile1 = cvs_temp_name (); - fp1 = CVS_FOPEN (tmpfile1, "w+"); - if (fp1 == NULL) + * to doing so now rather than just waiting until later. + * + * There is - cvs_temp_file opens the file so that it can guarantee that + * we have exclusive write access to the file. Unfortunately we spoil that + * by closing it and reopening it again. Of course any better solution + * requires that the RCS functions accept open file pointers rather than + * simple file names. + */ + if ((fp1 = cvs_temp_file (&tmpfile1)) == NULL) { error (0, errno, "cannot create temporary file %s", tmpfile1); ret = 1; @@ -514,9 +520,7 @@ patch_fileproc (callerdat, finfo) else if (fclose (fp1) < 0) error (0, errno, "warning: cannot close %s", tmpfile1); - tmpfile2 = cvs_temp_name (); - fp2 = CVS_FOPEN (tmpfile2, "w+"); - if (fp2 == NULL) + if ((fp2 = cvs_temp_file (&tmpfile2)) == NULL) { error (0, errno, "cannot create temporary file %s", tmpfile2); ret = 1; @@ -525,9 +529,7 @@ patch_fileproc (callerdat, finfo) else if (fclose (fp2) < 0) error (0, errno, "warning: cannot close %s", tmpfile2); - tmpfile3 = cvs_temp_name (); - fp3 = CVS_FOPEN (tmpfile3, "w+"); - if (fp3 == NULL) + if ((fp3 = cvs_temp_file (&tmpfile3)) == NULL) { error (0, errno, "cannot create temporary file %s", tmpfile3); ret = 1; @@ -580,7 +582,7 @@ patch_fileproc (callerdat, finfo) (void) utime (tmpfile2, &t); } - switch (diff_exec (tmpfile1, tmpfile2, 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); @@ -643,13 +645,14 @@ failed to read diff file header %s for %s: end of file", tmpfile3, rcs); goto out; } } - if (CVSroot_directory != NULL) + assert (current_parsed_root != NULL); + assert (current_parsed_root->directory != NULL); { - strippath = xmalloc (strlen (CVSroot_directory) + 10); - (void) sprintf (strippath, "%s/", CVSroot_directory); + strippath = xmalloc (strlen (current_parsed_root->directory) + 2); + (void) sprintf (strippath, "%s/", current_parsed_root->directory); } - else - strippath = xstrdup (REPOS_STRIP); + /*else + strippath = xstrdup (REPOS_STRIP); */ if (strncmp (rcs, strippath, strlen (strippath)) == 0) rcs += strlen (strippath); free (strippath); diff --git a/contrib/cvs/src/rcs.c b/contrib/cvs/src/rcs.c index b28572c..385eaf2 100644 --- a/contrib/cvs/src/rcs.c +++ b/contrib/cvs/src/rcs.c @@ -92,11 +92,6 @@ static void expand_keywords PROTO((RCSNode *, RCSVers *, const char *, size_t, char **, size_t *)); static void cmp_file_buffer PROTO((void *, const char *, size_t)); -enum rcs_delta_op {RCS_ANNOTATE, RCS_FETCH}; -static void RCS_deltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, char *, - enum rcs_delta_op, char **, size_t *, - char **, size_t *)); - /* Routines for reading, parsing and writing RCS files. */ static RCSVers *getdelta PROTO ((struct rcsbuffer *, char *, char **, char **)); @@ -2126,7 +2121,7 @@ RCS_getversion (rcs, tag, date, force_tag_match, simple_tag) * -- If tag is a branch tag, returns the branch number, not * the revision of the head of the branch. * If tag or revision is not valid or does not exist in file, - * exit with error. + * return NULL. */ char * RCS_tag2rev (rcs, tag) @@ -2205,9 +2200,8 @@ RCS_tag2rev (rcs, tag) if (rev) return rev; - error (1, 0, "tag `%s' does not exist", tag); - /* NOT REACHED -- error (1 ... ) does not return here */ - return 0; + /* Trust the caller to print warnings. */ + return NULL; } /* @@ -4147,7 +4141,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat) whether it should be considered an error for `dest' to exist at this point. If so, the unlink call should be removed and `symlink' should signal the error. -twp) */ - if (unlink (dest) < 0 && !existence_error (errno)) + if (CVS_UNLINK (dest) < 0 && !existence_error (errno)) error (1, errno, "cannot remove %s", dest); if (symlink (info->data, dest) < 0) error (1, errno, "cannot create symbolic link from %s to %s", @@ -4317,7 +4311,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat) /* Unlink `dest', just in case. It's okay if this provokes a ENOENT error. */ - if (unlink (dest) < 0 && existence_error (errno)) + if (CVS_UNLINK (dest) < 0 && existence_error (errno)) error (1, errno, "cannot remove %s", dest); if (mknod (dest, special_file, devnum) < 0) error (1, errno, "could not create special file %s", @@ -5260,7 +5254,7 @@ workfile); memset (commitpt->text, 0, sizeof (Deltatext)); bufsize = 0; - switch (diff_exec (workfile, tmpfile, diffopts, changefile)) + switch (diff_exec (workfile, tmpfile, NULL, NULL, diffopts, changefile)) { case 0: case 1: @@ -5308,7 +5302,7 @@ workfile); /* This file is not being inserted at the head, but on a side branch somewhere. Make a diff from the previous revision to the working file. */ - switch (diff_exec (tmpfile, workfile, diffopts, changefile)) + switch (diff_exec (tmpfile, workfile, NULL, NULL, diffopts, changefile)) { case 0: case 1: @@ -5688,7 +5682,7 @@ RCS_setbranch (rcs, rev) int RCS_lock (rcs, rev, lock_quiet) RCSNode *rcs; - const char *rev; + char *rev; int lock_quiet; { List *locks; @@ -5707,32 +5701,16 @@ RCS_lock (rcs, rev, lock_quiet) /* A revision number of NULL means lock the head or default branch. */ if (rev == NULL) xrev = RCS_head (rcs); - - /* If rev is a branch number, lock the latest revision on that - branch. I think that if the branch doesn't exist, it's - okay to return 0 -- that just means that the branch is new, - so we don't need to lock it anyway. -twp */ - else if (RCS_nodeisbranch (rcs, rev)) - { - xrev = RCS_getbranch (rcs, (char *) rev, 1); - if (xrev == NULL) - { - if (!lock_quiet) - error (0, 0, "%s: branch %s absent", rcs->path, rev); - return 1; - } - } - - if (xrev == NULL) - xrev = xstrdup (rev); + else + xrev = RCS_gettag (rcs, rev, 1, (int *) NULL); /* Make sure that the desired revision exists. Technically, we can update the locks list without even checking this, but RCS 5.7 did this. And it can't hurt. */ - if (findnode (rcs->versions, xrev) == NULL) + if (xrev == NULL || findnode (rcs->versions, xrev) == NULL) { if (!lock_quiet) - error (0, 0, "%s: revision %s absent", rcs->path, xrev); + error (0, 0, "%s: revision %s absent", rcs->path, rev); free (xrev); return 1; } @@ -5798,7 +5776,7 @@ RCS_lock (rcs, rev, lock_quiet) int RCS_unlock (rcs, rev, unlock_quiet) RCSNode *rcs; - const char *rev; + char *rev; int unlock_quiet; { Node *lock; @@ -5848,20 +5826,15 @@ RCS_unlock (rcs, rev, unlock_quiet) return 0; /* no lock found, ergo nothing to do */ xrev = xstrdup (lock->key); } - else if (RCS_nodeisbranch (rcs, rev)) + else { - /* If rev is a branch number, unlock the latest revision on that - branch. */ - xrev = RCS_getbranch (rcs, (char *) rev, 1); + xrev = RCS_gettag (rcs, rev, 1, (int *) NULL); if (xrev == NULL) { - error (0, 0, "%s: branch %s absent", rcs->path, rev); + error (0, 0, "%s: revision %s absent", rcs->path, rev); return 1; } } - else - /* REV is an exact revision number. */ - xrev = xstrdup (rev); lock = findnode (RCS_getlocks (rcs), xrev); if (lock == NULL) @@ -6383,7 +6356,7 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive) goto delrev_done; outfile = cvs_temp_name(); - status = diff_exec (beforefile, afterfile, "-an", outfile); + status = diff_exec (beforefile, afterfile, NULL, NULL, "-an", outfile); if (status == 2) { @@ -7022,7 +6995,7 @@ rcs_change_text (name, textbuf, textlen, diffbuf, difflen, retbuf, retlen) On error, give a fatal error. */ -static void +void RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen) RCSNode *rcs; FILE *fp; @@ -8381,138 +8354,6 @@ RCS_abandon (rcs) rcs->flags |= PARTIAL; } - -/* Annotate command. In rcs.c for historical reasons (from back when - what is now RCS_deltas was part of annotate_fileproc). */ - -/* Options from the command line. */ - -static int force_tag_match = 1; -static char *tag = NULL; -static char *date = NULL; - -static int annotate_fileproc PROTO ((void *callerdat, struct file_info *)); - -static int -annotate_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - FILE *fp = NULL; - struct rcsbuffer *rcsbufp = NULL; - struct rcsbuffer rcsbuf; - char *version; - - if (finfo->rcs == NULL) - return (1); - - if (finfo->rcs->flags & PARTIAL) - { - RCS_reparsercsfile (finfo->rcs, &fp, &rcsbuf); - rcsbufp = &rcsbuf; - } - - version = RCS_getversion (finfo->rcs, tag, date, force_tag_match, - (int *) NULL); - if (version == NULL) - return 0; - - /* Distinguish output for various files if we are processing - several files. */ - cvs_outerr ("Annotations for ", 0); - cvs_outerr (finfo->fullname, 0); - cvs_outerr ("\n***************\n", 0); - - RCS_deltas (finfo->rcs, fp, rcsbufp, version, RCS_ANNOTATE, NULL, - NULL, NULL, NULL); - free (version); - return 0; -} - -static const char *const annotate_usage[] = -{ - "Usage: %s %s [-lRf] [-r rev|-D date] [files...]\n", - "\t-l\tLocal directory only, no recursion.\n", - "\t-R\tProcess directories recursively.\n", - "\t-f\tUse head revision if tag/date not found.\n", - "\t-r rev\tAnnotate file as of specified revision/tag.\n", - "\t-D date\tAnnotate file as of specified date.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -/* Command to show the revision, date, and author where each line of a - file was modified. */ - -int -annotate (argc, argv) - int argc; - char **argv; -{ - int local = 0; - int c; - - if (argc == -1) - usage (annotate_usage); - - optind = 0; - while ((c = getopt (argc, argv, "+lr:D:fR")) != -1) - { - switch (c) - { - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case 'r': - tag = optarg; - break; - case 'D': - date = Make_Date (optarg); - break; - case 'f': - force_tag_match = 0; - break; - case '?': - default: - usage (annotate_usage); - break; - } - } - argc -= optind; - argv += optind; - -#ifdef CLIENT_SUPPORT - if (client_active) - { - start_server (); - ign_setup (); - - if (local) - send_arg ("-l"); - if (!force_tag_match) - send_arg ("-f"); - option_with_arg ("-r", tag); - if (date) - client_senddate (date); - send_files (argc, argv, local, 0, SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server ("annotate\012", 0); - return get_responses_and_close (); - } -#endif /* CLIENT_SUPPORT */ - - if (tag != NULL) - tag_check_valid (tag, argc, argv, local, 0, ""); - - return start_recursion (annotate_fileproc, (FILESDONEPROC) NULL, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, W_LOCAL, 0, 1, (char *)NULL, - 1); -} - /* * For a given file with full pathname PATH and revision number REV, * produce a file label suitable for passing to diff. The default @@ -8522,6 +8363,11 @@ annotate (argc, argv) * * The date and time used are the revision's last checkin date and time. * If REV is NULL, use the working copy's mtime instead. + * + * /dev/null is not statted but assumed to have been created on the Epoch. + * At least using the POSIX.2 definition of patch, this should cause creation + * of files on platforms such as Windoze where the null IO device isn't named + * /dev/null to be parsed by patch properly. */ char * make_file_label (path, rev, rcs) @@ -8529,37 +8375,45 @@ make_file_label (path, rev, rcs) char *rev; RCSNode *rcs; { - char datebuf[MAXDATELEN]; + char datebuf[MAXDATELEN + 1]; char *label; - char *file; - file = last_component (path); label = (char *) xmalloc (strlen (path) - + (rev == NULL ? 0 : strlen (rev)) - + 50); + + (rev == NULL ? 0 : strlen (rev) + 1) + + MAXDATELEN + + 2); if (rev) { - char *date; + char date[MAXDATELEN + 1]; + /* revs cannot be attached to /dev/null ... duh. */ + assert (strcmp(DEVNULL, path)); RCS_getrevtime (rcs, rev, datebuf, 0); - date = printable_date (datebuf); + (void) date_to_internet (date, datebuf); (void) sprintf (label, "-L%s\t%s\t%s", path, date, rev); - free (date); } else { struct stat sb; - struct tm *wm; + struct tm *wm = NULL; - if (CVS_STAT (file, &sb) < 0) - error (0, 1, "could not get info for `%s'", path); + if (strcmp(DEVNULL, path)) + { + 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); + } else { - wm = gmtime (&sb.st_mtime); - (void) sprintf (datebuf, "%04d/%02d/%02d %02d:%02d:%02d", - wm->tm_year + 1900, wm->tm_mon + 1, - wm->tm_mday, wm->tm_hour, - wm->tm_min, wm->tm_sec); + time_t t = 0; + wm = gmtime(&t); + } + + if (wm) + { + (void) tm_to_internet (datebuf, wm); (void) sprintf (label, "-L%s\t%s", path, datebuf); } } diff --git a/contrib/cvs/src/rcs.h b/contrib/cvs/src/rcs.h index 3466398..55eed95 100644 --- a/contrib/cvs/src/rcs.h +++ b/contrib/cvs/src/rcs.h @@ -179,6 +179,9 @@ typedef void (*RCSCHECKOUTPROC) PROTO ((void *, const char *, size_t)); struct rcsbuffer; #endif +/* What RCS_deltas is supposed to do. */ +enum rcs_delta_op {RCS_ANNOTATE, RCS_FETCH}; + /* * exported interfaces */ @@ -223,8 +226,8 @@ int RCS_cmp_file PROTO ((RCSNode *, char *, 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 *, const char *, int)); -int RCS_unlock PROTO ((RCSNode *, const char *, int)); +int RCS_lock PROTO ((RCSNode *, char *, int)); +int RCS_unlock PROTO ((RCSNode *, char *, int)); int RCS_delete_revs PROTO ((RCSNode *, char *, char *, int)); void RCS_addaccess PROTO ((RCSNode *, char *)); void RCS_delaccess PROTO ((RCSNode *, char *)); @@ -234,6 +237,9 @@ 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 *, + enum rcs_delta_op, char **, size_t *, + char **, size_t *)); char *make_file_label PROTO ((char *, char *, RCSNode *)); extern int preserve_perms; diff --git a/contrib/cvs/src/rcscmds.c b/contrib/cvs/src/rcscmds.c index ab94e40..43be168 100644 --- a/contrib/cvs/src/rcscmds.c +++ b/contrib/cvs/src/rcscmds.c @@ -530,9 +530,11 @@ RCS file: ", 0); message on stderr. */ int -diff_exec (file1, file2, options, out) +diff_exec (file1, file2, label1, label2, options, out) char *file1; char *file2; + char *label1; + char *label2; char *options; char *out; { @@ -575,6 +577,10 @@ diff_exec (file1, file2, options, out) /* The first word in this string is used only for error reporting. */ sprintf (args, "diff %s", options); call_diff_setup (args); + if (label1) + call_diff_arg (label1); + if (label2) + call_diff_arg (label2); call_diff_arg (file1); call_diff_arg (file2); free (args); diff --git a/contrib/cvs/src/recurse.c b/contrib/cvs/src/recurse.c index 1cb2fbb..2235193 100644 --- a/contrib/cvs/src/recurse.c +++ b/contrib/cvs/src/recurse.c @@ -157,10 +157,10 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat, #ifdef CLIENT_SUPPORT if (!just_subdirs && CVSroot_cmdline == NULL - && client_active) + && current_parsed_root->isremote) { char *root = Name_Root (NULL, update_dir); - if (root && strcmp (root, current_root) != 0) + if (root && strcmp (root, current_parsed_root->original) != 0) /* We're skipping this directory because it is for a different root. Therefore, we just want to do the subdirectories only. Processing files would @@ -204,7 +204,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat, program_name); } #ifdef CLIENT_SUPPORT - else if (client_active && server_started) + else if (current_parsed_root->isremote && server_started) { /* In the the case "cvs update foo bar baz", a call to send_file_names in update.c will have sent the @@ -290,7 +290,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat, { if ((which & W_LOCAL) && isdir (CVSADM) #ifdef CLIENT_SUPPORT - && !client_active + && !current_parsed_root->isremote #endif ) { @@ -363,8 +363,8 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat, /* FIXME (njc): in the multiroot case, we don't want to send argument commands for those top-level directories which do not contain any subdirectories which have files checked out - from current_root. If we do, and two repositories have a - module with the same name, nasty things could happen. + from current_parsed_root->original. If we do, and two repositories + have a module with the same name, nasty things could happen. This is hard. Perhaps we should send the Argument commands later in this procedure, after we've had a chance to notice @@ -440,7 +440,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat, "Directory xxx" command, which forces the server to descend and serve the files there. client.c (send_file_names) has also been modified to send only those arguments which are - appropriate to current_root. + appropriate to current_parsed_root->original. */ @@ -599,8 +599,9 @@ do_recursion (frame) } - process_this_directory = (strcmp (current_root, this_root) == 0); - + process_this_directory = + (strcmp (current_parsed_root->original, this_root) == 0); + free (this_root); } } @@ -710,7 +711,7 @@ do_recursion (frame) place (server_notify). For local, we can't do them here--we don't have writelocks in place, and there is no way to get writelocks here. */ - if (client_active) + if (current_parsed_root->isremote) notify_check (repository, update_dir); #endif /* CLIENT_SUPPORT */ @@ -1024,7 +1025,8 @@ but CVS uses %s for its own purposes; skipping %s directory", } - process_this_directory = (strcmp (current_root, this_root) == 0); + process_this_directory = (strcmp (current_parsed_root->original, this_root) == 0); + free (this_root); } } diff --git a/contrib/cvs/src/release.c b/contrib/cvs/src/release.c index 06d582f..f87583d 100644 --- a/contrib/cvs/src/release.c +++ b/contrib/cvs/src/release.c @@ -118,14 +118,14 @@ release (argc, argv) */ /* Construct the update command. */ update_cmd = xmalloc (strlen (program_path) - + strlen (CVSroot_original) + + strlen (current_parsed_root->original) + 20); sprintf (update_cmd, "%s -n -q -d %s update", - program_path, CVSroot_original); + program_path, current_parsed_root->original); #ifdef CLIENT_SUPPORT /* Start the server; we'll close it after looping. */ - if (client_active) + if (current_parsed_root->isremote) { start_server (); ign_setup (); @@ -226,7 +226,7 @@ release (argc, argv) if (1 #ifdef CLIENT_SUPPORT - && !(client_active + && !(current_parsed_root->isremote && (!supported_request ("noop") || !supported_request ("Notify"))) #endif @@ -242,7 +242,7 @@ release (argc, argv) } #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { send_to_server ("Argument ", 0); send_to_server (thisarg, 0); @@ -271,7 +271,7 @@ release (argc, argv) } #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) err += get_server_responses (); #endif /* CLIENT_SUPPORT */ } @@ -281,7 +281,7 @@ release (argc, argv) free_cwd (&cwd); #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { /* Unfortunately, client.c doesn't offer a way to close the connection without waiting for responses. The extra diff --git a/contrib/cvs/src/remove.c b/contrib/cvs/src/remove.c index f0055d9..63b61d3 100644 --- a/contrib/cvs/src/remove.c +++ b/contrib/cvs/src/remove.c @@ -77,7 +77,7 @@ cvsremove (argc, argv) wrap_setup (); #ifdef CLIENT_SUPPORT - if (client_active) { + if (current_parsed_root->isremote) { /* Call expand_wild so that the local removal of files will work. It's ok to do it always because we have to send the file names expanded anyway. */ @@ -115,7 +115,7 @@ cvsremove (argc, argv) argc, argv, local, W_LOCAL, 0, 1, (char *) NULL, 1); - if (removed_files) + if (removed_files && !really_quiet) error (0, 0, "use '%s commit' to remove %s permanently", program_name, (removed_files == 1) ? "this file" : "these files"); diff --git a/contrib/cvs/src/repos.c b/contrib/cvs/src/repos.c index bc2b4be..8cdcb45 100644 --- a/contrib/cvs/src/repos.c +++ b/contrib/cvs/src/repos.c @@ -110,7 +110,7 @@ Name_Repository (dir, update_dir) { char *newrepos; - if (CVSroot_original == NULL) + if (current_parsed_root == NULL) { error (0, 0, "in directory %s:", xupdate_dir); error (0, 0, "must set the CVSROOT environment variable\n"); @@ -123,8 +123,8 @@ Name_Repository (dir, update_dir) error (0, 0, "`..'-relative repositories are not supported."); error (1, 0, "illegal source repository"); } - newrepos = xmalloc (strlen (CVSroot_directory) + strlen (repos) + 10); - (void) sprintf (newrepos, "%s/%s", CVSroot_directory, repos); + newrepos = xmalloc (strlen (current_parsed_root->directory) + strlen (repos) + 2); + (void) sprintf (newrepos, "%s/%s", current_parsed_root->directory, repos); free (repos); repos = newrepos; } @@ -147,10 +147,10 @@ Short_Repository (repository) /* If repository matches CVSroot at the beginning, strip off CVSroot */ /* And skip leading '/' in rep, in case CVSroot ended with '/'. */ - if (strncmp (CVSroot_directory, repository, - strlen (CVSroot_directory)) == 0) + if (strncmp (current_parsed_root->directory, repository, + strlen (current_parsed_root->directory)) == 0) { - char *rep = repository + strlen (CVSroot_directory); + char *rep = repository + strlen (current_parsed_root->directory); return (*rep == '/') ? rep+1 : rep; } else diff --git a/contrib/cvs/src/root.c b/contrib/cvs/src/root.c index 81859c8..2d1261d 100644 --- a/contrib/cvs/src/root.c +++ b/contrib/cvs/src/root.c @@ -12,11 +12,11 @@ #include "cvs.h" #include "getline.h" -/* Printable names for things in the CVSroot_method enum variable. +/* 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[] = { - "local", "server (rsh)", "pserver", "kserver", "gserver", "ext", "fork" + "undefined", "local", "server (rsh)", "pserver", "kserver", "gserver", "ext", "fork" }; #ifndef DEBUG @@ -265,12 +265,16 @@ error 0 Server configuration missing --allow-root in inetd.conf\n"); return 0; } + + /* This global variable holds the global -d option. It is NULL if -d was not used, which means that we must get the CVSroot information from the CVSROOT environment variable or from a CVS/Root file. */ char *CVSroot_cmdline; + + /* Parse a CVSROOT variable into its constituent parts -- method, * username, hostname, directory. The prototypical CVSROOT variable * looks like: @@ -280,50 +284,102 @@ char *CVSroot_cmdline; * Some methods may omit fields; local, for example, doesn't need user * and host. * - * Returns zero on success, non-zero on failure. */ + * Returns pointer to new cvsroot_t on success, NULL on failure. */ -char *CVSroot_original = NULL; /* the CVSroot that was passed in */ -int client_active; /* nonzero if we are doing remote access */ -CVSmethod CVSroot_method; /* one of the enum values defined in cvs.h */ -char *CVSroot_username; /* the username or NULL if method == local */ -char *CVSroot_hostname; /* the hostname or NULL if method == local */ -char *CVSroot_directory; /* the directory name */ +cvsroot_t *current_parsed_root = NULL; -int -parse_cvsroot (CVSroot) - char *CVSroot; + + +/* allocate and initialize a cvsroot_t + * + * We must initialize the strings to NULL so we know later what we should + * free + * + * Some of the other zeroes remain meaningful as, "never set, use default", + * or the like + */ +static cvsroot_t * +new_cvsroot_t () { - static int cvsroot_parsed = 0; - char *cvsroot_copy, *cvsroot_save, *p; - int check_hostname; + cvsroot_t *newroot; + + /* gotta store it somewhere */ + newroot = xmalloc(sizeof(cvsroot_t)); + + newroot->original = NULL; + newroot->method = null_method; + newroot->username = NULL; + newroot->password = NULL; + newroot->hostname = NULL; + newroot->port = 0; + newroot->directory = NULL; +#ifdef CLIENT_SUPPORT + newroot->isremote = 0; +#endif /* CLIENT_SUPPORT */ - /* Don't go through the trouble twice. */ - if (cvsroot_parsed) + return newroot; +} + + + +/* Dispose of a cvsroot_t and its component parts */ +void +free_cvsroot_t (root) + cvsroot_t *root; +{ + if (root->original != NULL) + free (root->original); + if (root->username != NULL) + free (root->username); + if (root->password != NULL) { - error (0, 0, "WARNING (parse_cvsroot): someone called me twice!\n"); - return 0; + /* I like to be paranoid */ + memset (root->password, 0, strlen (root->password)); + free (root->password); } + if (root->hostname != NULL) + free (root->hostname); + if (root->directory != NULL) + free (root->directory); + free (root); +} + - if (CVSroot_original != NULL) - free (CVSroot_original); - if (CVSroot_directory != NULL) - free (CVSroot_directory); - if (CVSroot_username != NULL) - free (CVSroot_username); - if (CVSroot_hostname != NULL) - free (CVSroot_hostname); - CVSroot_original = xstrdup (CVSroot); - cvsroot_save = cvsroot_copy = xstrdup (CVSroot); +/* + * parse a CVSROOT string to allocate and return a new cvsroot_t structure + */ +cvsroot_t * +parse_cvsroot (root_in) + char *root_in; +{ + cvsroot_t *newroot; /* the new root to be returned */ + char *cvsroot_save; /* what we allocated so we can dispose + * it when finished */ + char *firstslash; /* save where the path spec starts + * while we parse + * [[user][:password]@]host[:[port]] + */ + char *cvsroot_copy, *p, *q; /* temporary pointers for parsing */ + int check_hostname, no_port, no_password; + + /* allocate some space */ + newroot = new_cvsroot_t(); + + /* save the original string */ + newroot->original = xstrdup (root_in); + + /* and another copy we can munge while parsing */ + cvsroot_save = cvsroot_copy = xstrdup (root_in); if (*cvsroot_copy == ':') { char *method = ++cvsroot_copy; /* Access method specified, as in - * "cvs -d :pserver:user@host:/path", + * "cvs -d :(gserver|kserver|pserver):[[user][:password]@]host[:[port]]/path", + * "cvs -d [:(ext|server):][[user]@]host[:]/path", * "cvs -d :local:e:\path", - * "cvs -d :kserver:user@host:/path", or * "cvs -d :fork:/path". * We need to get past that part of CVSroot before parsing the * rest of it. @@ -331,9 +387,9 @@ parse_cvsroot (CVSroot) if (! (p = strchr (method, ':'))) { - error (0, 0, "bad CVSroot: %s", CVSroot); + error (0, 0, "bad CVSroot: %s", root_in); free (cvsroot_save); - return 1; + goto error_exit; } *p = '\0'; cvsroot_copy = ++p; @@ -341,24 +397,24 @@ parse_cvsroot (CVSroot) /* Now we have an access method -- see if it's valid. */ if (strcmp (method, "local") == 0) - CVSroot_method = local_method; + newroot->method = local_method; else if (strcmp (method, "pserver") == 0) - CVSroot_method = pserver_method; + newroot->method = pserver_method; else if (strcmp (method, "kserver") == 0) - CVSroot_method = kserver_method; + newroot->method = kserver_method; else if (strcmp (method, "gserver") == 0) - CVSroot_method = gserver_method; + newroot->method = gserver_method; else if (strcmp (method, "server") == 0) - CVSroot_method = server_method; + newroot->method = server_method; else if (strcmp (method, "ext") == 0) - CVSroot_method = ext_method; + newroot->method = ext_method; else if (strcmp (method, "fork") == 0) - CVSroot_method = fork_method; + newroot->method = fork_method; else { - error (0, 0, "unknown method in CVSroot: %s", CVSroot); + error (0, 0, "unknown method in CVSroot: %s", root_in); free (cvsroot_save); - return 1; + goto error_exit; } } else @@ -367,171 +423,328 @@ parse_cvsroot (CVSroot) SERVER_METHOD/EXT_METHOD if the string contains a colon or LOCAL_METHOD otherwise. */ - CVSroot_method = ((strchr (cvsroot_copy, ':')) -#ifdef RSH_NOT_TRANSPARENT + newroot->method = ((*cvsroot_copy != '/' && strchr (cvsroot_copy, '/')) +/*#ifdef RSH_NOT_TRANSPARENT ? server_method -#else +#else*/ ? ext_method -#endif +/*#endif*/ : local_method); } - client_active = (CVSroot_method != local_method); - - /* Check for username/hostname if we're not LOCAL_METHOD. */ +#ifdef CLIENT_SUPPORT + newroot->isremote = (newroot->method != local_method); +#endif /* CLIENT_SUPPORT */ - CVSroot_username = NULL; - CVSroot_hostname = NULL; - if ((CVSroot_method != local_method) - && (CVSroot_method != fork_method)) + if ((newroot->method != local_method) + && (newroot->method != fork_method)) { - /* Check to see if there is a username in the string. */ + /* split the string into [[user][:password]@]host[:[port]] & /path + * + * this will allow some characters such as '@' & ':' to remain unquoted + * in the path portion of the spec + */ + if ((p = strchr (cvsroot_copy, '/')) == NULL) + { + error (0, 0, "CVSROOT (\"%s\")", root_in); + error (0, 0, "requires a path spec"); + error (0, 0, ":(gserver|kserver|pserver):[[user][:password]@]host[:[port]]/path"); + error (0, 0, "[:(ext|server):][[user]@]host[:]/path"); + free (cvsroot_save); + goto error_exit; + } + firstslash = p; /* == NULL if '/' not in string */ + *p = '\0'; + /* Check to see if there is a username[:password] in the string. */ if ((p = strchr (cvsroot_copy, '@')) != NULL) { *p = '\0'; - CVSroot_username = xstrdup (cvsroot_copy); + /* check for a password */ + if ((q = strchr (cvsroot_copy, ':')) != NULL) + { + *q = '\0'; + newroot->password = xstrdup (++q); + /* Don't check for *newroot->password == '\0' since + * a user could conceivably wish to specify a blank password + * (newroot->password == NULL means to use the + * password from .cvspass) + */ + } + + /* copy the username */ + if (*cvsroot_copy != '\0') + /* a blank username is impossible, so leave it NULL in that + * case so we know to use the default username + */ + newroot->username = xstrdup (cvsroot_copy); + cvsroot_copy = ++p; - if (*CVSroot_username == '\0') - CVSroot_username = NULL; } + /* now deal with host[:[port]] */ + + /* the port */ if ((p = strchr (cvsroot_copy, ':')) != NULL) { - *p = '\0'; - CVSroot_hostname = xstrdup (cvsroot_copy); - cvsroot_copy = ++p; - - if (*CVSroot_hostname == '\0') - CVSroot_hostname = NULL; + *p++ = '\0'; + if (strlen(p)) + { + q = p; + if (*q == '-') q++; + while (*q) + { + if (!isdigit(*q++)) + { + error(0, 0, "CVSROOT (\"%s\")", root_in); + error(0, 0, "may only specify a positive, non-zero, integer port (not \"%s\").", + p); + error(0, 0, "perhaps you entered a relative pathname?"); + free (cvsroot_save); + goto error_exit; + } + } + if ((newroot->port = atoi (p)) <= 0) + { + error (0, 0, "CVSROOT (\"%s\")", root_in); + error(0, 0, "may only specify a positive, non-zero, integer port (not \"%s\").", + p); + error(0, 0, "perhaps you entered a relative pathname?"); + free (cvsroot_save); + goto error_exit; + } + } } + + /* copy host */ + if (*cvsroot_copy != '\0') + /* blank hostnames are invalid, but for now leave the field NULL + * and catch the error during the sanity checks later + */ + newroot->hostname = xstrdup (cvsroot_copy); + + /* restore the '/' */ + cvsroot_copy = firstslash; + *cvsroot_copy = '/'; } - CVSroot_directory = xstrdup(cvsroot_copy); + /* parse the path for all methods */ + newroot->directory = xstrdup(cvsroot_copy); free (cvsroot_save); + /* + * Do various sanity checks. + */ + #if ! defined (CLIENT_SUPPORT) && ! defined (DEBUG) - if (CVSroot_method != local_method) + if (newroot->method != local_method) { - error (0, 0, "Your CVSROOT is set for a remote access method"); - error (0, 0, "but your CVS executable doesn't support it"); - error (0, 0, "(%s)", CVSroot); - return 1; + error (0, 0, "CVSROOT \"%s\"", root_in); + error (0, 0, "is set for a remote access method but your"); + error (0, 0, "CVS executable doesn't support it"); + goto error_exit; } #endif - - /* Do various sanity checks. */ - if (CVSroot_username && ! CVSroot_hostname) +#if ! defined (SERVER_SUPPORT) && ! defined (DEBUG) + if (newroot->method == fork_method) + { + error (0, 0, "CVSROOT \"%s\"", root_in); + error (0, 0, "is set to use the :fork: access method but your"); + error (0, 0, "CVS executable doesn't support it"); + goto error_exit; + } +#endif + + if (newroot->username && ! newroot->hostname) { - error (0, 0, "missing hostname in CVSROOT: %s", CVSroot); - return 1; + error (0, 0, "missing hostname in CVSROOT: \"%s\"", root_in); + goto error_exit; } check_hostname = 0; - switch (CVSroot_method) + no_password = 0; + no_port = 0; + switch (newroot->method) { case local_method: - if (CVSroot_username || CVSroot_hostname) + if (newroot->username || newroot->hostname) { error (0, 0, "can't specify hostname and username in CVSROOT"); + error (0, 0, "(\"%s\")", root_in); error (0, 0, "when using local access method"); - error (0, 0, "(%s)", CVSroot); - return 1; + goto error_exit; } /* 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), so there would seem to be little risk in making this a fatal error. */ - if (!isabsolute (CVSroot_directory)) - error (1, 0, "CVSROOT %s must be an absolute pathname", - CVSroot_directory); + if (!isabsolute (newroot->directory)) + { + error (0, 0, "CVSROOT \"%s\" must be an absolute pathname", + newroot->directory); + goto error_exit; + } + no_port = 1; + no_password = 1; break; case fork_method: /* We want :fork: to behave the same as other remote access methods. Therefore, don't check to see that the repository name is absolute -- let the server do it. */ - if (CVSroot_username || CVSroot_hostname) + if (newroot->username || newroot->hostname) { error (0, 0, "can't specify hostname and username in CVSROOT"); + error (0, 0, "(\"%s\")", root_in); error (0, 0, "when using fork access method"); - error (0, 0, "(%s)", CVSroot); - return 1; + goto error_exit; + } + if (!isabsolute (newroot->directory)) + { + error (0, 0, "CVSROOT \"%s\" must be an absolute pathname", + newroot->directory); + goto error_exit; } + no_port = 1; + no_password = 1; break; case kserver_method: #ifndef HAVE_KERBEROS - error (0, 0, "Your CVSROOT is set for a kerberos access method"); - error (0, 0, "but your CVS executable doesn't support it"); - error (0, 0, "(%s)", CVSroot); - return 1; + error (0, 0, "CVSROOT \"%s\"", root_in); + error (0, 0, "is set for a kerberos access method but your"); + error (0, 0, "CVS executable doesn't support it"); + goto error_exit; #else check_hostname = 1; break; #endif case gserver_method: #ifndef HAVE_GSSAPI - error (0, 0, "Your CVSROOT is set for a GSSAPI access method"); - error (0, 0, "but your CVS executable doesn't support it"); - error (0, 0, "(%s)", CVSroot); - return 1; + error (0, 0, "CVSROOT \"%s\"", root_in); + error (0, 0, "is set for a GSSAPI access method but your"); + error (0, 0, "CVS executable doesn't support it"); + goto error_exit; #else check_hostname = 1; break; #endif case server_method: case ext_method: + no_port = 1; + no_password = 1; + check_hostname = 1; + break; case pserver_method: check_hostname = 1; break; } - if (check_hostname) + if (no_password && newroot->password) + { + error (0, 0, "CVSROOT password specification is only valid for"); + error (0, 0, "pserver connection method."); + goto error_exit; + } + + if (check_hostname && !newroot->hostname) { - if (! CVSroot_hostname) + error (0, 0, "didn't specify hostname in CVSROOT: %s", root_in); + goto error_exit; + } + + if (no_port && newroot->port) { - error (0, 0, "didn't specify hostname in CVSROOT: %s", CVSroot); - return 1; + error (0, 0, "CVSROOT port specification is only valid for gserver, kserver,"); + error (0, 0, "and pserver connection methods."); + goto error_exit; } - } - if (*CVSroot_directory == '\0') + if (*newroot->directory == '\0') { - error (0, 0, "missing directory in CVSROOT: %s", CVSroot); - return 1; + error (0, 0, "missing directory in CVSROOT: %s", root_in); + goto error_exit; } /* Hooray! We finally parsed it! */ - return 0; + return newroot; + +error_exit: + free_cvsroot_t (newroot); + return NULL; } -/* Set up the global CVSroot* variables as if we're using the local - repository DIR. */ -void -set_local_cvsroot (dir) +#ifdef AUTH_CLIENT_SUPPORT +/* Use root->username, root->hostname, root->port, and root->directory + * to create a normalized CVSROOT fit for the .cvspass file + * + * username defaults to the result of getcaller() + * port defaults to the result of get_cvs_port_number() + * + * FIXME - we could cache the canonicalized version of a root inside the + * cvsroot_t, but we'd have to un'const the input here and stop expecting the + * caller to be responsible for our return value + */ +char * +normalize_cvsroot (root) + const cvsroot_t *root; +{ + char *cvsroot_canonical; + char *p, *hostname, *username; + char port_s[64]; + + /* get the appropriate port string */ + sprintf (port_s, "%d", get_cvs_port_number (root)); + + /* use a lower case hostname since we know hostnames are case insensitive */ + /* Some logic says we should be tacking our domain name on too if it isn't + * there already, but for now this works. Reverse->Forward lookups are + * almost certainly too much since that would make CVS immune to some of + * the DNS trickery that makes life easier for sysadmins when they want to + * move a repository or the like + */ + p = hostname = xstrdup(root->hostname); + while (*p) + { + *p = tolower(*p); + p++; + } + + /* get the username string */ + username = root->username ? root->username : getcaller(); + cvsroot_canonical = xmalloc ( strlen(username) + + strlen(hostname) + strlen(port_s) + + strlen(root->directory) + 12); + sprintf (cvsroot_canonical, ":pserver:%s@%s:%s%s", + username, hostname, port_s, root->directory); + + free (hostname); + return cvsroot_canonical; +} +#endif /* AUTH_CLIENT_SUPPORT */ + + + +/* allocate and return a cvsroot_t structure set up as if we're using the local + * repository DIR. */ +cvsroot_t * +local_cvsroot (dir) char *dir; { - if (CVSroot_original != NULL) - free (CVSroot_original); - CVSroot_original = xstrdup(dir); - CVSroot_method = local_method; - if (CVSroot_directory != NULL) - free (CVSroot_directory); - CVSroot_directory = xstrdup(dir); - if (CVSroot_username != NULL) - free (CVSroot_username); - CVSroot_username = NULL; - if (CVSroot_hostname != NULL) - free (CVSroot_hostname); - CVSroot_hostname = NULL; - client_active = 0; + cvsroot_t *newroot = new_cvsroot_t(); + + newroot->original = xstrdup(dir); + newroot->method = local_method; + newroot->directory = xstrdup(dir); + + return newroot; } + #ifdef DEBUG /* This is for testing the parsing function. Use @@ -541,7 +754,6 @@ set_local_cvsroot (dir) #include -char *CVSroot; char *program_name = "testing"; char *command_name = "parse_cvsroot"; /* XXX is this used??? */ @@ -555,13 +767,6 @@ error_exit PROTO ((void)) exit (1); } -char * -xstrdup (str) - const char *str; -{ - return strdup (str); -} - int isabsolute (dir) const char *dir; @@ -582,18 +787,18 @@ main (argc, argv) exit (2); } - if (parse_cvsroot (argv[1])) + if ((current_parsed_root = parse_cvsroot (argv[1])) == NULL) { fprintf (stderr, "%s: Parsing failed.\n", program_name); exit (1); } printf ("CVSroot: %s\n", argv[1]); - printf ("CVSroot_method: %s\n", method_names[CVSroot_method]); - printf ("CVSroot_username: %s\n", - CVSroot_username ? CVSroot_username : "NULL"); - printf ("CVSroot_hostname: %s\n", - CVSroot_hostname ? CVSroot_hostname : "NULL"); - printf ("CVSroot_directory: %s\n", CVSroot_directory); + printf ("current_parsed_root->method: %s\n", method_names[current_parsed_root->method]); + printf ("current_parsed_root->username: %s\n", + current_parsed_root->username ? current_parsed_root->username : "NULL"); + printf ("current_parsed_root->hostname: %s\n", + current_parsed_root->hostname ? current_parsed_root->hostname : "NULL"); + printf ("current_parsed_root->directory: %s\n", current_parsed_root->directory); exit (0); /* NOTREACHED */ diff --git a/contrib/cvs/src/run.c b/contrib/cvs/src/run.c index d382cef..2d020eb 100644 --- a/contrib/cvs/src/run.c +++ b/contrib/cvs/src/run.c @@ -324,9 +324,19 @@ run_exec (stin, stout, sterr, flags) out: if (sterr) (void) close (sherr); + else + /* ensure things are received by the parent in the correct order + * relative to the protocol pipe + */ + cvs_flusherr(); out2: if (stout) (void) close (shout); + else + /* ensure things are received by the parent in the correct order + * relative to the protocol pipe + */ + cvs_flushout(); out1: if (stin) (void) close (shin); @@ -444,7 +454,7 @@ void close_on_exec (fd) int fd; { -#if defined (FD_CLOEXEC) && defined (F_SETFD) +#ifdef F_SETFD if (fcntl (fd, F_SETFD, 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 84e67cc..727e33a 100755 --- a/contrib/cvs/src/sanity.sh +++ b/contrib/cvs/src/sanity.sh @@ -18,10 +18,18 @@ # # Original Author: K. Richard Pixley -# usage: sanity.sh [-r] @var{cvs-to-test} @var{tests-to-run} -# -r means to test remote instead of local cvs. -# @var{tests-to-run} are the names of the tests to run; if omitted run all -# tests. +# usage: +exit_usage () +{ + echo "Usage: `basename $0` [-kr] [-f FROM-TEST] CVS-TO-TEST [TESTS-TO-RUN...]" 1>&2 + 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. @@ -37,55 +45,46 @@ unset CVSREAD LC_ALL=C export LC_ALL -# 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: -# 1. Use /tmp/cvs-test$$. One disadvantage is that the old -# cvs-test* directories would pile up, because they wouldn't -# necessarily get removed. -# 2. Have everyone/everything running the testsuite set -# TESTDIR to some appropriate directory. -# 3. Have the default value of TESTDIR be some variation of -# `pwd`/cvs-sanity. The biggest problem here is that we have -# been fairly careful to test that CVS prints in messages the -# actual pathnames that we pass to it, rather than a different -# pathname for the same directory, as may come out of `pwd`. -# 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` -: ${TESTDIR=$tmp/cvs-sanity} - -# "debugger" -#set -x - -echo 'This test should produce no other output than this line, and a final "OK".' -if test x"$1" = x"-r"; then - shift - remote=yes -else - remote=no -fi -# The --keep option will eventually cause all the tests to leave around the -# contents of the /tmp directory; right now only some implement it. Not -# useful if you are running more than one test. -# FIXME: need some real option parsing so this doesn't depend on the order -# in which they are specified. -if test x"$1" = x"--keep"; then - shift - keep=yes -else - keep=no -fi +# +# read our options +# +unset fromtest +keep=false +remote=false +while getopts f:kr option ; do + case "$option" in + f) + fromtest="$OPTARG" + ;; + 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). + keep=: + ;; + r) + remote=: + ;; + \?) + exit_usage + ;; + esac +done + +# boot the arguments we used above +while test $OPTIND -gt 1 ; do + shift + OPTIND=`expr $OPTIND - 1` +done # Use full path for CVS executable, so that CVS_SERVER gets set properly # for remote. case $1 in "") - echo "Usage: `basename $0` [-r] [--keep] CVS-TO-TEST [TESTS-TO-RUN...]" 1>&2 - exit 1 + exit_usage ;; /*) testcvs=$1 @@ -94,9 +93,19 @@ case $1 in testcvs=`pwd`/$1 ;; esac - shift + + +### +### GUTS +### + +# "debugger" +#set -x + +echo 'This test should produce no other output than this line, and a final "OK".' + # 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 # just spuriously match a few things; if the name contains other regexp @@ -108,17 +117,22 @@ PROG=`basename ${testcvs}` # not allowed in usernames. Other than that I'm not sure. username="[-a-zA-Z0-9][-a-zA-Z0-9]*" author="[-a-zA-Z0-9][-a-zA-Z0-9]*" +hostname="[-_.a-zA-Z0-9]*" # Regexp to match the name of a temporary file (from cvs_temp_name). # This appears in certain diff output. tempname="[-a-zA-Z0-9/.%_]*" +# Regexp to match a date in RFC822 format (as amended by RFC1123). +RFCDATE="[a-zA-Z0-9 ][a-zA-Z0-9 ]* [0-9:][0-9:]* -0000" +RFCDATE_EPOCH="1 Jan 1970 00:00:00 -0000" + # On cygwin32, we may not have /bin/sh. -if [ -r /bin/sh ]; then +if test -r /bin/sh; then TESTSHELL="/bin/sh" else TESTSHELL=`type -p sh 2>/dev/null` - if [ ! -r "$TESTSHELL" ]; then + if test ! -r "$TESTSHELL"; then TESTSHELL="/bin/sh" fi fi @@ -141,13 +155,48 @@ if test -f check.log; then mv check.log check.plog fi +# 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: +# 1. Use /tmp/cvs-test$$. One disadvantage is that the old +# cvs-test* directories would pile up, because they wouldn't +# necessarily get removed. +# 2. Have everyone/everything running the testsuite set +# TESTDIR to some appropriate directory. +# 3. Have the default value of TESTDIR be some variation of +# `pwd`/cvs-sanity. The biggest problem here is that we have +# been fairly careful to test that CVS prints in messages the +# actual pathnames that we pass to it, rather than a different +# pathname for the same directory, as may come out of `pwd`. +# 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` + +# Now: +# 1) Set TESTDIR if it's not set already +# 2) Remove any old test remnants +# 3) Create $TESTDIR +# 4) Normalize TESTDIR with `cd && (/bin/pwd || pwd)` +# (This will match CVS output later) +: ${TESTDIR=$tmp/cvs-sanity} # clean any old remnants (we need the chmod because some tests make # directories read-only) if test -d ${TESTDIR}; then chmod -R a+wx ${TESTDIR} rm -rf ${TESTDIR} fi -mkdir ${TESTDIR} +# These exits are important. The first time I tried this, if the `mkdir && cd` +# failed then the build directory would get blown away. Some people probably +# wouldn't appreciate that. +mkdir ${TESTDIR} || exit 1 +cd ${TESTDIR} || exit 1 +TESTDIR=`(/bin/pwd || pwd) 2>/dev/null` +# Ensure $TESTDIR is absolute +if test -z "${TESTDIR}" || echo "${TESTDIR}" |grep '^[^/]'; then + echo "Unable to resolve TESTDIR to an absolute directory." >&2 + exit 1 +fi cd ${TESTDIR} # Make sure various tools work the way we expect, or try to find @@ -159,17 +208,19 @@ cd ${TESTDIR} find_tool () { - GLOCS="`echo $PATH | sed 's/:/ /g'` /usr/local/bin /usr/contrib/bin /usr/gnu/bin /local/bin /local/gnu/bin /gun/bin" + GLOCS="`echo $PATH | sed 's/:/ /g'` /usr/local/bin /usr/contrib/bin /usr/gnu/bin /local/bin /local/gnu/bin /gnu/bin" TOOL="" for path in $GLOCS ; do if test -x $path/g$1 ; then - if test "X`$path/g$1 --version`" != "X--version" ; then + RES="`$path/g$1 --version /dev/null`" + if test "X$RES" != "X--version" && test "X$RES" != "X" ; then TOOL=$path/g$1 break fi fi if test -x $path/$1 ; then - if test "X`$path/$1 --version`" != "X--version" ; then + RES="`$path/$1 --version /dev/null`" + if test "X$RES" != "X--version" && test "X$RES" != "X" ; then TOOL=$path/$1 break fi @@ -178,30 +229,41 @@ find_tool () if test -z "$TOOL"; then : else - echo "Notice: The default version of $1 is defective, using" >&2 - echo "$TOOL instead." >&2 + echo "Notice: The default version of \`$1' is defective, using" >&2 + echo "\`$TOOL' instead." >&2 fi echo "$TOOL" } # You can't run CVS as root; print a nice error message here instead # of somewhere later, after making a mess. -case "`$ID -u`" in - "0") - echo "Test suite does not work correctly when run as root" >&2 - exit 1 - ;; - - "") - ID=`find_tool id` - if test -z "$ID" ; then - echo 'Running these tests requires an "id" program that understands the' >&2 - echo '-u and -n flags. Make sure that such an id (GNU, or many but not' >&2 - echo 'all vendor-supplied versions) is in your path.' >&2 +# +# FIXME - find_tool() finds the 'gid' from GNU id-utils if I pull 'id' out of +# my path. +for pass in false :; do + case "`$ID -u 2>/dev/null`" in + "0") + echo "Test suite does not work correctly when run as root" >&2 exit 1 - fi - ;; -esac + ;; + + "") + if $pass; then :; else + ID=`find_tool id` + fi + if $pass || test -z "$ID" ; then + echo "Running these tests requires an \`id' program that understands the" >&2 + echo "-u and -n flags. Make sure that such an id (GNU, or many but not" >&2 + echo "all vendor-supplied versions) is in your path." >&2 + exit 1 + fi + ;; + + *) + break + ;; + esac +done username=`$ID -un` if $EXPR "${username}" : "${username}" >/dev/null; then : good, it works @@ -269,7 +331,6 @@ if $EXPR "`cat ${TESTDIR}/bar`x" : "`cat ${TESTDIR}/bar`y" >/dev/null; then else : good, it works fi -rm -f ${TESTDIR}/foo ${TESTDIR}/bar # That we should have to do this is total bogosity, but GNU expr # version 1.9.4-1.12 uses the emacs definition of "$" instead of the unix @@ -299,6 +360,21 @@ else \)*' fi +# Now that we have DOTSTAR, make sure it works with big matches +if $EXPR "`cat ${TESTDIR}/bar`" : "${DOTSTAR}xyzABC${DOTSTAR}$" >/dev/null; then + : good, it works +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 'You may wish to make sure GNU expr is in your path.' + EXPR=expr + fi +fi + +rm -f ${TESTDIR}/foo ${TESTDIR}/bar + # Work around yet another GNU expr (version 1.10) bug/incompatibility. # "+" is a special character, yet for unix expr (e.g. SunOS 4.1.3) # it is not. I doubt that POSIX allows us to use \+ and assume it means @@ -350,67 +426,45 @@ fail () # of the implementation common to the two). dotest_internal () { + if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : "$3${ENDANCHOR}" >/dev/null; then + # Why, I hear you ask, do we write this to the logfile + # even when the test passes? The reason is that the test + # may give us the regexp which we were supposed to match, + # but sometimes it may be useful to look at the exact + # text which was output. For example, suppose one wants + # to grep for a particular warning, and make _sure_ that + # CVS never hits it (even in cases where the tests might + # match it with .*). Or suppose one wants to see the exact + # date format output in a certain case (where the test will + # surely use a somewhat non-specific pattern). + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + pass "$1" # expr can't distinguish between "zero characters matched" and "no match", # so special-case it. - if test -z "$3"; then - if test -s ${TESTDIR}/dotest.tmp; then - if test x"$4" != x; then - # We want to match either the empty string or $4. - dotest_internal "$1" "$2" "$4" - else - echo "** expected: " >>${LOGFILE} - echo "$3" >>${LOGFILE} - echo "$3" > ${TESTDIR}/dotest.exp - rm -f ${TESTDIR}/dotest.ex2 - echo "** got: " >>${LOGFILE} - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - fail "$1" - fi - else - pass "$1" - fi - else - if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : \ - "$3"${ENDANCHOR} >/dev/null; then - # See below about writing this to the logfile. + elif test -z "$3" && test ! -s ${TESTDIR}/dotest.tmp; then + pass "$1" + elif test x"$4" != x; then + if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : "$4${ENDANCHOR}" >/dev/null; then cat ${TESTDIR}/dotest.tmp >>${LOGFILE} pass "$1" else - if test x"$4" != x; then - if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : \ - "$4"${ENDANCHOR} >/dev/null; then - # Why, I hear you ask, do we write this to the logfile - # even when the test passes? The reason is that the test - # may give us the regexp which we were supposed to match, - # but sometimes it may be useful to look at the exact - # text which was output. For example, suppose one wants - # to grep for a particular warning, and make _sure_ that - # CVS never hits it (even in cases where the tests might - # match it with .*). Or suppose one wants to see the exact - # date format output in a certain case (where the test will - # surely use a somewhat non-specific pattern). - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - pass "$1" - else - echo "** expected: " >>${LOGFILE} - echo "$3" >>${LOGFILE} - echo "$3" > ${TESTDIR}/dotest.ex1 - echo "** or: " >>${LOGFILE} - echo "$4" >>${LOGFILE} - echo "$4" > ${TESTDIR}/dotest.ex2 - echo "** got: " >>${LOGFILE} - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - fail "$1" - fi - else - echo "** expected: " >>${LOGFILE} - echo "$3" >>${LOGFILE} - echo "$3" > ${TESTDIR}/dotest.exp - echo "** got: " >>${LOGFILE} - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - fail "$1" - fi + echo "** expected: " >>${LOGFILE} + echo "$3" >>${LOGFILE} + echo "$3" > ${TESTDIR}/dotest.ex1 + echo "** or: " >>${LOGFILE} + echo "$4" >>${LOGFILE} + echo "$4" > ${TESTDIR}/dotest.ex2 + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" fi + else + echo "** expected: " >>${LOGFILE} + echo "$3" >>${LOGFILE} + echo "$3" > ${TESTDIR}/dotest.exp + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" fi } @@ -432,6 +486,9 @@ dotest_line_by_line () if $EXPR "`sed -n ${line}p ${TESTDIR}/dotest.tmp`" : \ "`sed -n ${line}p ${TESTDIR}/dotest.exp`" >/dev/null; then : + elif test -z "`sed -n ${line}p ${TESTDIR}/dotest.tmp`" && + test -z "`sed -n ${line}p ${TESTDIR}/dotest.exp`"; then + : else echo "Line $line:" >> ${LOGFILE} echo "**** expected: " >>${LOGFILE} @@ -512,10 +569,9 @@ dotest_internal_debug () dotest () { rm -f ${TESTDIR}/dotest.ex? 2>&1 - if eval "$2" >${TESTDIR}/dotest.tmp 2>&1; then - : so far so good - else - status=$? + eval "$2" >${TESTDIR}/dotest.tmp 2>&1 + status=$? + if test "$status" != 0; then cat ${TESTDIR}/dotest.tmp >>${LOGFILE} echo "exit status was $status" >>${LOGFILE} fail "$1" @@ -527,10 +583,9 @@ dotest () dotest_lit () { rm -f ${TESTDIR}/dotest.ex? 2>&1 - if eval "$2" >${TESTDIR}/dotest.tmp 2>&1; then - : so far so good - else - status=$? + eval "$2" >${TESTDIR}/dotest.tmp 2>&1 + status=$? + if test "$status" != 0; then cat ${TESTDIR}/dotest.tmp >>${LOGFILE} echo "exit status was $status" >>${LOGFILE} fail "$1" @@ -551,15 +606,13 @@ dotest_lit () dotest_fail () { rm -f ${TESTDIR}/dotest.ex? 2>&1 - if eval "$2" >${TESTDIR}/dotest.tmp 2>&1; then - status=$? + eval "$2" >${TESTDIR}/dotest.tmp 2>&1 + status=$? + if test "$status" = 0; then cat ${TESTDIR}/dotest.tmp >>${LOGFILE} echo "exit status was $status" >>${LOGFILE} fail "$1" - else - : so far so good - fi 2>${TESTDIR}/dotest.tmp1 - cat ${TESTDIR}/dotest.tmp1 >>${TESTDIR}/dotest.tmp + fi dotest_internal "$@" } @@ -568,9 +621,7 @@ dotest_status () { eval "$3" >${TESTDIR}/dotest.tmp 2>&1 status=$? - if test "$status" = "$2"; then - : so far so good - else + if test "$status" != "$2"; then cat ${TESTDIR}/dotest.tmp >>${LOGFILE} echo "exit status was $status; expected $2" >>${LOGFILE} fail "$1" @@ -582,10 +633,9 @@ dotest_status () dotest_sort () { rm -f ${TESTDIR}/dotest.ex? 2>&1 - if eval "$2" >${TESTDIR}/dotest.tmp1 2>&1; then - : so far so good - else - status=$? + eval "$2" >${TESTDIR}/dotest.tmp1 2>&1 + status=$? + if test "$status" != 0; then cat ${TESTDIR}/dotest.tmp1 >>${LOGFILE} echo "exit status was $status" >>${LOGFILE} fail "$1" @@ -594,21 +644,6 @@ dotest_sort () dotest_internal "$@" } -# This will show up in cvs history output where it prints the working -# directory. It should *not* appear in any cvs output referring to the -# repository; cvs should use the name of the repository as specified. -# -# Note that using pwd here rather than /bin/pwd will make it even less -# likely that we test whether CVS is distinguishing between TMPPWD -# and TESTDIR. However, there is no guarantee that will test it anyway. -# If we really care, we should do something along the lines of: -# cd /tmp/cvs-sanity # In reality, overridable with environment variable? -# mkdir realdir -# ln -s realdir testdir -# TESTDIR=/tmp/cvs-sanity/testdir -# TMPPWD=/tmp/cvs-sanity/realdir -TMPPWD=`pwd` - # Avoid picking up any stray .cvsrc, etc., from the user running the tests mkdir home HOME=${TESTDIR}/home; export HOME @@ -627,14 +662,15 @@ RCSINIT=; export RCSINIT if test x"$*" = x; then # Basic/miscellaneous functionality - tests="basica basicb basicc basic1 deep basic2" + tests="version basica basicb basicc basic1 deep basic2" tests="${tests} files spacefiles commit-readonly" # Branching, tagging, removing, adding, multiple directories - tests="${tests} rdiff diff death death2 rmadd rmadd2 dirs dirs2" - tests="${tests} branches branches2 tagc tagf" + tests="${tests} rdiff diff death death2 rm-update-message rmadd rmadd2" + tests="${tests} dirs dirs2 branches branches2 tagc tagf" tests="${tests} rcslib multibranch import importb importc" tests="${tests} import-after-initial" - tests="${tests} join join2 join3 join-readonly-conflict join-admin" + tests="${tests} join join2 join3 join-readonly-conflict" + tests="${tests} join-admin join-admin-2" tests="${tests} new newb conflicts conflicts2 conflicts3" tests="${tests} clean" # Checking out various places (modules, checkout -d, &c) @@ -642,11 +678,11 @@ if test x"$*" = x; then tests="${tests} mkmodules-temp-file-removal" tests="${tests} cvsadm emptydir abspath toplevel toplevel2" # Log messages, error messages. - tests="${tests} mflag editor errmsg1 errmsg2" + tests="${tests} mflag editor errmsg1 errmsg2 adderrmsg" # Watches, binary files, history browsing, &c. tests="${tests} devcom devcom2 devcom3 watch4 watch5" tests="${tests} unedit-without-baserev" - tests="${tests} ignore binfiles binfiles2 binfiles3" + tests="${tests} ignore ignore-on-branch binfiles binfiles2 binfiles3" tests="${tests} mcopy binwrap binwrap2" tests="${tests} binwrap3 mwrap info taginfo config" tests="${tests} serverpatch log log2 logopt ann ann-id" @@ -670,21 +706,20 @@ if test x"$*" = x; then # 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" else tests="$*" fi # a simple function to compare directory contents # -# Returns: {nothing} -# Side Effects: ISDIFF := true|false +# Returns: 0 for same, 1 for different # directory_cmp () { OLDPWD=`pwd` DIR_1=$1 DIR_2=$2 - ISDIFF=false cd $DIR_1 find . -print | fgrep -v /CVS | sort > /tmp/dc$$d1 @@ -698,8 +733,7 @@ directory_cmp () then : else - ISDIFF=true - return + return 1 fi cd $OLDPWD while read a @@ -707,132 +741,971 @@ directory_cmp () if test -f $DIR_1/"$a" ; then cmp -s $DIR_1/"$a" $DIR_2/"$a" if test $? -ne 0 ; then - ISDIFF=true + return 1 fi fi done < /tmp/dc$$d1 rm -f /tmp/dc$$* + return 0 } -# Set up CVSROOT (the crerepos tests will test operating without CVSROOT set). -CVSROOT_DIRNAME=${TESTDIR}/cvsroot -CVSROOT=${CVSROOT_DIRNAME} ; export CVSROOT -if test "x$remote" = xyes; 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 -fi -dotest 1 "${testcvs} init" '' -dotest 1a "${testcvs} init" '' -### The big loop -for what in $tests; do - case $what in - basica) - # Similar in spirit to some of the basic1, and basic2 - # tests, but hopefully a lot faster. Also tests operating on - # files two directories down *without* operating on the parent dirs. +# +# The following 4 functions are used by the diffmerge1 test case. They set up, +# respectively, the four versions of the files necessary: +# +# 1. Ancestor revisions. +# 2. "Your" changes. +# 3. "My" changes. +# 4. Expected merge result. +# - # Tests basica-0a and basica-0b provide the equivalent of the: - # mkdir ${CVSROOT_DIRNAME}/first-dir - # used by many of the tests. It is "more official" in the sense - # that is does everything through CVS; the reason most of the - # tests don't use it is mostly historical. - mkdir 1; cd 1 - dotest basica-0a "${testcvs} -q co -l ." '' - mkdir first-dir - dotest basica-0b "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" - cd .. - rm -r 1 +# Create ancestor revisions for diffmerge1 +diffmerge_create_older_files() { + # This test case was supplied by Noah Friedman: + cat >testcase01 <ssfile +public class Button +{ + /* Instantiates a Button with origin (0, 0) and zero width and height. + * You must call an initializer method to properly initialize the Button. + */ + public Button () + { + super (); - # Trying to commit it without a "cvs add" should be an error. - # The "use `cvs add' to create an entry" message is the one - # that I consider to be more correct, but local cvs prints the - # "nothing known" message and noone has gotten around to fixing it. - dotest_fail basica-notadded "${testcvs} -q ci ssfile" \ -"${PROG} [a-z]*: use .${PROG} add. to create an entry for ssfile -${PROG}"' \[[a-z]* aborted\]: correct above errors first!' \ -"${PROG}"' [a-z]*: nothing known about `ssfile'\'' -'"${PROG}"' \[[a-z]* aborted\]: correct above errors first!' + _titleColor = Color.black; + _disabledTitleColor = Color.gray; + _titleFont = Font.defaultFont (); + } - 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' - dotest_fail basica-4a "${testcvs} tag tag0 ssfile" \ -"${PROG} [a-z]*: nothing known about ssfile -${PROG} "'\[[a-z]* aborted\]: correct the above errors first!' - cd ../.. - dotest basica-5 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v -done -Checking in sdir/ssdir/ssfile; -${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile -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 ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v" - dotest basica-5b "${testcvs} -q tag NOT_RESERVED" \ -'T sdir/ssdir/ssfile' + /* Convenience constructor for instantiating a Button with + * bounds x, y, width, and height. Equivalent to + * foo = new Button (); + * foo.init (x, y, width, height); + */ + public Button (int x, int y, int width, int height) + { + this (); + init (x, y, width, height); + } +} +EOF - dotest basica-6 "${testcvs} -q update" '' - echo "ssfile line 2" >>sdir/ssdir/ssfile - dotest_status basica-6.2 1 "${testcvs} -q diff -c" \ -"Index: sdir/ssdir/ssfile -=================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v -retrieving revision 1\.1 -diff -c -r1\.1 ssfile -\*\*\* sdir/ssdir/ssfile [0-9/]* [0-9:]* 1\.1 ---- sdir/ssdir/ssfile [0-9/]* [0-9:]* -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* ---- 1,2 ---- + # This test case was supplied by Jacob Burckhardt: + cat >testcase02 <testcase03 <testcase04 <testcase05 <testcase06 <testcase07 <testcase08 <testcase09 <testcase10 <testcase01 <<\EOF +// Button.java + +package random.application; + +import random.util.*; + +public class Button +{ + /* Instantiates a Button with origin (0, 0) and zero width and height. + * You must call an initializer method to properly initialize the Button. + */ + public Button () + { + super (); + + _titleColor = Color.black; + _disabledTitleColor = Color.gray; + _titleFont = Font.defaultFont (); + } +} +EOF + + cat >testcase02 <<\EOF +y +a +a +a +a +EOF + + cat >testcase03 <<\EOF +x +s +a +b +s +b +s +y +EOF + + cat >testcase04 <<\EOF +s +m +s +v +s +m +s +EOF + + cat >testcase05 <<\EOF +v +s +m +s +s +s +s +s +s +s +s +s +s +v +EOF + + # Test case 6 and test case 7 both use the same input files, but they + # order the input files differently. In one case, a certain file is + # used as the older file, but in the other test case, that same file + # is used as the file which has changes. I could have put echo + # commands here, but since the echo lines would be the same as those + # in the previous function, I decided to save space and avoid repeating + # several lines of code. Instead, I merely swap the files: + mv testcase07 tmp + mv testcase06 testcase07 + mv tmp testcase06 + + # Make the date newer so that cvs thinks that the files are changed: + touch testcase06 testcase07 + + cat >testcase08 <<\EOF +no +changes +here + +First change has now added this in. + + no + changes + here + +Second change will change it here. + + no + changes + here + +Both changes move this line to the end of the file. +EOF + + cat >testcase09 <<\EOF + +m +a +{ +} +b +{ +} +c +{ +} +EOF + + cat >testcase10 <<\EOF + + fV ( BzQkV_URYYfYg ) (*jfle_Uecopdk)[0].jfle_Uecopd_KRLIep = ZpfgfYal_jUK; + + petRpY ( MtatRk ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + fV ( jfle_Uecopd_KRLIep < 16 ) + { + MtatRk = Uead_Ktz_qjT_jfle_Uecopd ( jfle_Uecopd_KRLIep, (uofd*)nRVVep ); + } + elke + { + MtatRk = ZreY_GttpfIRte_MtpeaL ( qjT_jfle_Uecopdk, qjT_jfle_Uecopd_BoRYt, HGTG_TvFD, KXbb, KXbb, &acI ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek ); + OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep ); + + Bloke_GttpfIRte_MtpeaL ( &acI ); +MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + fV ( Y < 16 ) + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + Y * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + elke + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + + petRpY ( MtatRk ); + +} + + +/**************************************************************************** +* * +* Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY ) * +* * +****************************************************************************/ + +MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep ); + + petRpY ( MtatRk ); + +} + HfkQipfte ( waYdle, /* waYdle */ + waYdleFok, /* ZVVket VpoL ktapt oV dfkQ */ + (coYkt RfYt8*) nRVVep, /* nRVVep */ + 0, /* MRrepVlRoRk KfxoYfkL */ + beYgtz /* nEtek to Apfte */ + ); + + petRpY ( Zy ); +} + +EOF +} + +# Create "my" revisions for diffmerge1 +diffmerge_create_my_files() { + # My working copy still has the Button() method, but I + # comment out some code at the top of the class. + cat >testcase01 <<\EOF +// Button.java + +package random.application; + +import random.util.*; + +public class Button +{ + /* Instantiates a Button with origin (0, 0) and zero width and height. + * You must call an initializer method to properly initialize the Button. + */ + public Button () + { + super (); + + // _titleColor = Color.black; + // _disabledTitleColor = Color.gray; + // _titleFont = Font.defaultFont (); + } + + /* Convenience constructor for instantiating a Button with + * bounds x, y, width, and height. Equivalent to + * foo = new Button (); + * foo.init (x, y, width, height); + */ + public Button (int x, int y, int width, int height) + { + this (); + init (x, y, width, height); + } +} +EOF + + cat >testcase02 <<\EOF +a +a +a +a +m +EOF + + cat >testcase03 <<\EOF +x +s +c +s +b +s +y +EOF + + cat >testcase04 <<\EOF +v +s +x +m +m +x +s +v +s +x +m +m +x +s +v +EOF + + # Note that in test case 5, there are no changes in the "mine" + # section, which explains why there is no command here which writes to + # file testcase05. + + # no changes for testcase06 + + # The two branches make the same changes: + cp ../yours/testcase07 . + + cat >testcase08 <<\EOF +no +changes +here + +First change will delete this line. + +First change will also delete this line. + + no + changes + here + +Second change has now changed it here. + + no + changes + here + +Both changes move this line to the end of the file. +EOF + + cat >testcase09 <<\EOF +m +a +{ +} +b +{ +} +c +{ +} +EOF + + cat >testcase10 <<\EOF + + petRpY ( MtatRk ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek ); + OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep ); + + Bloke_GttpfIRte_MtpeaL ( &acI ); +MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep ) +{ + fV ( Y < 16 ) + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + Y * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + elke + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + +} + + +/**************************************************************************** +* * +* Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY ) * +* * +****************************************************************************/ + +MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep ); + + petRpY ( MtatRk ); + +} + HfkQipfte ( waYdle, /* waYdle */ + waYdleFok, /* ZVVket VpoL ktapt oV dfkQ */ + (coYkt RfYt8*) nRVVep, /* nRVVep */ + beYgtz /* nEtek to Apfte */ + ); + + petRpY ( Zy ); +} + +EOF +} + +# Create expected results of merge for diffmerge1 +diffmerge_create_expected_files() { + cat >testcase01 <<\EOF +// Button.java + +package random.application; + +import random.util.*; + +public class Button +{ + /* Instantiates a Button with origin (0, 0) and zero width and height. + * You must call an initializer method to properly initialize the Button. + */ + public Button () + { + super (); + + // _titleColor = Color.black; + // _disabledTitleColor = Color.gray; + // _titleFont = Font.defaultFont (); + } +} +EOF + + cat >testcase02 <<\EOF +y +a +a +a +m +EOF + + cat >testcase03 <<\EOF +x +s +c +s +b +s +b +s +y +EOF + + cat >testcase04 <<\EOF +v +s +m +s +v +s +m +s +v +EOF + + # Since there are no changes in the "mine" section, just take exactly + # the version in the "yours" section: + cp ../yours/testcase05 . + + cp ../yours/testcase06 . + + # Since the two branches make the same changes, the result should be + # the same as both branches. Here, I happen to pick yours to copy from, + # but I could have also picked mine, since the source of the copy is + # the same in either case. However, the mine has already been + # altered by the update command, so don't use it. Instead, use the + # yours section which has not had an update on it and so is unchanged: + cp ../yours/testcase07 . + + cat >testcase08 <<\EOF +no +changes +here + +First change has now added this in. + + no + changes + here + +Second change has now changed it here. + + no + changes + here + +Both changes move this line to the end of the file. +EOF + + cat >testcase09 <<\EOF + +m +a +{ +} +b +{ +} +c +{ +} +EOF + + cat >testcase10 <<\EOF + + fV ( BzQkV_URYYfYg ) (*jfle_Uecopdk)[0].jfle_Uecopd_KRLIep = ZpfgfYal_jUK; + + petRpY ( MtatRk ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + fV ( jfle_Uecopd_KRLIep < 16 ) + { + MtatRk = Uead_Ktz_qjT_jfle_Uecopd ( jfle_Uecopd_KRLIep, (uofd*)nRVVep ); + } + elke + { + MtatRk = ZreY_GttpfIRte_MtpeaL ( qjT_jfle_Uecopdk, qjT_jfle_Uecopd_BoRYt, HGTG_TvFD, KXbb, KXbb, &acI ); + fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); + + MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek ); + OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep ); + + Bloke_GttpfIRte_MtpeaL ( &acI ); +MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + fV ( Y < 16 ) + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + Y * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + elke + { + petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep + + ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk, + jfle_Uecopd_MfJe_fY_Mectopk, + nRVVep ) ); + } + + petRpY ( MtatRk ); + +} + + +/**************************************************************************** +* * +* Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY ) * +* * +****************************************************************************/ + +MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep ) +{ +MTGTXM MtatRk = Zy; + + MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep ); + + petRpY ( MtatRk ); + +} + HfkQipfte ( waYdle, /* waYdle */ + waYdleFok, /* ZVVket VpoL ktapt oV dfkQ */ + (coYkt RfYt8*) nRVVep, /* nRVVep */ + beYgtz /* nEtek to Apfte */ + ); + + petRpY ( Zy ); +} + +EOF +} + +# 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 +fi + +dotest 1 "${testcvs} init" '' +dotest 1a "${testcvs} init" '' + +### The big loop +for what in $tests; do + if test -n "$fromtest" ; then + if test $fromtest = $what ; then + unset fromtest + else + continue + fi + fi + case $what in + + version) + # We've had cases where the version command started dumping core, + # so we might as well test it + dotest version-1 "${testcvs} --version" \ +' +Concurrent Versions System (CVS) [0-9.]*.* + +Copyright (c) [-0-9]* Brian Berliner, david d .zoo. zuhn, + Jeff Polk, and other authors + +CVS may be copied only under the terms of the GNU General Public License, +a copy of which can be found with the CVS distribution kit. + +Specify the --help option for further information about CVS' + + if $remote; then + dotest version-2r "${testcvs} version" \ +'Client: Concurrent Versions System (CVS) [0-9.]* (client/server) +Server: Concurrent Versions System (CVS) [0-9.]* (client/server)' + else + dotest version-2 "${testcvs} version" \ +'Concurrent Versions System (CVS) [0-9.]*.*' + fi + ;; + + basica) + # Similar in spirit to some of the basic1, and basic2 + # tests, but hopefully a lot faster. Also tests operating on + # files two directories down *without* operating on the parent dirs. + + # Tests basica-0a and basica-0b provide the equivalent of the: + # mkdir ${CVSROOT_DIRNAME}/first-dir + # used by many of the tests. It is "more official" in the sense + # that is does everything through CVS; the reason most of the + # tests don't use it is mostly historical. + mkdir 1; cd 1 + dotest basica-0a "${testcvs} -q co -l ." '' + mkdir first-dir + dotest basica-0b "${testcvs} add first-dir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" + cd .. + rm -r 1 + + dotest basica-1 "${testcvs} -q co first-dir" '' + cd first-dir + + # Test a few operations, to ensure they gracefully do + # nothing in an empty directory. + dotest basica-1a0 "${testcvs} -q update" '' + dotest basica-1a1 "${testcvs} -q diff -c" '' + dotest basica-1a2 "${testcvs} -q status" '' + + mkdir sdir + # Remote CVS gives the "cannot open CVS/Entries" error, which is + # clearly a bug, but not a simple one to fix. + dotest basica-1a10 "${testcvs} -n add sdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" \ +"${PROG} add: cannot open CVS/Entries for reading: No such file or directory +Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" + dotest_fail basica-1a11 \ + "test -d ${CVSROOT_DIRNAME}/first-dir/sdir" '' + dotest basica-2 "${testcvs} add sdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" + cd sdir + mkdir ssdir + dotest basica-3 "${testcvs} add ssdir" \ +"Directory ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir added to the repository" + cd ssdir + echo ssfile >ssfile + + # Trying to commit it without a "cvs add" should be an error. + # The "use `cvs add' to create an entry" message is the one + # that I consider to be more correct, but local cvs prints the + # "nothing known" message and noone has gotten around to fixing it. + dotest_fail basica-notadded "${testcvs} -q ci ssfile" \ +"${PROG} [a-z]*: use .${PROG} add. to create an entry for ssfile +${PROG}"' \[[a-z]* aborted\]: correct above errors first!' \ +"${PROG}"' [a-z]*: nothing known about `ssfile'\'' +'"${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' + dotest_fail basica-4a "${testcvs} tag tag0 ssfile" \ +"${PROG} [a-z]*: nothing known about ssfile +${PROG} "'\[[a-z]* 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 +done +Checking in sdir/ssdir/ssfile; +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +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" + 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" \ +"Index: sdir/ssdir/ssfile +=================================================================== +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +retrieving revision 1\.1 +diff -c -r1\.1 ssfile +\*\*\* sdir/ssdir/ssfile ${RFCDATE} 1\.1 +--- sdir/ssdir/ssfile ${RFCDATE} +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +--- 1,2 ---- ssfile ${PLUS} ssfile line 2" dotest_status basica-6.3 1 "${testcvs} -q diff -c -rBASE" \ "Index: sdir/ssdir/ssfile =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v retrieving revision 1\.1 diff -c -r1\.1 ssfile -\*\*\* sdir/ssdir/ssfile [0-9/]* [0-9:]* 1\.1 ---- sdir/ssdir/ssfile [0-9/]* [0-9:]* +\*\*\* sdir/ssdir/ssfile ${RFCDATE} 1\.1 +--- sdir/ssdir/ssfile ${RFCDATE} \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1 \*\*\*\* --- 1,2 ---- @@ -840,7 +1713,7 @@ diff -c -r1\.1 ssfile ${PLUS} ssfile line 2" dotest basica-7 "${testcvs} -q ci -m modify-it" \ "Checking in sdir/ssdir/ssfile; -${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile new revision: 1\.2; previous revision: 1\.1 done" dotest_fail basica-nonexist "${testcvs} -q ci nonexist" \ @@ -853,31 +1726,31 @@ done" dotest basica-8a0 "${testcvs} -q ci -m not-modified ssfile" '' dotest basica-8a "${testcvs} -q ci -f -m force-it" \ "Checking in ssfile; -${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile new revision: 1\.3; previous revision: 1\.2 done" dotest basica-8a1 "${testcvs} -q ci -m bump-it -r 2.0" \ "Checking in ssfile; -${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile new revision: 2\.0; previous revision: 1\.3 done" # -f should not be necessary, but it should be harmless. # Also test the "-r 3" (rather than "-r 3.0") usage. dotest basica-8a2 "${testcvs} -q ci -m bump-it -f -r 3" \ "Checking in ssfile; -${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile new revision: 3\.1; previous revision: 2\.0 done" # Test using -r to create a branch dotest_fail basica-8a3 "${testcvs} -q ci -m bogus -r 3.0.0" \ "Checking in ssfile; -${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile -${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v: can't find branch point 3\.0 +${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" dotest basica-8a4 "${testcvs} -q ci -m valid -r 3.1.2" \ "Checking in ssfile; -${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile new revision: 3\.1\.2\.1; previous revision: 3\.1 done" # now get rid of the sticky tag and go back to the trunk @@ -887,7 +1760,7 @@ done" dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" \ "Index: sdir/ssdir/ssfile =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v retrieving revision 1\.2 retrieving revision 1\.3 diff -r1\.2 -r1\.3" @@ -895,7 +1768,7 @@ diff -r1\.2 -r1\.3" dotest_fail basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd" \ "Index: sdir/ssdir/ssfile =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v retrieving revision 1\.2 retrieving revision 1\.3 diff -C3isacrowd -r1\.2 -r1\.3 @@ -916,6 +1789,27 @@ ${PROG} [a-z]*: invalid context length argument" 1\.1 .'"${username}"' *[0-9a-zA-Z-]*.: ssfile 1\.2 .'"${username}"' *[0-9a-zA-Z-]*.: ssfile line 2' + # 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" + dotest basica-r2 "${testcvs} -q ci -m remove" \ +"Removing ssfile; +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: delete; previous revision: 3\.1 +done" + dotest basica-r3 "${testcvs} -q up -p -r 3.1 ssfile >ssfile" "" + dotest basica-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" + dotest basica-r5 "${testcvs} -q ci -m resurrect" \ +"Checking in ssfile; +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 3\.3; previous revision: 3\.2 +done" + cd ../.. + # As long as we have a file with a few revisions, test # a few "cvs admin -o" invocations. cd sdir/ssdir @@ -923,40 +1817,42 @@ ${PROG} [a-z]*: invalid context length argument" "${PROG} [a-z]*: while processing more than one file: ${PROG} \[[a-z]* aborted\]: attempt to specify a numeric revision" dotest basica-o2 "${testcvs} admin -o 1.2::1.2 ssfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v done" dotest basica-o2a "${testcvs} admin -o 1.1::NOT_RESERVED ssfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v done" dotest_fail basica-o2b "${testcvs} admin -o 1.1::NOT_EXIST ssfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v -${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v: Revision NOT_EXIST doesn't exist. -${PROG} [a-z]*: cannot modify RCS file for .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\." dotest basica-o3 "${testcvs} admin -o 1.2::1.3 ssfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v done" dotest basica-o4 "${testcvs} admin -o 3.1:: ssfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +deleting revision 3\.3 +deleting revision 3\.2 done" dotest basica-o5 "${testcvs} admin -o ::1.1 ssfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v done" dotest basica-o5a "${testcvs} -n admin -o 1.2::3.1 ssfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v deleting revision 2\.0 deleting revision 1\.3 done" dotest basica-o6 "${testcvs} admin -o 1.2::3.1 ssfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v deleting revision 2\.0 deleting revision 1\.3 done" dotest basica-o6a "${testcvs} admin -o 3.1.2: ssfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v deleting revision 3\.1\.2\.1 done" dotest basica-o7 "${testcvs} log -N ssfile" " -RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v Working file: ssfile head: 3\.1 branch: @@ -996,10 +1892,10 @@ add-it "${PROG} [a-z]*: scheduling file .topfile. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest basicb-0c "${testcvs} -q ci -m add-it topfile" \ -"RCS file: ${TESTDIR}/cvsroot/topfile,v +"RCS file: ${CVSROOT_DIRNAME}/topfile,v done Checking in topfile; -${TESTDIR}/cvsroot/topfile,v <-- topfile +${CVSROOT_DIRNAME}/topfile,v <-- topfile initial revision: 1\.1 done" cd .. @@ -1015,7 +1911,7 @@ done" dotest basicb-0d0 "${testcvs} -q co -l ." "" mkdir first-dir dotest basicb-0e "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd .. rm -r 2 @@ -1032,10 +1928,10 @@ done" # (we're using relative paths). : dotest basicb-1b "cat CVS/Repository" \ -"${TESTDIR}/cvsroot/\." \ +"${CVSROOT_DIRNAME}/\." \ "\." dotest basicb-1c "cat first-dir/CVS/Repository" \ -"${TESTDIR}/cvsroot/first-dir" \ +"${CVSROOT_DIRNAME}/first-dir" \ "first-dir" cd first-dir @@ -1044,8 +1940,8 @@ done" # special only when it is directly in $CVSROOT/CVSROOT. mkdir Emptydir sdir2 dotest basicb-2 "${testcvs} add Emptydir sdir2" \ -"Directory ${TESTDIR}/cvsroot/first-dir/Emptydir added to the repository -Directory ${TESTDIR}/cvsroot/first-dir/sdir2 added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/Emptydir added to the repository +Directory ${CVSROOT_DIRNAME}/first-dir/sdir2 added to the repository" cd Emptydir echo sfile1 starts >sfile1 dotest basicb-2a10 "${testcvs} -n add sfile1" \ @@ -1081,22 +1977,22 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" ${PROG} [a-z]*: but CVS uses CVS for its own purposes; skipping CVS directory" cd .. dotest basicb-5 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/Emptydir/sfile1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Emptydir/sfile1,v done Checking in Emptydir/sfile1; -${TESTDIR}/cvsroot/first-dir/Emptydir/sfile1,v <-- sfile1 +${CVSROOT_DIRNAME}/first-dir/Emptydir/sfile1,v <-- sfile1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/sdir2/sfile2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v done Checking in sdir2/sfile2; -${TESTDIR}/cvsroot/first-dir/sdir2/sfile2,v <-- sfile2 +${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v <-- sfile2 initial revision: 1\.1 done" echo sfile1 develops >Emptydir/sfile1 dotest basicb-6 "${testcvs} -q ci -m modify" \ "Checking in Emptydir/sfile1; -${TESTDIR}/cvsroot/first-dir/Emptydir/sfile1,v <-- sfile1 +${CVSROOT_DIRNAME}/first-dir/Emptydir/sfile1,v <-- sfile1 new revision: 1\.2; previous revision: 1\.1 done" dotest basicb-7 "${testcvs} -q tag release-1" 'T Emptydir/sfile1 @@ -1104,7 +2000,7 @@ T sdir2/sfile2' echo not in time for release-1 >sdir2/sfile2 dotest basicb-8 "${testcvs} -q ci -m modify-2" \ "Checking in sdir2/sfile2; -${TESTDIR}/cvsroot/first-dir/sdir2/sfile2,v <-- sfile2 +${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v <-- sfile2 new revision: 1\.2; previous revision: 1\.1 done" # See if CVS can correctly notice when an invalid numeric @@ -1146,19 +2042,19 @@ U newdir/first-dir/sdir2/sfile2' # is defined (we're using relative paths). : dotest basicb-9b "cat CVS/Repository" \ -"${TESTDIR}/cvsroot/\." \ +"${CVSROOT_DIRNAME}/\." \ "\." dotest basicb-9c "cat newdir/CVS/Repository" \ -"${TESTDIR}/cvsroot/\." \ +"${CVSROOT_DIRNAME}/\." \ "\." dotest basicb-9d "cat newdir/first-dir/CVS/Repository" \ -"${TESTDIR}/cvsroot/first-dir" \ +"${CVSROOT_DIRNAME}/first-dir" \ "first-dir" dotest basicb-9e "cat newdir/first-dir/Emptydir/CVS/Repository" \ -"${TESTDIR}/cvsroot/first-dir/Emptydir" \ +"${CVSROOT_DIRNAME}/first-dir/Emptydir" \ "first-dir/Emptydir" dotest basicb-9f "cat newdir/first-dir/sdir2/CVS/Repository" \ -"${TESTDIR}/cvsroot/first-dir/sdir2" \ +"${CVSROOT_DIRNAME}/first-dir/sdir2" \ "first-dir/sdir2" dotest basicb-10 "cat newdir/first-dir/Emptydir/sfile1 newdir/first-dir/sdir2/sfile2" \ @@ -1188,24 +2084,24 @@ U sub1/sub2/sdir2/sfile2" dotest basicb-14 "${testcvs} -q co -l ." 'U topfile' mkdir second-dir dotest basicb-15 "${testcvs} add second-dir" \ -"Directory ${TESTDIR}/cvsroot/second-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" 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" dotest basicb-17 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/second-dir/aa,v +"RCS file: ${CVSROOT_DIRNAME}/second-dir/aa,v done Checking in aa; -${TESTDIR}/cvsroot/second-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/second-dir/aa,v <-- aa initial revision: 1\.1 done" cd .. # Try to remove all revisions in a file. dotest_fail basicb-o1 "${testcvs} admin -o1.1 topfile" \ -"RCS file: ${TESTDIR}/cvsroot/topfile,v +"RCS file: ${CVSROOT_DIRNAME}/topfile,v deleting revision 1\.1 ${PROG} \[[a-z]* aborted\]: attempt to delete all revisions" dotest basicb-o2 "${testcvs} -q update -d first-dir" \ @@ -1213,7 +2109,7 @@ ${PROG} \[[a-z]* aborted\]: attempt to delete all revisions" U first-dir/sdir2/sfile2" dotest_fail basicb-o3 \ "${testcvs} admin -o1.1:1.2 first-dir/sdir2/sfile2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir2/sfile2,v +"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" @@ -1234,7 +2130,7 @@ ${PROG} \[admin aborted\]: specify ${PROG} -H admin for usage information" cd .. rmdir 1 - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -1253,8 +2149,8 @@ ${PROG} \[[a-z]* aborted\]: there is no version here; run .${PROG} checkout. fir dotest basicc-2 "${testcvs} -q co -l ." '' mkdir first-dir second-dir dotest basicc-3 "${testcvs} add first-dir second-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository -Directory ${TESTDIR}/cvsroot/second-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository +Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" # Old versions of CVS often didn't create this top-level CVS # directory in the first place. I think that maybe the only # way to get it to work currently is to let CVS create it, @@ -1311,7 +2207,7 @@ ${PROG} [a-z]*: Updating second-dir" basic1) # first dive - add a files, first singly, then in a group. mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1; cd 1 + mkdir basic1; cd basic1 # check out an empty directory dotest basic1-1 "${testcvs} -q co first-dir" '' @@ -1444,28 +2340,28 @@ A first-dir/file5" cd first-dir dotest basic1-14-add-ci \ "${testcvs} commit -m test file2 file3 file4 file5" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file3,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v done Checking in file3; -${TESTDIR}/cvsroot/first-dir/file3,v <-- file3 +${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file4,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v done Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file5,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file5,v done Checking in file5; -${TESTDIR}/cvsroot/first-dir/file5,v <-- file5 +${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 initial revision: 1\.1 done" dotest basic1-15-add-ci \ @@ -1476,7 +2372,7 @@ done" File: file2 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file2,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file2,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) @@ -1485,7 +2381,7 @@ File: file2 Status: Up-to-date File: file3 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file3,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file3,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) @@ -1494,7 +2390,7 @@ File: file3 Status: Up-to-date File: file4 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file4,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file4,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) @@ -1503,7 +2399,7 @@ File: file4 Status: Up-to-date File: file5 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file5,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file5,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" @@ -1561,7 +2457,7 @@ R file5" File: no file file2 Status: Locally Removed Working revision: -1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file2,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file2,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) @@ -1570,7 +2466,7 @@ File: no file file2 Status: Locally Removed File: no file file3 Status: Locally Removed Working revision: -1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file3,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file3,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) @@ -1579,7 +2475,7 @@ File: no file file3 Status: Locally Removed File: no file file4 Status: Locally Removed Working revision: -1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file4,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file4,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) @@ -1588,7 +2484,7 @@ File: no file file4 Status: Locally Removed File: no file file5 Status: Locally Removed Working revision: -1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file5,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file5,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" @@ -1628,19 +2524,19 @@ R first-dir/file5" cd first-dir dotest basic1-14-rm-ci "${testcvs} -q commit -m test" \ "Removing file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: delete; previous revision: 1\.1 done Removing file3; -${TESTDIR}/cvsroot/first-dir/file3,v <-- file3 +${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 new revision: delete; previous revision: 1\.1 done Removing file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: delete; previous revision: 1\.1 done Removing file5; -${TESTDIR}/cvsroot/first-dir/file5,v <-- file5 +${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 new revision: delete; previous revision: 1\.1 done" dotest basic1-15-rm-ci \ @@ -1674,12 +2570,12 @@ done" cd .. cd .. - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi - rm -r 1 + rm -r basic1 rm -rf ${CVSROOT_DIRNAME}/first-dir ;; @@ -1691,7 +2587,7 @@ done" for i in dir1 dir2 dir3 dir4 dir5 dir6 dir7 dir8; do mkdir $i dotest deep-2-$i "${testcvs} add $i" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir1[/dir0-9]* added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/dir1[/dir0-9]* added to the repository" cd $i echo file1 >file1 dotest deep-3-$i "${testcvs} add file1" \ @@ -1700,52 +2596,52 @@ done" done cd ../../../../../../../../.. dotest_lit deep-4 "${testcvs} -q ci -m add-them first-dir" <> ${LOGFILE}; then - pass 29-$i - else - fail 29-$i - fi + dotest basic2-2-$i "${testcvs} add $i" \ +"Directory ${CVSROOT_DIRNAME}/.*/$i added to the repository" fi - cd $i + cd $i + + for j in file6 file7; do + echo $j > $j + 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" + + done + cd ../../.. + dotest basic2-4 "${testcvs} update first-dir" \ +"${PROG} [a-z]*: Updating first-dir +A first-dir/file6 +A first-dir/file7 +${PROG} [a-z]*: Updating first-dir/dir1 +A first-dir/dir1/file6 +A first-dir/dir1/file7 +${PROG} [a-z]*: 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" + + dotest basic2-6 "${testcvs} status first-dir" \ +"${PROG} [a-z]*: Examining first-dir +=================================================================== +File: file6 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file7 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +${PROG} [a-z]*: Examining first-dir/dir1 +=================================================================== +File: file6 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file7 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) - for j in file6 file7; do - echo $j > $j - done +${PROG} [a-z]*: Examining first-dir/dir1/dir2 +=================================================================== +File: file6 Status: Locally Added - if ${CVS} add file6 file7 2>> ${LOGFILE}; then - pass 30-$i-$j - else - fail 30-$i-$j - fi - done - cd ../../.. - if ${CVS} update first-dir ; then - pass 31 - else - fail 31 - fi + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) - # fixme: doesn't work right for added files. - if ${CVS} log first-dir >> ${LOGFILE}; then - pass 32 - else - fail 32 - fi +=================================================================== +File: file7 Status: Locally Added - if ${CVS} status first-dir >> ${LOGFILE}; then - pass 33 - else - fail 33 - fi + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" # XXX why is this commented out??? # if ${CVS} diff -u first-dir >> ${LOGFILE} || test $? = 1 ; then @@ -1890,17 +2845,54 @@ done" # fail 34 # fi - if ${CVS} ci -m "second dive" first-dir >> ${LOGFILE} 2>&1; then - pass 35 - else - fail 35 - fi + dotest basic2-8 "${testcvs} -q ci -m 'second dive' first-dir" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v +done +Checking in first-dir/file6; +${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 +initial revision: 1\.1 +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v +done +Checking in first-dir/file7; +${CVSROOT_DIRNAME}/first-dir/file7,v <-- file7 +initial revision: 1\.1 +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v +done +Checking in first-dir/dir1/file6; +${CVSROOT_DIRNAME}/first-dir/dir1/file6,v <-- file6 +initial revision: 1\.1 +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v +done +Checking in first-dir/dir1/file7; +${CVSROOT_DIRNAME}/first-dir/dir1/file7,v <-- file7 +initial revision: 1\.1 +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v +done +Checking in first-dir/dir1/dir2/file6; +${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v <-- file6 +initial revision: 1\.1 +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v +done +Checking in first-dir/dir1/dir2/file7; +${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v <-- file7 +initial revision: 1\.1 +done" - if ${CVS} tag second-dive first-dir ; then - pass 36 - else - fail 36 - fi + dotest basic2-9 "${testcvs} tag second-dive first-dir" \ +"${PROG} [a-z]*: Tagging first-dir +T first-dir/file6 +T first-dir/file7 +${PROG} [a-z]*: Tagging first-dir/dir1 +T first-dir/dir1/file6 +T first-dir/dir1/file7 +${PROG} [a-z]*: Tagging first-dir/dir1/dir2 +T first-dir/dir1/dir2/file6 +T first-dir/dir1/dir2/file7" # third dive - in bunch o' directories, add bunch o' files, # delete some, change some. @@ -1914,40 +2906,228 @@ done" # delete a file rm file7 - if ${CVS} rm file7 2>> ${LOGFILE}; then - pass 37-$i - else - fail 37-$i - fi + 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" # and add a new file echo file14 >file14 - if ${CVS} add file14 2>> ${LOGFILE}; then - pass 38-$i - else - fail 38-$i - fi + 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" done + cd ../../.. - if ${CVS} update first-dir ; then - pass 39 - else - fail 39 - fi + dotest basic2-12 "${testcvs} update first-dir" \ +"${PROG} [a-z]*: Updating first-dir +A first-dir/file14 +M first-dir/file6 +R first-dir/file7 +${PROG} [a-z]*: 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 +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 - if ${CVS} log first-dir >> ${LOGFILE}; then - pass 40 - else - fail 40 - fi + dotest basic2-13 "${testcvs} log first-dir" \ +"${PROG} [a-z]*: Logging first-dir +${PROG} [a-z]*: file14 has been added, but not committed - if ${CVS} status first-dir >> ${LOGFILE}; then - pass 41 - else - fail 41 - fi +RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v +Working file: first-dir/file6 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; +second dive +============================================================================= + +RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v +Working file: first-dir/file7 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +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 + +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v +Working file: first-dir/dir1/file6 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; +second dive +============================================================================= + +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v +Working file: first-dir/dir1/file7 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +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 + +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v +Working file: first-dir/dir1/dir2/file6 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; +second dive +============================================================================= + +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v +Working file: first-dir/dir1/dir2/file7 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + second-dive: 1\.1 +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1\.1 +date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; +second dive +=============================================================================" + + dotest basic2-14 "${testcvs} status first-dir" \ +"${PROG} [a-z]*: Examining first-dir +=================================================================== +File: file14 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file6 Status: Locally Modified + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file6,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: no file file7 Status: Locally Removed + + Working revision: -1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file7,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +${PROG} [a-z]*: Examining first-dir/dir1 +=================================================================== +File: file14 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file6 Status: Locally Modified + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: no file file7 Status: Locally Removed + + Working revision: -1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +${PROG} [a-z]*: Examining first-dir/dir1/dir2 +=================================================================== +File: file14 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: file6 Status: Locally Modified + + Working revision: 1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: no file file7 Status: Locally Removed + + Working revision: -1\.1.* + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" # XXX why is this commented out? # if ${CVS} diff -u first-dir >> ${LOGFILE} || test $? = 1 ; then @@ -1956,113 +3136,213 @@ done" # fail 42 # fi - if ${CVS} ci -m "third dive" first-dir >>${LOGFILE} 2>&1; then - pass 43 - else - fail 43 - fi - dotest 43.5 "${testcvs} -q update first-dir" '' - - if ${CVS} tag third-dive first-dir ; then - pass 44 - else - fail 44 - fi + dotest basic2-16 "${testcvs} ci -m 'third dive' first-dir" \ +"${PROG} [a-z]*: Examining first-dir +${PROG} [a-z]*: Examining first-dir/dir1 +${PROG} [a-z]*: Examining first-dir/dir1/dir2 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file14,v +done +Checking in first-dir/file14; +${CVSROOT_DIRNAME}/first-dir/file14,v <-- file14 +initial revision: 1\.1 +done +Checking in first-dir/file6; +${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 +new revision: 1\.2; previous revision: 1\.1 +done +Removing first-dir/file7; +${CVSROOT_DIRNAME}/first-dir/file7,v <-- file7 +new revision: delete; previous revision: 1\.1 +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file14,v +done +Checking in first-dir/dir1/file14; +${CVSROOT_DIRNAME}/first-dir/dir1/file14,v <-- file14 +initial revision: 1\.1 +done +Checking in first-dir/dir1/file6; +${CVSROOT_DIRNAME}/first-dir/dir1/file6,v <-- file6 +new revision: 1\.2; previous revision: 1\.1 +done +Removing first-dir/dir1/file7; +${CVSROOT_DIRNAME}/first-dir/dir1/file7,v <-- file7 +new revision: delete; previous revision: 1\.1 +done +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file14,v +done +Checking in first-dir/dir1/dir2/file14; +${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file14,v <-- file14 +initial revision: 1\.1 +done +Checking in first-dir/dir1/dir2/file6; +${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v <-- file6 +new revision: 1\.2; previous revision: 1\.1 +done +Removing first-dir/dir1/dir2/file7; +${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v <-- file7 +new revision: delete; previous revision: 1\.1 +done" + dotest basic2-17 "${testcvs} -q update first-dir" '' - if echo "yes" | ${CVS} release -d first-dir ; then - pass 45 - else - fail 45 - fi + dotest basic2-18 "${testcvs} tag third-dive first-dir" \ +"${PROG} [a-z]*: Tagging first-dir +T first-dir/file14 +T first-dir/file6 +${PROG} [a-z]*: Tagging first-dir/dir1 +T first-dir/dir1/file14 +T first-dir/dir1/file6 +${PROG} [a-z]*: Tagging first-dir/dir1/dir2 +T first-dir/dir1/dir2/file14 +T first-dir/dir1/dir2/file6" + + dotest basic2-19 "echo yes | ${testcvs} release -d first-dir" \ +"You have \[0\] altered files in this repository\. +Are you sure you want to release (and delete) directory .first-dir.: " # end of third dive - if test -d first-dir ; then - fail 45.5 - else - pass 45.5 - fi + dotest_fail basic2-20 "test -d first-dir" "" # now try some rtags # rtag HEADS - if ${CVS} rtag rtagged-by-head first-dir ; then - pass 46 - else - fail 46 - fi + 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" # tag by tag - if ${CVS} rtag -r rtagged-by-head rtagged-by-tag first-dir ; then - pass 47 - else - fail 47 - fi + 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" # tag by revision - if ${CVS} rtag -r1.1 rtagged-by-revision first-dir ; then - pass 48 - else - fail 48 - fi - - # rdiff by revision - if ${CVS} rdiff -r1.1 -rrtagged-by-head first-dir >> ${LOGFILE} || test $? = 1 ; then - pass 49 - else - fail 49 - fi + 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" + # rdiff by revision + dotest basic2-24 "${testcvs} rdiff -r1.1 -rrtagged-by-head first-dir" \ +"${PROG} [a-z]*: 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 .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 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 .* +--- first-dir/file7 .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- file7 +--- 0 ---- +${PROG} [a-z]*: 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 .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +--- 1,2 ---- + file6 +${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 .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- file7 +--- 0 ---- +${PROG} [a-z]*: 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 .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +--- 1,2 ---- + file6 +${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 .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- file7 +--- 0 ----" # now export by rtagged-by-head and rtagged-by-tag and compare. - if ${CVS} export -r rtagged-by-head first-dir ; then - pass 50 - else - fail 50 - fi + dotest basic2-25 "${testcvs} export -r rtagged-by-head first-dir" \ +"${PROG} [a-z]*: Updating first-dir +U first-dir/file14 +U first-dir/file6 +${PROG} [a-z]*: Updating first-dir/dir1 +U first-dir/dir1/file14 +U first-dir/dir1/file6 +${PROG} [a-z]*: Updating first-dir/dir1/dir2 +U first-dir/dir1/dir2/file14 +U first-dir/dir1/dir2/file6" mv first-dir 1dir - if ${CVS} export -r rtagged-by-tag first-dir ; then - pass 51 - else - fail 51 - fi - - directory_cmp 1dir first-dir - - if $ISDIFF ; then - fail 52 - else - pass 52 - fi + dotest basic2-26 "${testcvs} export -r rtagged-by-tag first-dir" \ +"${PROG} [a-z]*: Updating first-dir +U first-dir/file14 +U first-dir/file6 +${PROG} [a-z]*: Updating first-dir/dir1 +U first-dir/dir1/file14 +U first-dir/dir1/file6 +${PROG} [a-z]*: Updating first-dir/dir1/dir2 +U first-dir/dir1/dir2/file14 +U first-dir/dir1/dir2/file6" + + dotest basic2-27 "directory_cmp 1dir first-dir" rm -r 1dir first-dir # checkout by revision vs export by rtagged-by-revision and compare. - if ${CVS} export -rrtagged-by-revision -d export-dir first-dir ; then - pass 53 - else - fail 53 - fi - - if ${CVS} co -r1.1 first-dir ; then - pass 54 - else - fail 54 - fi + dotest basic2-28 "${testcvs} export -rrtagged-by-revision -d export-dir first-dir" \ +"${PROG} [a-z]*: Updating export-dir +U export-dir/file14 +U export-dir/file6 +U export-dir/file7 +${PROG} [a-z]*: 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 +U export-dir/dir1/dir2/file14 +U export-dir/dir1/dir2/file6 +U export-dir/dir1/dir2/file7" + + dotest basic2-29 "${testcvs} co -r1.1 first-dir" \ +"${PROG} [a-z]*: Updating first-dir +U first-dir/file14 +U first-dir/file6 +U first-dir/file7 +${PROG} [a-z]*: 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 +U first-dir/dir1/dir2/file14 +U first-dir/dir1/dir2/file6 +U first-dir/dir1/dir2/file7" # directory copies are done in an oblique way in order to avoid a bug in sun's tmp filesystem. mkdir first-dir.cpy ; (cd first-dir ; tar cf - . | (cd ../first-dir.cpy ; tar xf -)) - directory_cmp first-dir export-dir - - if $ISDIFF ; then - fail 55 - else - pass 55 - fi + dotest basic2-30 "directory_cmp first-dir export-dir" # interrupt, while we've got a clean 1.1 here, let's import it # into a couple of other modules. cd export-dir - dotest_sort 56 "${testcvs} import -m first-import second-dir first-immigration immigration1 immigration1_0" \ + dotest_sort basic2-31 "${testcvs} import -m first-import second-dir first-immigration immigration1 immigration1_0" \ " N second-dir/dir1/dir2/file14 @@ -2075,23 +3355,25 @@ N second-dir/file14 N second-dir/file6 N second-dir/file7 No conflicts created by this import -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/second-dir/dir1 -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/second-dir/dir1/dir2" +${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/second-dir/dir1 +${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/second-dir/dir1/dir2" cd .. - if ${CVS} export -r HEAD second-dir ; then - pass 57 - else - fail 57 - fi - - directory_cmp first-dir second-dir - - if $ISDIFF ; then - fail 58 - else - pass 58 - fi + dotest basic2-32 "${testcvs} export -r HEAD second-dir" \ +"${PROG} [a-z]*: Updating second-dir +U second-dir/file14 +U second-dir/file6 +U second-dir/file7 +${PROG} [a-z]*: 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 +U second-dir/dir1/dir2/file14 +U second-dir/dir1/dir2/file6 +U second-dir/dir1/dir2/file7" + + dotest basic2-33 "directory_cmp first-dir second-dir" rm -r second-dir @@ -2101,49 +3383,39 @@ ${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/second-dir/dir1/dir2" # update the top, cancelling sticky tags, retag, update other copy, compare. cd first-dir - if ${CVS} update -A -l *file* 2>> ${LOGFILE}; then - pass 59 - else - fail 59 - fi + dotest basic2-34 "${testcvs} update -A -l *file*" \ +"[UP] file6 +${PROG} [a-z]*: 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. - if ${CVS} tag -l -d rtagged-by-revision ; then - pass 60a - else - fail 60a - fi - if ${CVS} tag -l rtagged-by-revision ; then - pass 60b - else - fail 60b - fi + dotest basic2-35 "${testcvs} tag -l -d rtagged-by-revision" \ +"${PROG} [a-z]*: Untagging \. +D file14 +D file6" + dotest basic2-36 "${testcvs} tag -l rtagged-by-revision" \ +"${PROG} [a-z]*: Tagging \. +T file14 +T file6" cd .. mv first-dir 1dir mv first-dir.cpy first-dir cd first-dir - dotest 61 "${testcvs} -q diff -u" '' + dotest basic2-37 "${testcvs} -q diff -u" '' - if ${CVS} update ; then - pass 62 - else - fail 62 - fi + dotest basic2-38 "${testcvs} update" \ +"${PROG} [a-z]*: Updating . +${PROG} [a-z]*: Updating dir1 +${PROG} [a-z]*: Updating dir1/dir2" cd .. #### FIXME: is this expected to work??? Need to investigate #### and fix or remove the test. -# directory_cmp 1dir first-dir -# -# if $ISDIFF ; then -# fail 63 -# else -# pass 63 -# fi +# dotest basic2-39 "directory_cmp 1dir first-dir" + rm -r 1dir first-dir # Test the cvs history command. @@ -2158,29 +3430,29 @@ ${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/second-dir/dir1/dir2" # which don't exist in the remote output? would seem to be # a CVS bug. dotest basic2-64 "${testcvs} his -x TOFWUCGMAR -a" \ -"O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= ${TMPPWD}/\* -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == ${TMPPWD} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == ${TMPPWD} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1 == ${TMPPWD} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1 == ${TMPPWD} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1/dir2 == ${TMPPWD} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1/dir2 == ${TMPPWD} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir == ${TMPPWD} -M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TMPPWD} -R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == ${TMPPWD} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1 == ${TMPPWD} -M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1 == ${TMPPWD} -R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1 == ${TMPPWD} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1/dir2 == ${TMPPWD} -M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1/dir2 == ${TMPPWD} -R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1/dir2 == ${TMPPWD} -F [0-9-]* [0-9:]* ${PLUS}0000 ${username} =first-dir= ${TMPPWD}/\* +"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} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1 == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1 == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1/dir2 == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1/dir2 == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir == ${TESTDIR} +M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TESTDIR} +R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1 == ${TESTDIR} +M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1 == ${TESTDIR} +R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1 == ${TESTDIR} +A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1/dir2 == ${TESTDIR} +M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1/dir2 == ${TESTDIR} +R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1/dir2 == ${TESTDIR} +F [0-9-]* [0-9:]* ${PLUS}0000 ${username} =first-dir= ${TESTDIR}/\* 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= ${TMPPWD}/\* -U [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TMPPWD}/first-dir -U [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == ${TMPPWD}/first-dir" \ +O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= ${TESTDIR}/\* +U [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TESTDIR}/first-dir +W [0-9-]* [0-9:]* ${PLUS}0000 ${username} file7 first-dir == ${TESTDIR}/first-dir" \ "O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= /\* A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == @@ -2201,7 +3473,8 @@ F [0-9-]* [0-9:]* ${PLUS}0000 ${username} =first-dir= /\*" +O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= /\* +W [0-9-]* [0-9:]* ${PLUS}0000 ${username} file7 first-dir == " \ rm -rf ${CVSROOT_DIRNAME}/first-dir rm -rf ${CVSROOT_DIRNAME}/second-dir @@ -2219,24 +3492,24 @@ O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-di dotest files-1 "${testcvs} -q co -l ." "" mkdir first-dir dotest files-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest files-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/tfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v done Checking in tfile; -${TESTDIR}/cvsroot/first-dir/tfile,v <-- tfile +${CVSROOT_DIRNAME}/first-dir/tfile,v <-- tfile initial revision: 1\.1 done" dotest files-5 "${testcvs} -q tag -b C" "T tfile" dotest files-6 "${testcvs} -q update -r C" "" mkdir dir dotest files-7 "${testcvs} add dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir added to the repository +"Directory ${CVSROOT_DIRNAME}/first-dir/dir added to the repository --> Using per-directory sticky tag .C'" cd dir touch .file @@ -2245,12 +3518,12 @@ done" ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" mkdir sdir dotest files-7 "${testcvs} add sdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir/sdir added to the repository +"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir added to the repository --> Using per-directory sticky tag .C'" cd sdir mkdir ssdir dotest files-8 "${testcvs} add ssdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir added to the repository +"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir added to the repository --> Using per-directory sticky tag .C'" cd ssdir touch .file @@ -2259,29 +3532,29 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" cd ../.. dotest files-10 "${testcvs} -q ci -m test" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/dir/Attic/\.file,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v done Checking in \.file; -${TESTDIR}/cvsroot/first-dir/dir/Attic/\.file,v <-- \.file +${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file new revision: 1\.1\.2\.1; previous revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir/Attic/\.file,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v done Checking in sdir/ssdir/\.file; -${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file +${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file new revision: 1\.1\.2\.1; previous revision: 1\.1 done" dotest files-11 \ "${testcvs} commit -m test -f ./.file ./sdir/ssdir/.file" \ "Checking in \.file; -${TESTDIR}/cvsroot/first-dir/dir/Attic/\.file,v <-- \.file +${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 done Checking in \./sdir/ssdir/\.file; -${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file +${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 done" - if test "$remote" = yes; then + if $remote; then # This is a bug, looks like that toplevel_repos cruft in # client.c is coming back to haunt us. # May want to think about the whole issue, toplevel_repos @@ -2298,32 +3571,32 @@ ${PROG} \[server aborted\]: correct above errors first!" dotest files-12-workaround \ "${testcvs} commit -f -m test sdir/ssdir/.file .file" \ "Checking in sdir/ssdir/\.file; -${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file +${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2 done Checking in \.file; -${TESTDIR}/cvsroot/first-dir/dir/Attic/\.file,v <-- \.file +${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2 done" else dotest files-12 \ "${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \ "Checking in \./sdir/ssdir/\.file; -${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file +${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2 done Checking in \.file; -${TESTDIR}/cvsroot/first-dir/dir/Attic/\.file,v <-- \.file +${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2 done" fi dotest files-13 \ "${testcvs} commit -fmtest ./sdir/../sdir/ssdir/..///ssdir/.file" \ "Checking in \./sdir/\.\./sdir/ssdir/\.\.///ssdir/\.file; -${TESTDIR}/cvsroot/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file +${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 test "$remote" = yes; then + if $remote; then dotest_fail files-14 \ "${testcvs} commit -fmtest ../../first-dir/dir/.file" \ "protocol error: .\.\./\.\./first-dir/dir' has too many \.\." @@ -2331,7 +3604,7 @@ done" dotest files-14 \ "${testcvs} commit -fmtest ../../first-dir/dir/.file" \ "Checking in \.\./\.\./first-dir/dir/\.file; -${TESTDIR}/cvsroot/first-dir/dir/Attic/\.file,v <-- \.file +${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3 done" fi @@ -2350,7 +3623,7 @@ done" # 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 test "$remote" = yes; then + if $remote; then dashb=dashb dashc=dashc else @@ -2366,34 +3639,34 @@ done" ${PROG} [a-z]*: scheduling file .top. for addition ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest spacefiles-3 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/${dashc},v +"RCS file: ${CVSROOT_DIRNAME}/${dashc},v done Checking in ${dashc}; -${TESTDIR}/cvsroot/${dashc},v <-- ${dashc} +${CVSROOT_DIRNAME}/${dashc},v <-- ${dashc} initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/top,v +RCS file: ${CVSROOT_DIRNAME}/top,v done Checking in top; -${TESTDIR}/cvsroot/top,v <-- top +${CVSROOT_DIRNAME}/top,v <-- top initial revision: 1\.1 done" mkdir 'first dir' dotest spacefiles-4 "${testcvs} add 'first dir'" \ -"Directory ${TESTDIR}/cvsroot/first dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first dir added to the repository" mkdir ./${dashb} dotest spacefiles-5 "${testcvs} add -- ${dashb}" \ -"Directory ${TESTDIR}/cvsroot/${dashb} added to the repository" +"Directory ${CVSROOT_DIRNAME}/${dashb} 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" dotest spacefiles-7 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first dir/a file,v +"RCS file: ${CVSROOT_DIRNAME}/first dir/a file,v done Checking in a file; -${TESTDIR}/cvsroot/first dir/a file,v <-- a file +${CVSROOT_DIRNAME}/first dir/a file,v <-- a file initial revision: 1\.1 done" dotest spacefiles-8 "${testcvs} -q tag new-tag" "T a file" @@ -2443,10 +3716,10 @@ done" "${PROG} [a-z]*: scheduling file .$file. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest commit-readonly-4 "$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" @@ -2456,7 +3729,7 @@ done" dotest commit-readonly-5 "$testcvs -Q ci -m . $file" \ "Checking in $file; -${TESTDIR}/cvsroot/$module/$file,v <-- $file +${CVSROOT_DIRNAME}/$module/$file,v <-- $file new revision: 1\.2; previous revision: 1\.1 done" @@ -2494,7 +3767,7 @@ U trdiff/foo" dotest rdiff-3 \ "${testcvs} ci -m added-something foo" \ "Checking in foo; -${TESTDIR}/cvsroot/trdiff/foo,v <-- foo +${CVSROOT_DIRNAME}/trdiff/foo,v <-- foo new revision: 1\.2; previous revision: 1\.1 done" echo '#ident "@(#)trdiff:$''Name$:$''Id$"' > new @@ -2505,10 +3778,10 @@ done" ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest rdiff-5 \ "${testcvs} commit -m added-new-file new" \ -"RCS file: ${TESTDIR}/cvsroot/trdiff/new,v +"RCS file: ${CVSROOT_DIRNAME}/trdiff/new,v done Checking in new; -${TESTDIR}/cvsroot/trdiff/new,v <-- new +${CVSROOT_DIRNAME}/trdiff/new,v <-- new initial revision: 1\.1 done" dotest rdiff-6 \ @@ -2523,7 +3796,7 @@ T new" File: foo Status: Up-to-date Working revision: 1\.2.* - Repository revision: 1\.2 ${TESTDIR}/cvsroot/trdiff/foo,v + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/trdiff/foo,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -ko @@ -2561,11 +3834,10 @@ diff -c /dev/null trdiff/new:1\.1 '"${PLUS}"' #ident "@(#)trdiff:\$''Name: local-v0 \$:\$''Id: new,v 1\.1 [0-9/]* [0-9:]* '"${username}"' Exp \$" '"${PLUS}"' new file' -# FIXME: will this work here? -# if test "$keep" = yes; then -# echo Keeping ${TESTDIR} and exiting due to --keep -# exit 0 -# fi + if $keep; then + echo Keeping ${TESTDIR} and exiting due to --keep + exit 0 + fi cd .. rm -r testimport @@ -2583,7 +3855,7 @@ diff -c /dev/null trdiff/new:1\.1 dotest diff-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest diff-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir # diff is anomalous. Most CVS commands print the "nothing @@ -2596,16 +3868,16 @@ diff -c /dev/null trdiff/new:1\.1 "${PROG} [a-z]*: scheduling file .abc. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest diff-5 "${testcvs} -q ci -mtest" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/abc,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v done Checking in abc; -${TESTDIR}/cvsroot/first-dir/abc,v <-- abc +${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc initial revision: 1\.1 done" echo "extern int gethostname ();" >abc dotest diff-6 "${testcvs} -q ci -mtest" \ "Checking in abc; -${TESTDIR}/cvsroot/first-dir/abc,v <-- abc +${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc new revision: 1\.2; previous revision: 1\.1 done" echo "#include " >abc @@ -2613,7 +3885,7 @@ done" dotest_fail diff-7 "${testcvs} -q diff --ifdef=HAVE_WINSOCK_H" \ "Index: abc =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/abc,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v retrieving revision 1\.2 diff --ifdef=HAVE_WINSOCK_H -r1\.2 abc #ifndef HAVE_WINSOCK_H @@ -2622,7 +3894,7 @@ extern int gethostname (); #include #endif /\* HAVE_WINSOCK_H \*/" - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -2653,17 +3925,17 @@ extern int gethostname (); # doesn't get confused by it. mkdir subdir dotest 65a0 "${testcvs} add subdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/subdir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" 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' dotest 65a2 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/sfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v done Checking in sfile; -${TESTDIR}/cvsroot/first-dir/subdir/sfile,v <-- sfile +${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v <-- sfile initial revision: 1\.1 done" rm sfile @@ -2672,7 +3944,7 @@ done" '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove this file permanently' dotest 65a4 "${testcvs} -q ci -m remove-it" \ "Removing sfile; -${TESTDIR}/cvsroot/first-dir/subdir/sfile,v <-- sfile +${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v <-- sfile new revision: delete; previous revision: 1\.1 done" cd .. @@ -2746,10 +4018,10 @@ done" "${PROG}"' [a-z]*: scheduling file `file4'\'' for addition '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest death-file4-ciadd "${testcvs} -q ci -m add file4" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file4,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v done Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 initial revision: 1\.1 done" rm file4 @@ -2758,7 +4030,7 @@ done" '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove this file permanently' dotest death-file4-cirm "${testcvs} -q ci -m remove file4" \ "Removing file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: delete; previous revision: 1\.1 done" @@ -2890,7 +4162,7 @@ diff -c first-dir/file3:1\.1\.2\.1 first-dir/file3:removed # join dotest 86 "${testcvs} -q update -j branch1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.3 retrieving revision 1\.3\.2\.1 Merging differences between 1\.3 and 1\.3\.2\.1 into file1 @@ -2922,15 +4194,15 @@ U file3" # commit dotest 89 "${testcvs} -q ci -m test" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.4; previous revision: 1\.3 done Removing file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: delete; previous revision: 1\.1 done Checking in file3; -${TESTDIR}/cvsroot/first-dir/file3,v <-- file3 +${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 new revision: 1\.2; previous revision: 1\.1 done" cd .. @@ -3026,16 +4298,16 @@ U first-dir/file3' '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add these files permanently' dotest death2-3 "${testcvs} -q commit -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file4,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v done Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 initial revision: 1\.1 done" @@ -3068,8 +4340,8 @@ ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" =================================================================== RCS file: file1 diff -N file1 -\*\*\* ${tempname}[ ][ ]*[a-zA-Z0-9: ]* ---- /dev/null[ ][ ]*[a-zA-Z0-9: ]* +\*\*\* file1 ${RFCDATE} [0-9.]* +--- /dev/null ${RFCDATE_EPOCH} \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1 \*\*\*\* - first revision @@ -3077,7 +4349,7 @@ diff -N file1 dotest death2-8 "${testcvs} -q ci -m removed" \ "Removing file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: delete; previous revision: 1\.1\.2 done" @@ -3092,8 +4364,8 @@ done" =================================================================== RCS file: file1 diff -N file1 -\*\*\* ${tempname}[ ][ ]*[a-zA-Z0-9: ]* ---- /dev/null[ ][ ]*[a-zA-Z0-9: ]* +\*\*\* file1 ${RFCDATE} [0-9.]* +--- /dev/null ${RFCDATE_EPOCH} \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1 \*\*\*\* - first revision @@ -3107,8 +4379,8 @@ diff -N file1 =================================================================== RCS file: file1 diff -N file1 -\*\*\* ${tempname}[ ][ ]*[a-zA-Z0-9: ]* ---- /dev/null[ ][ ]*[a-zA-Z0-9: ]* +\*\*\* file1 [-a-zA-Z0-9: ]* [0-9.]* +--- /dev/null ${RFCDATE_EPOCH} \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1 \*\*\*\* - first revision @@ -3121,8 +4393,8 @@ diff -N file1 dotest death2-rdiff-2 "${testcvs} -q rdiff -rtag -rbranch first-dir" \ "Index: first-dir/file1 diff -c first-dir/file1:1\.1 first-dir/file1:removed -\*\*\* first-dir/file1:1\.1[ ][ ]*[a-zA-Z0-9: ]* ---- first-dir/file1[ ][ ]*[a-zA-Z0-9: ]* +\*\*\* first-dir/file1:1\.1 [a-zA-Z0-9: ]* +--- first-dir/file1 [a-zA-Z0-9: ]* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1 \*\*\*\* - first revision @@ -3143,8 +4415,8 @@ diff -c first-dir/file1:1\.1 first-dir/file1:removed =================================================================== RCS file: file1 diff -N file1 -\*\*\* /dev/null[ ][ ]*[a-zA-Z0-9: ]* ---- ${tempname}[ ][ ]*[a-zA-Z0-9: ]* +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file1 ${RFCDATE} \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 0 \*\*\*\* --- 1 ---- @@ -3152,7 +4424,7 @@ ${PLUS} second revision" dotest death2-10 "${testcvs} -q commit -m add" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 done" @@ -3162,7 +4434,7 @@ done" ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" dotest death2-10b "${testcvs} -q ci -m removed" \ "Removing file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: delete; previous revision: 1\.1\.2 done" @@ -3177,10 +4449,10 @@ U file4" "${PROG}"' [a-z]*: scheduling file `file2'\'' for addition '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest death2-13 "${testcvs} -q commit -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done" @@ -3188,7 +4460,7 @@ done" echo "new file4 revision" > file4 dotest death2-13a "${testcvs} -q commit -m mod" \ "Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: 1\.2; previous revision: 1\.1 done" @@ -3199,7 +4471,7 @@ done" dotest death2-14 "${testcvs} -q update -r branch" \ "[UP] file1 ${PROG} [a-z]*: file2 is no longer in the repository -${PROG} [a-z]*: warning: file4 is not (any longer) pertinent" +${PROG} [a-z]*: file4 is no longer in the repository" # Add a file on the branch with the same name. echo "branch revision" > file2 @@ -3208,7 +4480,7 @@ ${PROG} [a-z]*: warning: file4 is not (any longer) pertinent" '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest death2-16 "${testcvs} -q commit -m add" \ "Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" @@ -3218,10 +4490,10 @@ done" "${PROG}"' [a-z]*: scheduling file `file3'\'' for addition on branch `branch'\'' '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest death2-18 "${testcvs} -q commit -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/file3,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v done Checking in file3; -${TESTDIR}/cvsroot/first-dir/Attic/file3,v <-- file3 +${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" @@ -3234,8 +4506,8 @@ done" =================================================================== RCS file: file3 diff -N file3 -\*\*\* /dev/null[ ][ ]*[a-zA-Z0-9: ]* ---- ${tempname}[ ][ ]*[a-zA-Z0-9: ]* +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file3 ${RFCDATE} [0-9.]* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 0 \*\*\*\* --- 1 ---- @@ -3244,12 +4516,12 @@ ${PLUS} first revision" dotest_fail death2-diff-11 "${testcvs} -q diff -rtag -c ." \ "Index: file1 =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.1 retrieving revision 1\.1\.2\.2 diff -c -r1\.1 -r1\.1\.2\.2 -\*\*\* file1[ ][ ]*[a-zA-Z0-9:./ ]* ---- file1[ ][ ]*[a-zA-Z0-9:./ ]* +\*\*\* file1 ${RFCDATE} [0-9.]* +--- file1 ${RFCDATE} [0-9.]* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1 \*\*\*\* ! first revision @@ -3262,12 +4534,12 @@ ${PROG} [a-z]*: file4 no longer exists, no comparison available" dotest_fail death2-diff-12 "${testcvs} -q diff -rtag -c -N ." \ "Index: file1 =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.1 retrieving revision 1\.1\.2\.2 diff -c -r1\.1 -r1\.1\.2\.2 -\*\*\* file1[ ][ ]*[a-zA-Z0-9:./ ]* ---- file1[ ][ ]*[a-zA-Z0-9:./ ]* +\*\*\* file1 ${RFCDATE} [0-9.]* +--- file1 ${RFCDATE} [0-9.]* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1 \*\*\*\* ! first revision @@ -3277,8 +4549,8 @@ Index: file2 =================================================================== RCS file: file2 diff -N file2 -\*\*\* /dev/null[ ][ ]*[a-zA-Z0-9: ]* ---- ${tempname}[ ][ ]*[a-zA-Z0-9: ]* +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file2 ${RFCDATE} [0-9.]* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 0 \*\*\*\* --- 1 ---- @@ -3287,8 +4559,8 @@ Index: file3 =================================================================== RCS file: file3 diff -N file3 -\*\*\* /dev/null[ ][ ]*[a-zA-Z0-9: ]* ---- ${tempname}[ ][ ]*[a-zA-Z0-9: ]* +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file3 ${RFCDATE} [0-9.]* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 0 \*\*\*\* --- 1 ---- @@ -3297,8 +4569,8 @@ Index: file4 =================================================================== RCS file: file4 diff -N file4 -\*\*\* ${tempname}[ ][ ]*[a-zA-Z0-9: ]* ---- /dev/null[ ][ ]*[a-zA-Z0-9: ]* +\*\*\* file4 ${RFCDATE} [0-9.]* +--- /dev/null ${RFCDATE_EPOCH} \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1 \*\*\*\* - file4 first revision @@ -3322,16 +4594,78 @@ U file4" =================================================================== RCS file: file1 diff -N file1 -\*\*\* /dev/null[ ][ ]*[a-zA-Z0-9: ]* ---- ${tempname}[ ][ ]*[a-zA-Z0-9: ]* +\*\*\* /dev/null ${RFCDATE_EPOCH} +--- file1 ${RFCDATE} [0-9.]* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 0 \*\*\*\* --- 1 ---- ${PLUS} first revision" + # now back to the trunk + dotest death2-21 "${testcvs} -q update -A" \ +"U file2 +[UP] file4" + + # test merging with a dead file + dotest death2-22 "${testcvs} -q co first-dir" \ +"U first-dir/file1 +U first-dir/file2 +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" + dotest death2-24 "${testcvs} -q ci -m removed file4" \ +"Removing file4; +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 +new revision: delete; previous revision: 1\.2 +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 +C file4" + cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir ;; + rm-update-message) + # FIXME + # local CVS prints a warning message when update notices a missing + # file and client/server CVS doesn't. These should be identical. + mkdir rm-update-message; cd rm-update-message + mkdir $CVSROOT_DIRNAME/rm-update-message + dotest rm-update-message-setup-1 "$testcvs -q co rm-update-message" '' + cd rm-update-message + file=x + echo >$file + dotest rm-update-message-setup-2 "$testcvs -q add $file" \ +"$PROG [a-z]*: use .cvs commit. to add this file permanently" + dotest rm-update-message-setup-3 "$testcvs -q ci -mcreate $file" \ +"RCS file: $CVSROOT_DIRNAME/rm-update-message/$file,v +done +Checking in $file; +$CVSROOT_DIRNAME/rm-update-message/$file,v <-- $file +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 +U $file" + fi + + cd ../.. + if $keep; then :; else + rm -rf rm-update-message + rm -rf $CVSROOT_DIRNAME/rm-update-message + fi + ;; + rmadd) # More tests of adding and removing files. # In particular ci -r. @@ -3345,7 +4679,7 @@ ${PLUS} first revision" dotest rmadd-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest rmadd-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir echo first file1 >file1 dotest rmadd-3 "${testcvs} add file1" \ @@ -3365,13 +4699,13 @@ ${PROG} \[[a-z]* aborted\]: correct above errors first!" # bizarre behavior, but it would seem to be intentional # (see commit.c). It probably could go away.... dotest rmadd-7 "${testcvs} -q ci -r 7.... -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 7\.1 done" - if test "$remote" = yes; then + if $remote; then # I guess remote doesn't set a sticky tag in this case. # Kind of odd, in the sense that rmadd-24a does set one # both local and remote. @@ -3395,10 +4729,10 @@ done" ${PROG} [a-z]*: 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: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 7\.1 done" @@ -3413,10 +4747,10 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" ${PROG} \[[a-z]* 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: ${TESTDIR}/cvsroot/first-dir/Attic/file3,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v done Checking in file3; -${TESTDIR}/cvsroot/first-dir/Attic/file3,v <-- file3 +${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" @@ -3445,10 +4779,10 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" # a non-branch tag. dotest rmadd-21 \ "${testcvs} -q ci -r mynonbranch -m add file4" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/file4,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file4,v done Checking in file4; -${TESTDIR}/cvsroot/first-dir/Attic/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/Attic/file4,v <-- file4 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" @@ -3458,42 +4792,42 @@ done" 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" - if test "$remote" = yes; then + if $remote; then # Interesting bug (or missing feature) here. findmaxrev # gets the major revision from the Entries. Well, remote # doesn't send the entries for files which are not involved. - dotest rmadd-23 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file5,v + dotest rmadd-23r "${testcvs} -q ci -m add" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file5,v done Checking in file5; -${TESTDIR}/cvsroot/first-dir/file5,v <-- file5 +${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 initial revision: 1\.1 done" - dotest rmadd-23-workaround \ + dotest rmadd-23-workaroundr \ "${testcvs} -q ci -r 7 -m bump-it file5" \ "Checking in file5; -${TESTDIR}/cvsroot/first-dir/file5,v <-- file5 +${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 new revision: 7\.1; previous revision: 1\.1 done" else dotest rmadd-23 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file5,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file5,v done Checking in file5; -${TESTDIR}/cvsroot/first-dir/file5,v <-- file5 +${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 initial revision: 7\.1 done" fi echo change it >file5 dotest_fail rmadd-24 "${testcvs} -q ci -r 4.8 -m change file5" \ "Checking in file5; -${TESTDIR}/cvsroot/first-dir/file5,v <-- file5 -${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/file5,v: revision 4\.8 too low; must be higher than 7\.1 +${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 +${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/file5,v: revision 4\.8 too low; must be higher than 7\.1 ${PROG} [a-z]*: could not check in file5 7\.1 unlocked" dotest rmadd-24a "${testcvs} -q ci -r 8.4 -m change file5" \ "Checking in file5; -${TESTDIR}/cvsroot/first-dir/file5,v <-- file5 +${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 new revision: 8\.4; previous revision: 7\.1 done" # I'm not really sure that a sticky tag make sense here. @@ -3503,7 +4837,7 @@ done" File: file5 Status: Up-to-date Working revision: 8\.4.* - Repository revision: 8\.4 ${TESTDIR}/cvsroot/first-dir/file5,v + Repository revision: 8\.4 ${CVSROOT_DIRNAME}/first-dir/file5,v Sticky Tag: 8\.4 Sticky Date: (none) Sticky Options: (none)" @@ -3520,17 +4854,17 @@ File: file5 Status: Up-to-date dotest rmadd2-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest rmadd2-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest rmadd2-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" dotest rmadd2-4a "${testcvs} -Q tag tagone" "" @@ -3539,29 +4873,29 @@ done" ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" dotest rmadd2-6 "${testcvs} -q ci -m remove" \ "Removing file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: delete; previous revision: 1\.1 done" dotest rmadd2-7 "${testcvs} -q update -j 1.2 -j 1.1 file1" "U file1" dotest rmadd2-8 "${testcvs} -q ci -m readd" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.3; previous revision: 1\.2 done" echo 'new contents' >file1 dotest rmadd2-9 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.4; previous revision: 1\.3 done" dotest rmadd2-10 "${testcvs} -q update -j 1.4 -j 1.3 file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.4 retrieving revision 1\.3 Merging differences between 1\.4 and 1\.3 into file1" dotest rmadd2-11 "${testcvs} -q ci -m undo" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.5; previous revision: 1\.4 done" dotest rmadd2-12 "cat file1" "initial contents" @@ -3571,13 +4905,19 @@ done" # the head. dotest rmadd2-14 "${testcvs} -q update -j 1.3 -j 1.2 file1" \ "${PROG} [a-z]*: scheduling file1 for removal" + + # Check that -p can get arbitrary revisions of a removed file + dotest rmadd2-14a "${testcvs} -q update -p" "initial contents" + dotest rmadd2-14b "${testcvs} -q update -p -r 1.5" "initial contents" + dotest rmadd2-14c "${testcvs} -q update -p -r 1.3" "initial contents" + dotest rmadd2-15 "${testcvs} -q ci -m re-remove" \ "Removing file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: delete; previous revision: 1\.5 done" dotest rmadd2-16 "${testcvs} log -h file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v Working file: file1 head: 1\.6 branch: @@ -3593,7 +4933,7 @@ total revisions: 6 File: no file file1 Status: Up-to-date Working revision: No entry for file1 - Repository revision: 1\.6 ${TESTDIR}/cvsroot/first-dir/Attic/file1,v + Repository revision: 1\.6 ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v Existing Tags: tagone (revision: 1.1)" @@ -3601,7 +4941,7 @@ File: no file file1 Status: Up-to-date cd ../.. rm -r 1 - rm -rf ${TESTDIR}/cvsroot/first-dir + rm -rf ${CVSROOT_DIRNAME}/first-dir ;; dirs) @@ -3625,7 +4965,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 ${TESTDIR}/cvsroot/dir1/sdir" +${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/dir1/sdir" cd .. mkdir 1; cd 1 @@ -3642,12 +4982,12 @@ ${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/dir1/sdir" dotest dirs-3 "${testcvs} update" \ "${PROG} [a-z]*: Updating dir1 ${PROG} [a-z]*: Updating dir1/sdir -${PROG} [a-z]*: cannot open directory ${TESTDIR}/cvsroot/dir1/sdir: No such file or directory +${PROG} [a-z]*: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory ${PROG} [a-z]*: 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 ${TESTDIR}/cvsroot/dir1/sdir: No such file or directory +${PROG} [a-z]*: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory ${PROG} [a-z]*: skipping directory dir1/sdir" # If we say "yes", then CVS gives errors about not being able to @@ -3655,7 +4995,7 @@ ${PROG} [a-z]*: skipping directory dir1/sdir" # 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 ${TESTDIR}/cvsroot/dir1/sdir: No such file or directory +"${PROG} [a-z]*: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory ${PROG} [a-z]*: 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." @@ -3688,47 +5028,40 @@ D/sdir////" dotest dirs2-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest dirs2-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir mkdir sdir dotest dirs2-3 "${testcvs} add sdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/sdir added to the repository" +"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" dotest dirs2-5 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/file1,v done Checking in sdir/file1; -${TESTDIR}/cvsroot/first-dir/sdir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/sdir/file1,v <-- file1 initial revision: 1\.1 done" rm -r sdir/CVS - if test "$remote" = yes; then + if $remote; then # This is just like conflicts3-23 dotest_fail dirs2-6 "${testcvs} update -d" \ "${QUESTION} sdir ${PROG} server: Updating \. -${PROG} update: in directory sdir: -${PROG} update: cannot open CVS/Entries for reading: No such file or directory ${PROG} server: Updating sdir ${PROG} update: move away sdir/file1; it is in the way C sdir/file1" rm sdir/file1 + rm -r sdir/CVS # This is where things are not just like conflicts3-23 - # As with conflicts3-23, all these CVS/Entries* warnings - # are somewhat doubtful, and we probably should think some - # about whether they should be changed/fixed. dotest dirs2-7 "${testcvs} update -d" \ "${QUESTION} sdir ${PROG} server: Updating \. -${PROG} update: in directory sdir: -${PROG} update: cannot open CVS/Entries for reading: No such file or directory ${PROG} server: Updating sdir -U sdir/file1 -${PROG} update: cannot open CVS/Entries.Log: No such file or directory" +U sdir/file1" else dotest dirs2-6 "${testcvs} update -d" \ "${PROG} update: Updating \. @@ -3746,7 +5079,7 @@ ${QUESTION} sdir" cd first-dir dotest dirs2-9 "${testcvs} -q tag -b br" "T sdir/file1" rm -r sdir/CVS - if test "$remote" = yes; then + if $remote; then # Cute little quirk of val-tags; if we don't recurse into # the directories where the tag is defined, val-tags won't # get updated. @@ -3759,14 +5092,9 @@ ${PROG} \[server aborted\]: no such tag br" dotest_fail dirs2-10-again "${testcvs} update -d -r br" \ "${QUESTION} sdir ${PROG} server: Updating \. -${PROG} update: in directory sdir: -${PROG} update: cannot open CVS/Entries for reading: No such file or directory -${PROG} update: cannot open CVS/Tag: No such file or directory -${PROG} update: cannot open CVS/Tag: No such file or directory ${PROG} server: Updating sdir ${PROG} update: move away sdir/file1; it is in the way -C sdir/file1 -${PROG} update: cannot open CVS/Tag: No such file or directory" +C sdir/file1" else dotest_fail dirs2-10 "${testcvs} update -d -r br" \ "${PROG} update: in directory sdir: @@ -3790,20 +5118,15 @@ ${PROG} \[update aborted\]: there is no version here; do '${PROG} checkout' firs ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" dotest dirs2-13 "${testcvs} -q ci -m remove" \ "Removing sdir/file1; -${TESTDIR}/cvsroot/first-dir/sdir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/sdir/file1,v <-- file1 new revision: delete; previous revision: 1\.1\.2 done" cd ../../2/first-dir - if test "$remote" = yes; then + if $remote; then dotest dirs2-14 "${testcvs} update -d -r br" \ -"${QUESTION} sdir +"${QUESTION} sdir/file1 ${PROG} server: Updating \. -${PROG} update: in directory sdir: -${PROG} update: cannot open CVS/Entries for reading: No such file or directory -${PROG} update: cannot open CVS/Tag: No such file or directory -${PROG} update: cannot open CVS/Tag: No such file or directory -${PROG} server: Updating sdir -${PROG} update: cannot open CVS/Tag: No such file or directory" +${PROG} server: Updating sdir" else dotest dirs2-14 "${testcvs} update -d -r br" \ "${PROG} update: Updating \. @@ -3812,7 +5135,7 @@ ${QUESTION} sdir" cd ../.. rm -r 1 2 3 - rm -rf ${TESTDIR}/cvsroot/first-dir + rm -rf ${CVSROOT_DIRNAME}/first-dir ;; branches) @@ -3832,35 +5155,35 @@ ${QUESTION} sdir" '"${PROG}"' [a-z]*: 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" <file4 dotest branches-3.2 "${testcvs} -q ci -m trunk-before-branch" \ "Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: 1\.2; previous revision: 1\.1 done" # The "cvs log file4" in test branches-14.3 will test that we @@ -3886,15 +5209,15 @@ M file1" echo 4:br1 >file4 dotest branches-6 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: 1\.2\.2\.1; previous revision: 1\.2 done" dotest branches-7 "${testcvs} -q tag -b brbr" 'T file1 @@ -3906,11 +5229,11 @@ T file4' echo 4:brbr >file4 dotest branches-9 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1\.2\.1; previous revision: 1\.1\.2\.1 done Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: 1\.2\.2\.1\.2\.1; previous revision: 1\.2\.2\.1 done" dotest branches-10 "cat file1 file2 file3 file4" '1:brbr @@ -3927,7 +5250,7 @@ done" echo 4:br1-2 >file4 dotest branches-12.2 "${testcvs} -q ci -m change-on-br1" \ "Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1 done" dotest branches-13 "${testcvs} -q update -A" '[UP] file1 @@ -3941,12 +5264,12 @@ done" dotest branches-14.2 \ "${testcvs} -q ci -m trunk-change-after-branch" \ "Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: 1\.3; previous revision: 1\.2 done" dotest branches-14.3 "${testcvs} log file4" \ " -RCS file: ${TESTDIR}/cvsroot/first-dir/file4,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v Working file: file4 head: 1\.3 branch: @@ -3989,12 +5312,12 @@ modify "${testcvs} diff -c -r 1.1 -r 1.3 file4" \ "Index: file4 =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/file4,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v retrieving revision 1\.1 retrieving revision 1\.3 diff -c -r1\.1 -r1\.3 -\*\*\* file4 [0-9/]* [0-9:]* 1\.1 ---- file4 [0-9/]* [0-9:]* 1\.3 +\*\*\* file4 ${RFCDATE} 1\.1 +--- file4 ${RFCDATE} 1\.3 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1 \*\*\*\* ! 4:trunk-1 @@ -4004,12 +5327,12 @@ diff -c -r1\.1 -r1\.3 "${testcvs} diff -c -r 1.1 -r 1.2.2.1 file4" \ "Index: file4 =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/file4,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v retrieving revision 1\.1 retrieving revision 1\.2\.2\.1 diff -c -r1\.1 -r1\.2\.2\.1 -\*\*\* file4 [0-9/]* [0-9:]* 1\.1 ---- file4 [0-9/]* [0-9:]* 1\.2\.2\.1 +\*\*\* file4 ${RFCDATE} 1\.1 +--- file4 ${RFCDATE} 1\.2\.2\.1 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1 \*\*\*\* ! 4:trunk-1 @@ -4017,7 +5340,7 @@ diff -c -r1\.1 -r1\.2\.2\.1 ! 4:br1" dotest branches-15 \ "${testcvs} update -j 1.1.2.1 -j 1.1.2.1.2.1 file1" \ - "RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v + "RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.1\.2\.1 retrieving revision 1\.1\.2\.1\.2\.1 Merging differences between 1\.1\.2\.1 and 1\.1\.2\.1\.2\.1 into file1 @@ -4029,17 +5352,17 @@ rcsmerge: warning: conflicts during merge" [>]>>>>>> 1\.1\.2\.1\.2\.1' dotest branches-o1 "${testcvs} -q admin -o ::brbr" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done -RCS file: ${TESTDIR}/cvsroot/first-dir/file3,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v done -RCS file: ${TESTDIR}/cvsroot/first-dir/file4,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v done" cd .. - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -4066,10 +5389,10 @@ done" "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest branches2-3 "${testcvs} commit -m add file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" @@ -4092,23 +5415,23 @@ done" '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' mkdir dir1 dotest branches2-9 "${testcvs} add dir1" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir1 added to the repository +"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' dotest branches2-11 "${testcvs} -q ci -madd ." \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/Attic/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/Attic/file2,v <-- file2 new revision: 1\.1\.2\.1; previous revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/dir1/Attic/file3,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v done Checking in dir1/file3; -${TESTDIR}/cvsroot/first-dir/dir1/Attic/file3,v <-- file3 +${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v <-- file3 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" @@ -4128,7 +5451,7 @@ U dir1/file3" File: file1 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v Sticky Tag: b2 (branch: 1\.1\.4) Sticky Date: (none) Sticky Options: (none) @@ -4137,7 +5460,7 @@ File: file1 Status: Up-to-date File: file3 Status: Up-to-date Working revision: 1\.1\.2\.1.* - Repository revision: 1\.1\.2\.1 ${TESTDIR}/cvsroot/first-dir/dir1/Attic/file3,v + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v Sticky Tag: b1 (branch: 1\.1\.2) Sticky Date: (none) Sticky Options: (none)" @@ -4159,7 +5482,7 @@ U dir1/file3" File: file1 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v Sticky Tag: b2 (branch: 1\.1\.4) Sticky Date: (none) Sticky Options: (none) @@ -4185,7 +5508,7 @@ U dir1/file3" File: file1 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) @@ -4194,7 +5517,7 @@ File: file1 Status: Up-to-date File: file3 Status: Up-to-date Working revision: 1\.1\.2\.1.* - Repository revision: 1\.1\.2\.1 ${TESTDIR}/cvsroot/first-dir/dir1/Attic/file3,v + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v Sticky Tag: b1 (branch: 1\.1\.2) Sticky Date: (none) Sticky Options: (none)" @@ -4208,7 +5531,7 @@ U dir1/file3" File: file1 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) @@ -4217,7 +5540,7 @@ File: file1 Status: Up-to-date File: file3 Status: Locally Added Working revision: New file! - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/dir1/Attic/file3,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" @@ -4243,17 +5566,17 @@ U first-dir/dir1/file3' cd first-dir mkdir dir2 dotest branches2-25 "${testcvs} add dir2" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir2 added to the repository +"Directory ${CVSROOT_DIRNAME}/first-dir/dir2 added to the repository --> 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' dotest branches2-27 "${testcvs} -q commit -madd" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/dir2/Attic/file4,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/dir2/Attic/file4,v done Checking in dir2/file4; -${TESTDIR}/cvsroot/first-dir/dir2/Attic/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/dir2/Attic/file4,v <-- file4 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" @@ -4267,7 +5590,7 @@ U dir2/file4" File: file4 Status: Up-to-date Working revision: 1\.1\.2\.1.* - Repository revision: 1\.1\.2\.1 ${TESTDIR}/cvsroot/first-dir/dir2/Attic/file4,v + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/dir2/Attic/file4,v Sticky Tag: b1 (branch: 1\.1\.2) Sticky Date: (none) Sticky Options: (none)" @@ -4288,10 +5611,10 @@ File: file4 Status: Up-to-date "${PROG}"' [a-z]*: scheduling file `file5'\'' for addition '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest branches2-35 "${testcvs} -q commit -madd" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/dir2/file5,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/dir2/file5,v done Checking in file5; -${TESTDIR}/cvsroot/first-dir/dir2/file5,v <-- file5 +${CVSROOT_DIRNAME}/first-dir/dir2/file5,v <-- file5 initial revision: 1\.1 done" @@ -4303,7 +5626,7 @@ done" File: file5 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/dir2/file5,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir2/file5,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" @@ -4320,17 +5643,17 @@ File: file5 Status: Up-to-date dotest tagc-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest tagc-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir touch file1 dotest tagc-3 "${testcvs} add file1" \ "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest tagc-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" dotest tagc-5 "${testcvs} -q tag -c tag1" "T file1" @@ -4350,16 +5673,11 @@ ${PROG} \[[a-z]* aborted\]: correct the above errors first!" cd ../1/first-dir dotest tagc-9 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" cd ../../2/first-dir - # That this is an error is a bug. Although the bug has existed - # since tag -c was created, I don't think there would be a - # compatibility problem with just fixing it. - dotest_fail tagc-10 "${testcvs} -q tag -c tag4" \ -"${PROG} [a-z]*: file1 is locally modified -${PROG} \[[a-z]* aborted\]: correct the above errors first!" + dotest tagc-10 "${testcvs} -q tag -c tag4" "T file1" cd ../.. rm -r 1 2 @@ -4375,7 +5693,7 @@ ${PROG} \[[a-z]* aborted\]: correct the above errors first!" dotest tagf-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest tagf-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir touch file1 file2 dotest tagf-3 "${testcvs} add file1 file2" \ @@ -4383,16 +5701,16 @@ ${PROG} \[[a-z]* aborted\]: correct the above errors first!" ${PROG} [a-z]*: scheduling file .file2. for addition ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest tagf-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done" @@ -4404,11 +5722,11 @@ T file2" echo brmod >> file2 dotest tagf-7 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" # Here we make it a non-branch tag. Some think this should @@ -4424,7 +5742,7 @@ T file2" File: file1 Status: Locally Modified Working revision: 1\.1\.2\.1.* - Repository revision: 1\.1\.2\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v Sticky Tag: br (revision: 1\.1\.2\.1) Sticky Date: (none) Sticky Options: (none) @@ -4441,13 +5759,13 @@ D file2" dotest tagf-11 "${testcvs} -q tag -r 1.1 -b br file1" "T file1" # Fix it with admin -n (cf admin-18, admin-26-4). dotest tagf-12 "${testcvs} -q admin -nbr:1.1.2 file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" # Another variation on the file2 test would be to use two working # directories so that the update -r br would need to # a merge to get from 1.1.2.1 to the head of the 1.1.2 branch. dotest tagf-13 "${testcvs} -q update -r br" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.1\.2\.1 retrieving revision 1\.1 Merging differences between 1\.1\.2\.1 and 1\.1 into file1 @@ -4467,11 +5785,11 @@ moremod echo resolve >file1 dotest tagf-15 "${testcvs} -q ci -m recovered" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.4\.1; previous revision: 1\.1 done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 done" cd ../.. @@ -4495,17 +5813,17 @@ done" "${PROG} [a-z]*: scheduling file .foo\.c. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest rcsdiff-3 "${testcvs} commit -m rev1 foo.c" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/foo\.c,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v done Checking in foo\.c; -${TESTDIR}/cvsroot/first-dir/foo.c,v <-- foo\.c +${CVSROOT_DIRNAME}/first-dir/foo.c,v <-- foo\.c initial revision: 1\.1 done" dotest rcsdiff-4 "${testcvs} tag first foo.c" "T foo\.c" dotest rcsdiff-5 "${testcvs} update -p -r first foo.c" \ "=================================================================== Checking out foo\.c -RCS: ${TESTDIR}/cvsroot/first-dir/foo\.c,v +RCS: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v VERS: 1\.1 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* I am the first foo, and my name is \$""Name: first \$\." @@ -4513,14 +5831,14 @@ I am the first foo, and my name is \$""Name: first \$\." echo "I am the second foo, and my name is $""Name$." > foo.c dotest rcsdiff-6 "${testcvs} commit -m rev2 foo.c" \ "Checking in foo\.c; -${TESTDIR}/cvsroot/first-dir/foo\.c,v <-- foo\.c +${CVSROOT_DIRNAME}/first-dir/foo\.c,v <-- foo\.c new revision: 1\.2; previous revision: 1\.1 done" dotest rcsdiff-7 "${testcvs} tag second foo.c" "T foo\.c" dotest rcsdiff-8 "${testcvs} update -p -r second foo.c" \ "=================================================================== Checking out foo\.c -RCS: ${TESTDIR}/cvsroot/first-dir/foo\.c,v +RCS: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v VERS: 1\.2 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* I am the second foo, and my name is \$""Name: second \$\." @@ -4529,7 +5847,7 @@ I am the second foo, and my name is \$""Name: second \$\." "${PROG} [a-z]*: Diffing \. Index: foo\.c =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/foo\.c,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v retrieving revision 1\.1 retrieving revision 1\.2 diff -r1\.1 -r1\.2 @@ -4543,7 +5861,7 @@ diff -r1\.1 -r1\.2 "${PROG} [a-z]*: Diffing \. Index: foo\.c =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/foo\.c,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v retrieving revision 1\.1 diff -r1\.1 foo\.c 1c1 @@ -4570,10 +5888,10 @@ EOF dotest rcslib-diffrgx-1 "${testcvs} -q add -m '' rgx.c" \ "${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest rcslib-diffrgx-2 "${testcvs} -q ci -m '' rgx.c" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/rgx\.c,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/rgx\.c,v done Checking in rgx\.c; -${TESTDIR}/cvsroot/first-dir/rgx\.c,v <-- rgx\.c +${CVSROOT_DIRNAME}/first-dir/rgx\.c,v <-- rgx\.c initial revision: 1\.1 done" cat >rgx.c < f; mv f file1 dotest rcslib-merge-6 "${testcvs} -q commit -m '' file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" dotest rcslib-merge-7 "${testcvs} -q tag -b -r 1.1 patch1" "T file1" @@ -4653,7 +5971,7 @@ done" File: file1 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v Sticky Tag: patch1 (branch: 1\.1\.2) Sticky Date: (none) Sticky Options: (none)" @@ -4664,12 +5982,12 @@ File: file1 Status: Up-to-date sed -e 's/3/three/' file1 > f; mv f file1 dotest rcslib-merge-11 "${testcvs} -q commit -m '' file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" dotest rcslib-merge-12 "${testcvs} -q update -kv -j1.2" \ "U file1 -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.1 retrieving revision 1\.2 Merging differences between 1\.1 and 1\.2 into file1 @@ -4691,7 +6009,7 @@ two echo "This is a change" >> file2 dotest rcslib-symlink-3 "${testcvs} ci -m because file2" \ "Checking in file2; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file2 +${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" \ @@ -4722,7 +6040,7 @@ U first-dir/file2" ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" dotest rcslib-symlink-9 "${testcvs} -q ci -m rm-it" \ "Removing file2; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file2 new revision: delete; previous revision: 1\.2 done" # OK, why this message happens twice is relatively clear @@ -4737,7 +6055,7 @@ ${PROG} [a-z]*: could not read RCS file for first-dir/file2" cd .. - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -4757,10 +6075,10 @@ ${PROG} [a-z]*: could not read RCS file for first-dir/file2" "${PROG}"' [a-z]*: scheduling file `file1'\'' for addition '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest_lit multibranch-3 "${testcvs} -q ci -m add-it" <file1 dotest multibranch-7 "${testcvs} -q ci -m modify-on-br1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" dotest multibranch-8 "${testcvs} -q update -r br2" '[UP] file1' echo br2 adds a line >>file1 dotest multibranch-9 "${testcvs} -q ci -m modify-on-br2" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.4\.1; previous revision: 1\.1 done" dotest multibranch-10 "${testcvs} -q update -r br1" '[UP] file1' @@ -4792,7 +6110,7 @@ br2 adds a line' dotest multibranch-14 "${testcvs} log file1" \ " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -4820,7 +6138,7 @@ modify-on-br1 =============================================================================" cd .. - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -4901,18 +6219,18 @@ U first-dir/imported-f4" dotest import-100 "${testcvs} ci -m local-changes" \ "${PROG} [a-z]*: Examining . Removing imported-f1; -${TESTDIR}/cvsroot/first-dir/imported-f1,v <-- imported-f1 +${CVSROOT_DIRNAME}/first-dir/imported-f1,v <-- imported-f1 new revision: delete; previous revision: 1\.1\.1\.1 done Checking in imported-f2; -${TESTDIR}/cvsroot/first-dir/imported-f2,v <-- imported-f2 +${CVSROOT_DIRNAME}/first-dir/imported-f2,v <-- imported-f2 new revision: 1\.2; previous revision: 1\.1 done" # log dotest import-101 "${testcvs} log imported-f1" \ " -RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/imported-f1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/imported-f1,v Working file: imported-f1 head: 1\.2 branch: @@ -4955,13 +6273,13 @@ first-import dotest import-104 \ "${testcvs} ci -m vendor-removed imported-f4" \ "Removing imported-f4; -${TESTDIR}/cvsroot/first-dir/imported-f4,v <-- imported-f4 +${CVSROOT_DIRNAME}/first-dir/imported-f4,v <-- imported-f4 new revision: delete; previous revision: 1\.1\.1\.1 done" # update to main line dotest import-105 "${testcvs} -q update -A" \ -"${PROG} [a-z]*: warning: imported-f1 is not (any longer) pertinent +"${PROG} [a-z]*: imported-f1 is no longer in the repository [UP] imported-f2" # second import - file4 deliberately unchanged @@ -5015,7 +6333,7 @@ Use the following command to help the merge:" # update to main line dotest import-112 "${testcvs} -q update -A" \ -"${PROG} [a-z]*: warning: imported-f1 is not (any longer) pertinent +"${PROG} [a-z]*: imported-f1 is no longer in the repository [UP] imported-f2" cd .. @@ -5023,7 +6341,7 @@ Use the following command to help the merge:" 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 -RCS file: ${TESTDIR}/cvsroot/first-dir/imported-f2,v +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 @@ -5119,7 +6437,7 @@ No conflicts created by this import" U first-dir/file2" cd first-dir dotest importb-5 "${testcvs} -q log file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: 1\.1\.1 @@ -5182,13 +6500,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 ${TESTDIR}/cvsroot/first-dir/adir -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/first-dir/adir/sub1 -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/first-dir/adir/sub1/ssdir -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/first-dir/adir/sub2 -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/first-dir/bdir -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/first-dir/bdir/subdir -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/first-dir/cdir" +${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" cd .. mkdir 2; cd 2 dotest importc-2 "${testcvs} -q co first-dir" \ @@ -5211,7 +6529,14 @@ ${PROG} [a-z]*: Updating bdir/subdir" "${testcvs} -q rtag -b -r release wip_test first-dir" "" dotest importc-6 "${testcvs} -q update -r wip_test" "M cdir/cfile" - if test "$remote" = no; then + if $remote; then + # Remote doesn't have the bug in the first place. + dotest importc-7r "${testcvs} -q ci -m modify -r wip_test" \ +"Checking in cdir/cfile; +${CVSROOT_DIRNAME}/first-dir/cdir/cfile,v <-- cfile +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done" + else # This checkin should just succeed. That it doesn't is a # bug (CVS 1.9.16 through the present seem to have it; CVS # 1.9 did not). @@ -5221,14 +6546,7 @@ ${PROG} \[[a-z]* aborted\]: there is no version here; do .${PROG} checkout. firs # The workaround is to leave off the "-r wip_test". dotest importc-7a "${testcvs} -q ci -m modify" \ "Checking in cdir/cfile; -${TESTDIR}/cvsroot/first-dir/cdir/cfile,v <-- cfile -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done" - else - # Remote doesn't have the bug in the first place. - dotest importc-7r "${testcvs} -q ci -m modify -r wip_test" \ -"Checking in cdir/cfile; -${TESTDIR}/cvsroot/first-dir/cdir/cfile,v <-- cfile +${CVSROOT_DIRNAME}/first-dir/cdir/cfile,v <-- cfile new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 done" fi @@ -5236,7 +6554,7 @@ done" # TODO: should also be testing "import -d" when we update # an existing file. dotest importc-8 "${testcvs} -q log cdir/cfile" " -RCS file: ${TESTDIR}/cvsroot/first-dir/cdir/cfile,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/cdir/cfile,v Working file: cdir/cfile head: 1\.1 branch: 1\.1\.1 @@ -5266,7 +6584,7 @@ modify =============================================================================" dotest importc-9 "${testcvs} -q log bdir/subdir/file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/bdir/subdir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/bdir/subdir/file1,v Working file: bdir/subdir/file1 head: 1\.1 branch: 1\.1\.1 @@ -5328,13 +6646,12 @@ import-it dotest import-after-initial-2 "$testcvs -Q co $module" '' cd $module echo original > $file - dotest import-after-initial-3 "${testcvs} -Q add $file" \ -"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' + dotest import-after-initial-3 "${testcvs} -Q add $file" "" dotest import-after-initial-4 "${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" @@ -5453,28 +6770,28 @@ done" '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add these files permanently' dotest join-3 "${testcvs} -q commit -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file3,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v done Checking in file3; -${TESTDIR}/cvsroot/first-dir/file3,v <-- file3 +${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file4,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v done Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file6,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v done Checking in file6; -${TESTDIR}/cvsroot/first-dir/file6,v <-- file6 +${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file8,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file8,v done Checking in file8; -${TESTDIR}/cvsroot/first-dir/file8,v <-- file8 +${CVSROOT_DIRNAME}/first-dir/file8,v <-- file8 initial revision: 1\.1 done" @@ -5499,28 +6816,28 @@ T file8' '"${PROG}"' [a-z]*: scheduling `file8'\'' for removal '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove these files permanently' dotest join-7 "${testcvs} -q ci -mx ." \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: 1\.2; previous revision: 1\.1 done Removing file6; -${TESTDIR}/cvsroot/first-dir/file6,v <-- file6 +${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 new revision: delete; previous revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file7,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v done Checking in file7; -${TESTDIR}/cvsroot/first-dir/file7,v <-- file7 +${CVSROOT_DIRNAME}/first-dir/file7,v <-- file7 initial revision: 1\.1 done Removing file8; -${TESTDIR}/cvsroot/first-dir/file8,v <-- file8 +${CVSROOT_DIRNAME}/first-dir/file8,v <-- file8 new revision: delete; previous revision: 1\.1 done" @@ -5547,21 +6864,21 @@ U first-dir/file8' '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest join-10 "${testcvs} -q ci -mx ." \ "Checking in file3; -${TESTDIR}/cvsroot/first-dir/file3,v <-- file3 +${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: 1\.1\.2\.1; previous revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/file5,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file5,v done Checking in file5; -${TESTDIR}/cvsroot/first-dir/Attic/file5,v <-- file5 +${CVSROOT_DIRNAME}/first-dir/Attic/file5,v <-- file5 new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in file6; -${TESTDIR}/cvsroot/first-dir/Attic/file6,v <-- file6 +${CVSROOT_DIRNAME}/first-dir/Attic/file6,v <-- file6 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" @@ -5588,30 +6905,30 @@ T file8' '"${PROG}"' [a-z]*: scheduling `file6'\'' for removal '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to remove these files permanently' dotest join-14 "${testcvs} -q ci -mx ." \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/Attic/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/Attic/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.1\.2\.1; previous revision: 1\.1 done Removing file3; -${TESTDIR}/cvsroot/first-dir/file3,v <-- file3 +${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 new revision: delete; previous revision: 1\.1\.2\.1 done Removing file4; -${TESTDIR}/cvsroot/first-dir/file4,v <-- file4 +${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 new revision: delete; previous revision: 1\.1\.2\.1 done Removing file5; -${TESTDIR}/cvsroot/first-dir/Attic/file5,v <-- file5 +${CVSROOT_DIRNAME}/first-dir/Attic/file5,v <-- file5 new revision: delete; previous revision: 1\.1\.2\.1 done Removing file6; -${TESTDIR}/cvsroot/first-dir/Attic/file6,v <-- file6 +${CVSROOT_DIRNAME}/first-dir/Attic/file6,v <-- file6 new revision: delete; previous revision: 1\.1\.2\.1 done" @@ -5674,7 +6991,7 @@ M file4' dotest join-20 "${testcvs} -q co -jbranch first-dir" \ "U first-dir/file1 U first-dir/file2 -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +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 @@ -5708,7 +7025,7 @@ U first-dir/file7' echo 'third revision of file4' > file4 dotest join-23 "${testcvs} -q update -jbranch ." \ "U file1 -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +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 @@ -5746,7 +7063,7 @@ T file7" # the trunk (e.g. join-23). dotest join-28 "${testcvs} -q update -j branch" \ "U file1 -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +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 @@ -5760,6 +7077,41 @@ M file2 R file3 A file8" + # Checkout the mainline again to try updating and merging between two + # branches in the same step + # this seems a likely scenario - the user finishes up on branch and + # updates to br2 and merges in the same step - and there was a bug + # once that if the file was removed in the update then it wouldn't be + # readded in the merge + cd .. + rm -r first-dir + dotest join-twobranch-1 "${testcvs} -q co -rbranch first-dir" \ +'U first-dir/file1 +U first-dir/file2 +U first-dir/file8' + cd first-dir + dotest join-twobranch-2 "${testcvs} -q update -rbr2 -jbranch" \ +"cvs [a-z]*: file1 is no longer in the repository +U file1 +U file2 +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into file2 +U file3 +${PROG} [a-z]*: scheduling file3 for removal +U file4 +${PROG} [a-z]*: 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" + # Verify that the right changes have been scheduled. + dotest join-twobranch-3 "${testcvs} -q update" \ +"A file1 +M file2 +R file3 +A file8" + # Checkout the mainline again to try merging from the trunk # to a branch. cd .. @@ -5782,7 +7134,7 @@ T file7' echo 'second revision of file7' > file7 dotest join-32 "${testcvs} -q ci -mx ." \ "Checking in file7; -${TESTDIR}/cvsroot/first-dir/file7,v <-- file7 +${CVSROOT_DIRNAME}/first-dir/file7,v <-- file7 new revision: 1\.2; previous revision: 1\.1 done" @@ -5808,7 +7160,7 @@ U file7" # happens to do the right thing; see above join-20. dotest join-36 "${testcvs} -q up -j T3 -j T4" \ "A file7 -RCS file: ${TESTDIR}/cvsroot/first-dir/file7,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v retrieving revision 1\.1 retrieving revision 1\.2 Merging differences between 1\.1 and 1\.2 into file7" @@ -5832,17 +7184,17 @@ Merging differences between 1\.1 and 1\.2 into file7" dotest join2-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest join2-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest join2-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" dotest join2-5 "${testcvs} -q tag -b br1" "T file1" @@ -5853,14 +7205,14 @@ done" "${PROG} [a-z]*: scheduling file .bradd. for addition on branch .br1. ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest join2-7 "${testcvs} -q ci -m modify" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/bradd,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/bradd,v done Checking in bradd; -${TESTDIR}/cvsroot/first-dir/Attic/bradd,v <-- bradd +${CVSROOT_DIRNAME}/first-dir/Attic/bradd,v <-- bradd new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" @@ -5872,14 +7224,14 @@ done" File: file1 Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" dotest join2-10 "cat CVS/Tag" "Tbr1" dotest join2-11 "${testcvs} -q update -j br1 file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"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" @@ -5891,7 +7243,7 @@ modify on branch" File: file1 Status: Locally Modified Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" @@ -5899,7 +7251,7 @@ File: file1 Status: Locally Modified # And the checkin should go to the trunk dotest join2-15 "${testcvs} -q ci -m modify file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" @@ -5916,7 +7268,7 @@ 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]*: warning: bradd is not (any longer) pertinent +"${PROG} [a-z]*: 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" @@ -5926,13 +7278,13 @@ done" File: bradd Status: Locally Added Working revision: New file! - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/Attic/bradd,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/bradd,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" dotest join2-20 "${testcvs} -q ci -m modify bradd" \ "Checking in bradd; -${TESTDIR}/cvsroot/first-dir/bradd,v <-- bradd +${CVSROOT_DIRNAME}/first-dir/bradd,v <-- bradd new revision: 1\.2; previous revision: 1\.1 done" @@ -5949,17 +7301,17 @@ done" dotest join3-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest join3-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest join3-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" dotest join3-5 "${testcvs} -q tag -b br1" "T file1" @@ -5967,7 +7319,7 @@ done" echo 'br1:line1' >>file1 dotest join3-7 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" @@ -5982,13 +7334,13 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" echo 'trunk:line1' >>file1 dotest join3-9 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done" dotest join3-10 "${testcvs} -q tag -b br2" "T file1 @@ -5998,7 +7350,7 @@ T file2" dotest join3-11 "${testcvs} -q update -r br1" "[UP] file1 ${PROG} [a-z]*: file2 is no longer in the repository" dotest join3-12 "${testcvs} -q update -j br2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.1 retrieving revision 1\.2 Merging differences between 1\.1 and 1\.2 into file1 @@ -6020,7 +7372,7 @@ U file1" "U file1" echo 'br2:line1' >>file1 dotest join3-15 "${testcvs} -q ci -m modify file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2\.2\.1; previous revision: 1\.2 done" @@ -6031,7 +7383,7 @@ done" # and so it merges both the 1.1->1.2 and 1.2->1.2.2.1 changes. # This seems like a reasonably plausible behavior. dotest join3-17 "${testcvs} -q update -j br2 file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.1 retrieving revision 1\.2\.2\.1 Merging differences between 1\.1 and 1\.2\.2\.1 into file1 @@ -6051,6 +7403,9 @@ br2:line1 ;; join-readonly-conflict) + # Previously, only tests 1 & 11 were being tested. I added the + # intermediate dotest's to try and diagnose a different failure + # # Demonstrate that cvs-1.9.29 can fail on 2nd and subsequent # conflict-evoking join attempts. # Even with that version of CVS, This test failed only in @@ -6058,50 +7413,77 @@ br2:line1 # operation only for files that were read-only (either due to # use of cvs' global -r option, setting the CVSREAD envvar, # or use of watch lists). - mkdir 1; cd 1 + mkdir join-readonly-conflict; cd join-readonly-conflict dotest join-readonly-conflict-1 "$testcvs -q co -l ." '' - module=x + module=join-readonly-conflict mkdir $module $testcvs -q add $module >>$LOGFILE 2>&1 cd $module file=m echo trunk > $file - $testcvs -q add $file >>$LOGFILE 2>&1 - $testcvs -q ci -m . $file >>$LOGFILE 2>&1 + dotest join-readonly-conflict-2 "$testcvs -Q add $file" '' + + dotest join-readonly-conflict-3 "$testcvs -q ci -m . $file" \ +"RCS file: $CVSROOT_DIRNAME/$module/$file,v +done +Checking in $file; +$CVSROOT_DIRNAME/$module/$file,v <-- $file +initial revision: 1\.1 +done" - $testcvs tag -b B $file >>$LOGFILE 2>&1 - $testcvs -q update -rB $file >>$LOGFILE 2>&1 + dotest join-readonly-conflict-4 "$testcvs tag -b B $file" "T $file" + dotest join-readonly-conflict-5 "$testcvs -q update -rB $file" '' echo branch B > $file - $testcvs ci -m . $file >>$LOGFILE 2>&1 + dotest join-readonly-conflict-6 "$testcvs -q ci -m . $file" \ +"Checking in $file; +$CVSROOT_DIRNAME/$module/$file,v <-- $file +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done" rm $file - $testcvs update -A $file >>$LOGFILE 2>&1 + dotest join-readonly-conflict-7 "$testcvs -Q update -A $file" '' # Make sure $file is read-only. This can happen more realistically # via patch -- which could be used to apply a delta, yet would # preserve a file's read-only permissions. echo conflict > $file; chmod u-w $file - $testcvs update -r B $file >>$LOGFILE 2>&1 + dotest join-readonly-conflict-8 "$testcvs update -r B $file" \ +"RCS file: $CVSROOT_DIRNAME/$module/$file,v +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 +C $file" + # restore to the trunk rm -f $file - $testcvs update -A $file >>$LOGFILE 2>&1 + dotest join-readonly-conflict-9 "$testcvs -Q update -A $file" '' + # This one would fail because cvs couldn't open the existing # (and read-only) .# file for writing. echo conflict > $file - test -w ".#$file.1.1" && fail "$file is writable" - dotest join-readonly-conflict-2 "$testcvs update -r B $file" \ -"RCS file: ${TESTDIR}/cvsroot/$module/$file,v + # verify that the backup file is writable + if test -w ".#$file.1.1"; then + fail "join-readonly-conflict-10 : .#$file.1.1 is writable" + else + pass "join-readonly-conflict-10" + fi + dotest join-readonly-conflict-11 "$testcvs update -r B $file" \ +"RCS file: $CVSROOT_DIRNAME/$module/$file,v 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 [a-z]*: conflicts found in $file C m" cd ../.. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/$module + if $keep; then :; else + rm -rf join-readonly-conflict + rm -rf $CVSROOT_DIRNAME/$module + fi ;; join-admin) @@ -6137,7 +7519,7 @@ C m" File: b Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/x/b,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/x/b,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" @@ -6147,6 +7529,87 @@ File: b Status: Up-to-date rm -rf ${CVSROOT_DIRNAME}/$module ;; + join-admin-2) + # Show that when a merge (via update -kk -jtag1 -jtag2) first + # removes a file, then modifies another containing an $Id...$ line, + # the resulting file contains the unexpanded `$Id.$' string, as + # -kk requires. + mkdir 1; cd 1 + dotest join-admin-2-1 "$testcvs -q co -l ." '' + module=x + mkdir $module + dotest join-admin-2-2 "$testcvs -q add $module" \ +"Directory ${CVSROOT_DIRNAME}/x added to the repository" + cd $module + + # Create a file so applying the first tag works. + echo '$''Id$' > e0 + cp e0 e + dotest join-admin-2-3 "$testcvs -Q add e" '' + dotest join-admin-2-4 "$testcvs -Q ci -m. e" \ +"RCS file: ${CVSROOT_DIRNAME}/x/e,v +done +Checking in e; +${CVSROOT_DIRNAME}/x/e,v <-- e +initial revision: 1\.1 +done" + + dotest join-admin-2-5 "$testcvs -Q tag -b T" '' "${QUESTION} e0" + dotest join-admin-2-6 "$testcvs -Q update -r T" '' "${QUESTION} e0" + cp e0 e + dotest join-admin-2-7 "$testcvs -Q ci -m. e" \ +"Checking in e; +${CVSROOT_DIRNAME}/x/e,v <-- e +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done" + + dotest join-admin-2-8 "$testcvs -Q update -A" '' "${QUESTION} e0" + dotest join-admin-2-9 "$testcvs -Q tag -b M1" '' "${QUESTION} e0" + + echo '$''Id$' > b + dotest join-admin-2-10 "$testcvs -Q add b" '' + cp e0 e + dotest join-admin-2-11 "$testcvs -Q ci -m. b e" \ +"RCS file: ${CVSROOT_DIRNAME}/x/b,v +done +Checking in b; +${CVSROOT_DIRNAME}/x/b,v <-- b +initial revision: 1\.1 +done +Checking in e; +${CVSROOT_DIRNAME}/x/e,v <-- e +new revision: 1\.2; previous revision: 1\.1 +done" + + dotest join-admin-2-12 "$testcvs -Q tag -b M2" '' "${QUESTION} e0" + + 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 . +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 +${QUESTION} e0" \ +"${QUESTION} e0 +${PROG} [a-z]*: 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" + + # Verify that the $Id.$ string is not expanded. + dotest join-admin-2-15 "cat e" '$''Id$' + + cd ../.. + rm -rf 1 + rm -rf ${CVSROOT_DIRNAME}/$module + ;; + new) # look for stray "no longer pertinent" messages. mkdir ${CVSROOT_DIRNAME}/first-dir @@ -6218,10 +7681,10 @@ File: b Status: Up-to-date "${PROG} [a-z]*: scheduling file .a. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest newb-123c "${testcvs} -q ci -m added" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/a,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v done Checking in a; -${TESTDIR}/cvsroot/first-dir/a,v <-- a +${CVSROOT_DIRNAME}/first-dir/a,v <-- a initial revision: 1\.1 done" @@ -6249,7 +7712,7 @@ done" ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" dotest newb-123h "${testcvs} -q ci -m removed" \ "Removing a; -${TESTDIR}/cvsroot/first-dir/a,v <-- a +${CVSROOT_DIRNAME}/first-dir/a,v <-- a new revision: delete; previous revision: 1\.1\.2 done" @@ -6263,29 +7726,20 @@ done" # Update the other copy, and make sure that a is removed. cd ../1/first-dir - # "Needs Patch" is a rather strange output here. Something like + # "Entry Invalid" is a rather strange output here. Something like # "Removed in Repository" would make more sense. - # The "Need Checkout" output is what CVS does if configured - # --disable-server. dotest newb-123j0 "${testcvs} status a" \ -"=================================================================== -File: a Status: Needs Patch - - Working revision: 1\.1.* - Repository revision: 1\.1\.2\.1 ${TESTDIR}/cvsroot/first-dir/a,v - Sticky Tag: branch (branch: 1\.1\.2) - Sticky Date: (none) - Sticky Options: (none)" \ -"=================================================================== -File: a Status: Needs Checkout +"${PROG} [a-z]*: a is no longer in the repository +=================================================================== +File: a Status: Entry Invalid Working revision: 1\.1.* - Repository revision: 1\.1\.2\.1 ${TESTDIR}/cvsroot/first-dir/a,v + Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/a,v Sticky Tag: branch (branch: 1\.1\.2) Sticky Date: (none) Sticky Options: (none)" dotest newb-123j "${testcvs} -q update" \ -"${PROG} [a-z]*: warning: a is not (any longer) pertinent" +"${PROG} [a-z]*: a is no longer in the repository" if test -f a; then fail newb-123k @@ -6313,10 +7767,10 @@ File: a Status: Needs Checkout "${PROG} [a-z]*: scheduling file .a. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest conflicts-126 "${testcvs} -q ci -m added" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/a,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v done Checking in a; -${TESTDIR}/cvsroot/first-dir/a,v <-- a +${CVSROOT_DIRNAME}/first-dir/a,v <-- a initial revision: 1\.1 done" @@ -6324,13 +7778,11 @@ done" mkdir 2 cd 2 - # The need for TMPPWD here is a (minor) CVS bug; the - # output should use the name of the repository as specified. dotest conflicts-126.5 "${testcvs} co -p first-dir" \ "${PROG} [a-z]*: Updating first-dir =================================================================== Checking out first-dir/a -RCS: ${TMPPWD}/cvsroot/first-dir/a,v +RCS: ${CVSROOT_DIRNAME}/first-dir/a,v VERS: 1\.1 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*" if ${CVS} co first-dir ; then @@ -6349,10 +7801,10 @@ VERS: 1\.1 echo add a line >>a mkdir dir1 dotest conflicts-127b "${testcvs} add dir1" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir1 added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" dotest conflicts-128 "${testcvs} -q ci -m changed" \ "Checking in a; -${TESTDIR}/cvsroot/first-dir/a,v <-- a +${CVSROOT_DIRNAME}/first-dir/a,v <-- a new revision: 1\.2; previous revision: 1\.1 done" cd ../.. @@ -6361,13 +7813,11 @@ done" # contents. mkdir 3 cd 3 - # The need for TMPPWD here is a (minor) CVS bug; the - # output should use the name of the repository as specified. dotest conflicts-128.5 "${testcvs} co -p -l first-dir" \ "${PROG} [a-z]*: Updating first-dir =================================================================== Checking out first-dir/a -RCS: ${TMPPWD}/cvsroot/first-dir/a,v +RCS: ${CVSROOT_DIRNAME}/first-dir/a,v VERS: 1\.2 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* add a line" @@ -6388,12 +7838,12 @@ add a line" File: a Status: Needs Merge Working revision: 1\.1.* - Repository revision: 1\.2 ${TESTDIR}/cvsroot/first-dir/a,v + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/a,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" dotest conflicts-129a "${testcvs} -nq update a" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/a,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v retrieving revision 1\.1 retrieving revision 1\.2 Merging differences between 1\.1 and 1\.2 into a @@ -6401,7 +7851,7 @@ rcsmerge: warning: conflicts during merge ${PROG} [a-z]*: conflicts found in a C a" dotest conflicts-130 "${testcvs} -q update" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/a,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v retrieving revision 1\.1 retrieving revision 1\.2 Merging differences between 1\.1 and 1\.2 into a @@ -6412,7 +7862,7 @@ ${QUESTION} dir1 ${QUESTION} sdir" \ "${QUESTION} dir1 ${QUESTION} sdir -RCS file: ${TESTDIR}/cvsroot/first-dir/a,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v retrieving revision 1\.1 retrieving revision 1\.2 Merging differences between 1\.1 and 1\.2 into a @@ -6426,7 +7876,7 @@ C a" File: a Status: File had conflicts on merge Working revision: 1\.2.* - Repository revision: 1\.2 ${TESTDIR}/cvsroot/first-dir/a,v + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/a,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" @@ -6456,14 +7906,14 @@ ${PROG} \[[a-z]* aborted\]: correct above errors first!" File: a Status: File had conflicts on merge Working revision: 1\.2.* - Repository revision: 1\.2 ${TESTDIR}/cvsroot/first-dir/a,v + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/a,v Sticky Tag: (none) 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 Checking in a; -${TESTDIR}/cvsroot/first-dir/a,v <-- a +${CVSROOT_DIRNAME}/first-dir/a,v <-- a new revision: 1\.3; previous revision: 1\.2 done" @@ -6475,13 +7925,13 @@ done" File: a Status: Locally Modified Working revision: 1\.3.* - Repository revision: 1\.3 ${TESTDIR}/cvsroot/first-dir/a,v + Repository revision: 1\.3 ${CVSROOT_DIRNAME}/first-dir/a,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" dotest conflicts-133 "${testcvs} -q ci -m resolved" \ "Checking in a; -${TESTDIR}/cvsroot/first-dir/a,v <-- a +${CVSROOT_DIRNAME}/first-dir/a,v <-- a new revision: 1\.4; previous revision: 1\.3 done" dotest conflicts-status-7 "${testcvs} status a" \ @@ -6489,7 +7939,7 @@ done" File: a Status: Up-to-date Working revision: 1\.4.* - Repository revision: 1\.4 ${TESTDIR}/cvsroot/first-dir/a,v + Repository revision: 1\.4 ${CVSROOT_DIRNAME}/first-dir/a,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" @@ -6584,16 +8034,16 @@ File: a Status: Up-to-date ${PROG} [a-z]*: scheduling file .abc. for addition ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest conflicts2-142a3 "${testcvs} -q ci -m added" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/a,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v done Checking in a; -${TESTDIR}/cvsroot/first-dir/a,v <-- a +${CVSROOT_DIRNAME}/first-dir/a,v <-- a initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/abc,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v done Checking in abc; -${TESTDIR}/cvsroot/first-dir/abc,v <-- abc +${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc initial revision: 1\.1 done" @@ -6615,7 +8065,7 @@ U first-dir/abc' echo modify a >>a dotest conflicts2-142b2 "${testcvs} -q ci -m modify-a" \ "Checking in a; -${TESTDIR}/cvsroot/first-dir/a,v <-- a +${CVSROOT_DIRNAME}/first-dir/a,v <-- a new revision: 1\.2; previous revision: 1\.1 done" cd ../../2/first-dir @@ -6638,7 +8088,13 @@ ${PROG} [a-z]*: a, version 1\.1, resurrected" "${PROG} [a-z]*: scheduling .first-dir/a. for removal ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" - if test "$remote" = no; then + if $remote; then + # Haven't investigated this one. + dotest_fail conflicts2-142b8 "${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. @@ -6656,12 +8112,6 @@ ${PROG} [a-z]*: first-dir/a, version 1\.2, resurrected" 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" - else - # Haven't investigated this one. - dotest_fail conflicts2-142b8 "${testcvs} add first-dir/a" \ -"${PROG} add: in directory \.: -${PROG} \[add aborted\]: there is no version here; do '${PROG} checkout' first" - cd first-dir fi # As before, 1.2 instead of 1.1 is a bug. @@ -6682,7 +8132,7 @@ ${PROG} [a-z]*: a, version 1\.2, resurrected" ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" dotest conflicts2-142c1 "${testcvs} -q ci -m remove-abc" \ "Removing abc; -${TESTDIR}/cvsroot/first-dir/abc,v <-- abc +${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc new revision: delete; previous revision: 1\.1 done" cd ../../2/first-dir @@ -6704,16 +8154,16 @@ ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" ${PROG} [a-z]*: scheduling file .same\.c. for addition ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest conflicts2-142d1 "${testcvs} -q ci -m added" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aa\.c,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa\.c,v done Checking in aa\.c; -${TESTDIR}/cvsroot/first-dir/aa\.c,v <-- aa\.c +${CVSROOT_DIRNAME}/first-dir/aa\.c,v <-- aa\.c initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/same\.c,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/same\.c,v done Checking in same\.c; -${TESTDIR}/cvsroot/first-dir/same\.c,v <-- same\.c +${CVSROOT_DIRNAME}/first-dir/same\.c,v <-- same\.c initial revision: 1\.1 done" cd ../../2/first-dir @@ -6726,7 +8176,7 @@ done" # cvs add just to get them in that habit (also, trying to implement # the local CVS behavior for remote without the cvs add seems # pretty difficult). - if test "$remote" = yes; then + if $remote; then dotest_fail conflicts2-142d2 "${testcvs} -q update" \ "${QUESTION} aa\.c ${QUESTION} same\.c @@ -6746,7 +8196,7 @@ U same\.c" File: aa\.c Status: Unresolved Conflict Working revision: No entry for aa\.c - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/aa\.c,v" + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/aa\.c,v" # Could also be testing the case in which the cvs add happened # before the commit by the other user. @@ -6789,7 +8239,7 @@ File: aa\.c Status: Unresolved Conflict dotest conflicts3-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest conflicts3-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd .. mkdir 2; cd 2 dotest conflicts3-3 "${testcvs} -q co -l first-dir" '' @@ -6800,16 +8250,16 @@ File: aa\.c Status: Unresolved Conflict ${PROG} [a-z]*: scheduling file .file2. for addition ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest conflicts3-5 "${testcvs} -q ci -m add-them" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done" cd ../../2/first-dir @@ -6831,35 +8281,35 @@ ${PROG} [a-z]*: scheduling .file2. for removal ${PROG} [a-z]*: use .${PROG} commit. to remove these files permanently" dotest conflicts3-11 "${testcvs} -q ci -m remove-them" \ "Removing file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: delete; previous revision: 1\.1 done Removing file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: delete; previous revision: 1\.1 done" cd ../../1/first-dir dotest conflicts3-12 "${testcvs} -n -q update" \ -"${PROG} [a-z]*: warning: file1 is not (any longer) pertinent -${PROG} [a-z]*: warning: file2 is not (any longer) pertinent" +"${PROG} [a-z]*: file1 is no longer in the repository +${PROG} [a-z]*: file2 is no longer in the repository" dotest conflicts3-13 "${testcvs} -q update" \ -"${PROG} [a-z]*: warning: file1 is not (any longer) pertinent -${PROG} [a-z]*: warning: file2 is not (any longer) pertinent" +"${PROG} [a-z]*: file1 is no longer in the repository +${PROG} [a-z]*: 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. mkdir sdir dotest conflicts3-14 "${testcvs} add sdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/sdir added to 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" dotest conflicts3-14b "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/sfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/sfile,v done Checking in sdir/sfile; -${TESTDIR}/cvsroot/first-dir/sdir/sfile,v <-- sfile +${CVSROOT_DIRNAME}/first-dir/sdir/sfile,v <-- sfile initial revision: 1\.1 done" @@ -6876,7 +8326,7 @@ done" # that sdir is even a directory (stat'ing everything would be # too slow). The remote behavior makes more sense to me (but # would this affect other cases?). - if test "$remote" = yes; then + if $remote; then dotest conflicts3-15 "${testcvs} -q update" \ "${QUESTION} sdir" else @@ -6923,16 +8373,9 @@ ${PROG} [a-z]*: ignoring first-dir/sdir (CVS/Entries missing)" dotest conflicts3-21 "${testcvs} -q update -d sdir" "U sdir/sfile" rm -r sdir/CVS dotest conflicts3-22 "${testcvs} -q update" "${QUESTION} sdir" - if test "x$remote" = xyes; then - # It isn't particularly swift that CVS prints this - # "cannot open CVS/Entries" where it has already printed - # "? sdir". At least I don't think so. But do note: (1) - # non-fatal error, and (2) tells us which directory has - # the problem. + if $remote; then dotest_fail conflicts3-23 "${testcvs} -q update -PdA" \ "${QUESTION} sdir -${PROG} update: in directory sdir: -${PROG} update: cannot open CVS/Entries for reading: No such file or directory ${PROG} update: move away sdir/sfile; it is in the way C sdir/sfile" else @@ -6954,22 +8397,13 @@ C sdir/sfile" ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" dotest conflicts3-26 "${testcvs} ci -m remove sdir/sfile" \ "Removing sdir/sfile; -${TESTDIR}/cvsroot/first-dir/sdir/sfile,v <-- sfile +${CVSROOT_DIRNAME}/first-dir/sdir/sfile,v <-- sfile new revision: delete; previous revision: 1\.1 done" rm -r sdir/CVS dotest conflicts3-27 "${testcvs} -q update" "${QUESTION} sdir" - if test "x$remote" = xyes; then - # Regarding "cannot open CVS/Entries", see comments at - # conflicts3-23. - dotest conflicts3-28 "${testcvs} -q update -PdA" \ -"${QUESTION} sdir -${PROG} update: in directory sdir: -${PROG} update: cannot open CVS/Entries for reading: No such file or directory" - else - dotest conflicts3-28 "${testcvs} -q update -PdA" \ + dotest conflicts3-28 "${testcvs} -q update -PdA" \ "${QUESTION} sdir" - fi cd ../.. @@ -6983,17 +8417,17 @@ ${PROG} update: cannot open CVS/Entries for reading: No such file or directory" dotest clean-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest clean-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest clean-4 "${testcvs} -q ci -m clean-3" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/cleanme\.txt,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/cleanme\.txt,v done Checking in cleanme\.txt; -${TESTDIR}/cvsroot/first-dir/cleanme\.txt,v <-- cleanme\.txt +${CVSROOT_DIRNAME}/first-dir/cleanme\.txt,v <-- cleanme\.txt initial revision: 1\.1 done" # Okay, preparation is done, now test. @@ -7027,10 +8461,38 @@ U cleanme\.txt" "The usual boring test text\. bluegill" + # Now try with conflicts + cd .. + dotest clean-15 "${testcvs} -q co -d second-dir first-dir" \ +'U second-dir/cleanme\.txt' + cd second-dir + echo "conflict test" >> cleanme.txt + dotest clean-16 "${testcvs} -q ci -m." \ +"Checking in cleanme\.txt; +${CVSROOT_DIRNAME}/first-dir/cleanme\.txt,v <-- cleanme\.txt +new revision: 1\.2; previous revision: 1\.1 +done" + cd ../first-dir + echo "fish" >> cleanme.txt + dotest clean-17 "${testcvs} -nq update" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/cleanme\.txt,v +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 +C cleanme\.txt" + dotest clean-18 "${testcvs} -q update -C" \ +"(Locally modified cleanme\.txt moved to \.#cleanme\.txt\.1\.1) +U cleanme\.txt" + dotest clean-19 "cat .#cleanme.txt.1.1" \ +"The usual boring test text\. +fish" + # Done. Clean up. cd ../.. rm -rf 1 - rm -rf ${TESTDIR}/cvsroot/first-dir + rm -rf ${CVSROOT_DIRNAME}/first-dir ;; modules) @@ -7069,7 +8531,7 @@ U CVSROOT/verifymsg' echo "# made a change" >>CVSROOT/modules dotest modules-1d "${testcvs} -q ci -m add-modules" \ "Checking in CVSROOT/modules; -${TESTDIR}/cvsroot/CVSROOT/modules,v <-- 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" @@ -7093,7 +8555,7 @@ U CVSROOT/verifymsg' echo "# made a change" >>CVSROOT/modules dotest modules-2d "${testcvs} -q ci -m add-modules" \ "Checking in CVSROOT/modules; -${TESTDIR}/cvsroot/CVSROOT/modules,v <-- 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" @@ -7120,7 +8582,7 @@ U CVSROOT/verifymsg' echo "# made a change" >>CVSROOT/modules dotest modules-3g "${testcvs} -q ci -m add-modules" \ "Checking in CVSROOT/modules; -${TESTDIR}/cvsroot/CVSROOT/modules,v <-- 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" @@ -7142,12 +8604,12 @@ ${PROG} [a-z]*: Rebuilding administrative file database" cd first-dir mkdir subdir dotest modules-143a "${testcvs} add subdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/subdir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" cd subdir mkdir ssdir dotest modules-143b "${testcvs} add ssdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/subdir/ssdir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir/ssdir added to the repository" touch a b @@ -7159,16 +8621,16 @@ ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest modules-145 "${testcvs} ci -m added" \ "${PROG} [a-z]*: Examining . ${PROG} [a-z]*: Examining ssdir -RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/a,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/a,v done Checking in a; -${TESTDIR}/cvsroot/first-dir/subdir/a,v <-- a +${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/b,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/b,v done Checking in b; -${TESTDIR}/cvsroot/first-dir/subdir/b,v <-- b +${CVSROOT_DIRNAME}/first-dir/subdir/b,v <-- b initial revision: 1\.1 done" @@ -7208,7 +8670,7 @@ bogusalias first-dir/subdir/a -a EOF dotest modules-148 "${testcvs} ci -m 'add modules' CVSROOT/modules" \ "Checking in CVSROOT/modules; -${TESTDIR}/cvsroot/CVSROOT/modules,v <-- 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" @@ -7337,16 +8799,16 @@ U first-dir/subdir/b" '"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add these files permanently' dotest modules-155c3 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done" @@ -7363,7 +8825,7 @@ U first-dir/file2" "${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" dotest modules-155c7 "${testcvs} -q ci -m remove-it" \ "Removing file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: delete; previous revision: 1\.1 done" cd .. @@ -7385,19 +8847,19 @@ U first-dir/file2" mkdir first-dir second-dir third-dir dotest modules2-setup-2 \ "${testcvs} add first-dir second-dir third-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository -Directory ${TESTDIR}/cvsroot/second-dir added to the repository -Directory ${TESTDIR}/cvsroot/third-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository +Directory ${CVSROOT_DIRNAME}/second-dir added to the repository +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" dotest modules2-setup-4 "${testcvs} -q ci -m add file3" \ -"RCS file: ${TESTDIR}/cvsroot/third-dir/file3,v +"RCS file: ${CVSROOT_DIRNAME}/third-dir/file3,v done Checking in file3; -${TESTDIR}/cvsroot/third-dir/file3,v <-- file3 +${CVSROOT_DIRNAME}/third-dir/file3,v <-- file3 initial revision: 1\.1 done" cd ../.. @@ -7409,15 +8871,19 @@ done" dotest modules2-1 "${testcvs} -q co CVSROOT/modules" \ 'U CVSROOT/modules' cd CVSROOT - echo 'ampermodule &first-dir &second-dir' > modules - echo 'combmodule third-dir file3 &first-dir' >> modules - echo 'ampdirmod -d newdir &first-dir &second-dir' >> modules - echo 'badmod -d newdir' >> modules + cat >> modules << EOF +ampermodule &first-dir &second-dir +combmodule third-dir file3 &first-dir +ampdirmod -d newdir &first-dir &second-dir +badmod -d newdir +messymod first-dir &messymodchild +messymodchild -d sdir/child second-dir +EOF # Depending on whether the user also ran the modules test # we will be checking in revision 1.2 or 1.3. dotest modules2-2 "${testcvs} -q ci -m add-modules" \ "Checking in modules; -${TESTDIR}/cvsroot/CVSROOT/modules,v <-- 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" @@ -7445,6 +8911,26 @@ EOF cd .. + # There used to be a nasty-hack that made CVS skip creation of the + # module dir (in this case ampermodule) when -n was specified + dotest modules2-ampermod-1 "${testcvs} -q co -n ampermodule" '' + dotest modules2-ampermod-2 "test -d ampermodule/first-dir" '' + dotest modules2-ampermod-3 "test -d ampermodule/second-dir" '' + + # Test release of a module + if echo yes |${testcvs} release -d ampermodule >>${LOGFILE}; then + pass modules2-ampermod-release-1 + else + fail modules2-ampermod-release-1 + fi + dotest_fail modules2-ampermod-release-2 "test -d ampermodule" '' + + # and the '-n' test again, but in conjunction with '-d' + dotest modules2-ampermod-4 "${testcvs} -q co -n -d newname ampermodule" '' + dotest modules2-ampermod-5 "test -d newname/first-dir" '' + dotest modules2-ampermod-6 "test -d newname/second-dir" '' + rm -rf newname + # Now we create another directory named first-dir and make # sure that CVS doesn't get them mixed up. mkdir first-dir @@ -7468,12 +8954,12 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" A first-dir/amper1 ${PROG} [a-z]*: Updating second-dir" - if test "$remote" = no; then + if $remote; then dotest modules2-13 "${testcvs} -q ci -m add-it ampermodule" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/amper1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/amper1,v done Checking in ampermodule/first-dir/amper1; -${TESTDIR}/cvsroot/first-dir/amper1,v <-- amper1 +${CVSROOT_DIRNAME}/first-dir/amper1,v <-- amper1 initial revision: 1\.1 done" else @@ -7481,10 +8967,10 @@ done" # Work around this bug. cd ampermodule dotest modules2-13 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/amper1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/amper1,v done Checking in first-dir/amper1; -${TESTDIR}/cvsroot/first-dir/amper1,v <-- amper1 +${CVSROOT_DIRNAME}/first-dir/amper1,v <-- amper1 initial revision: 1\.1 done" cd .. @@ -7529,13 +9015,61 @@ U first-dir/amper1" U first-dir/amper1 ${PROG} [a-z]*: Updating second-dir" dotest modules2-21 "test -f newdir/first-dir/amper1" "" - dotest_fail modules2-22 "${testcvs} co badmod" \ + 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" cd .. rm -r 1 + # Confirm that a rename with added depth nested in an ampersand + # module works. + mkdir 1; cd 1 + dotest modules2-nestedrename-1 "${testcvs} -q co messymod" \ +"U messymod/amper1" + dotest modules2-nestedrename-2 "test -d messymod/sdir" '' + dotest modules2-nestedrename-3 "test -d messymod/sdir/CVS" '' + dotest modules2-nestedrename-4 "test -d messymod/sdir/child" '' + dotest modules2-nestedrename-5 "test -d messymod/sdir/child/CVS" '' + cd ..; rm -r 1 + + # FIXME: client/server has a bug. It should be working like a local + # repository in this case, but fails to check out the second module + # in the list when a branch is specified. + mkdir 1; cd 1 + dotest modules2-ampertag-setup-1 \ +"${testcvs} -Q rtag tag first-dir second-dir third-dir" \ +'' + dotest modules2-ampertag-1 "${testcvs} -q co -rtag ampermodule" \ +"U first-dir/amper1" + if $remote; then + dotest_fail modules2-ampertag-2 "test -d ampermodule/second-dir" '' + dotest_fail modules2-ampertag-3 "test -d ampermodule/second-dir/CVS" '' + else + dotest modules2-ampertag-2 "test -d ampermodule/second-dir" '' + dotest modules2-ampertag-3 "test -d ampermodule/second-dir/CVS" '' + fi + cd ..; rm -r 1 + + # Test for tag files when an ampermod is renamed with more path + # elements than it started with. + # + # FIXME: This is currently broken in the remote case, possibly only + # because the messymodchild isn't being checked out at all. + mkdir 1; cd 1 +# dotest modules2-tagfiles-setup-1 \ +#"${testcvs} -Q rtag -b branch first-dir second-dir" \ +#'' + dotest modules2-tagfiles-1 "${testcvs} -q co -rtag messymod" \ +"U messymod/amper1" + if $remote; then + dotest_fail modules2-tagfiles-2r "test -d messymod/sdir" '' + else + dotest modules2-tagfiles-2 "cat messymod/sdir/CVS/Tag" 'Ttag' + fi + cd ..; rm -r 1 + # Test that CVS gives an error if one combines -a with # other options. # Probably would be better to break this out into a separate @@ -7548,7 +9082,7 @@ ${PROG} \[[a-z]* aborted\]: cannot expand modules" echo 'aliasopt -a -d onedir first-dir' >modules dotest modules2-a0 "${testcvs} -q ci -m add-modules" \ "Checking in modules; -${TESTDIR}/cvsroot/CVSROOT/modules,v <-- 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" @@ -7557,11 +9091,9 @@ ${PROG} [a-z]*: Rebuilding administrative file database" "${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" + cd ..; rm -r 1 # Clean up. - rm -r CVSROOT - cd .. - rm -r 1 rm -rf ${CVSROOT_DIRNAME}/first-dir rm -rf ${CVSROOT_DIRNAME}/second-dir rm -rf ${CVSROOT_DIRNAME}/third-dir @@ -7577,7 +9109,7 @@ ${PROG} \[[a-z]* aborted\]: cannot expand modules" dotest modules3-0 "${testcvs} -q co -l ." '' mkdir first-dir dotest modules3-1 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir echo file1 >file1 @@ -7585,10 +9117,10 @@ ${PROG} \[[a-z]* aborted\]: cannot expand modules" "${PROG}"' [a-z]*: scheduling file `file1'\'' for addition '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest modules3-3 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" cd .. @@ -7607,7 +9139,7 @@ another/path/test -d another/path/test first-dir EOF dotest modules3-5 "${testcvs} -q ci -m add-modules" \ "Checking in modules; -${TESTDIR}/cvsroot/CVSROOT/modules,v <-- 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" @@ -7627,8 +9159,8 @@ ${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 ${TESTDIR}/cvsroot/second-dir/suba -${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/second-dir/suba/subb +"${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/second-dir/suba +${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/second-dir/suba/subb No conflicts created by this import" " No conflicts created by this import" @@ -7640,15 +9172,15 @@ ${PROG} [a-z]*: Updating second-dir/suba ${PROG} [a-z]*: Updating second-dir/suba/subb" \ "${PROG} server: Updating second-dir" - if test "x$remote" = xyes; then + if $remote; then cd second-dir mkdir suba dotest modules3-7-workaround1 "${testcvs} add suba" \ -"Directory ${TESTDIR}/cvsroot/second-dir/suba added to the repository" +"Directory ${CVSROOT_DIRNAME}/second-dir/suba added to the repository" cd suba mkdir subb dotest modules3-7-workaround2 "${testcvs} add subb" \ -"Directory ${TESTDIR}/cvsroot/second-dir/suba/subb added to the repository" +"Directory ${CVSROOT_DIRNAME}/second-dir/suba/subb added to the repository" cd ../.. fi @@ -7658,10 +9190,10 @@ ${PROG} [a-z]*: Updating second-dir/suba/subb" \ "${PROG} [a-z]*: scheduling file .fileb. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest modules3-7d "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/second-dir/suba/subb/fileb,v +"RCS file: ${CVSROOT_DIRNAME}/second-dir/suba/subb/fileb,v done Checking in fileb; -${TESTDIR}/cvsroot/second-dir/suba/subb/fileb,v <-- fileb +${CVSROOT_DIRNAME}/second-dir/suba/subb/fileb,v <-- fileb initial revision: 1\.1 done" cd ../../.. @@ -7686,7 +9218,7 @@ done" # While we are doing things like twisted uses of '/' (e.g. # modules3-12), try this one. - if test "x$remote" = xyes; then + if $remote; then dotest_fail modules3-11b \ "${testcvs} -q update ${TESTDIR}/1/src/sub1/sub2/sub3/dir/file1" \ "absolute pathname .${TESTDIR}/1/src/sub1/sub2/sub3/dir. illegal for server" @@ -7708,24 +9240,24 @@ done" # instead of a real error). # I'm tempted to just make it a fatal error to have '/' in a # module name. But see comments at modules3-16. - if test "x$remote" = xno; then - mkdir 1; cd 1 - dotest modules3-12 "${testcvs} -q co path/in/modules" \ + if $remote; then :; else + mkdir 1; cd 1 + dotest modules3-12 "${testcvs} -q co path/in/modules" \ "U first-dir/file1" - dotest modules3-13 "test -f path/in/modules/first-dir/file1" '' - cd ..; rm -r 1 + dotest modules3-13 "test -f path/in/modules/first-dir/file1" '' + cd ..; rm -r 1 + fi # end of tests skipped for remote - # Now here is where it gets seriously bogus. + # Now here is where it used to get seriously bogus. mkdir 1; cd 1 dotest modules3-14 \ "${testcvs} -q rtag tag1 path/in/modules" '' - # CVS creates this even though rtag should *never* affect + # CVS used to create this even though rtag should *never* affect # the directory current when it is called! - dotest modules3-15 "test -d path/in/modules" '' - # Just for trivia's sake, rdiff is not similarly vulnerable - # because it passes 0 for run_module_prog to do_module. + dotest_fail modules3-15 "test -d path/in/modules" '' + # Just for trivia's sake, rdiff was not similarly vulnerable + # because it passed 0 for run_module_prog to do_module. cd ..; rm -r 1 - fi # end of tests skipped for remote # Some people seem to want this to work. I still suspect there # are dark corners in slashes in module names. This probably wants @@ -7750,12 +9282,12 @@ done" dotest modules4-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest modules4-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir mkdir subdir dotest modules4-3 "${testcvs} add subdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/subdir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" echo file1 > file1 dotest modules4-4 "${testcvs} add file1" \ @@ -7768,16 +9300,16 @@ done" '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest modules4-6 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/file2,v done Checking in subdir/file2; -${TESTDIR}/cvsroot/first-dir/subdir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/subdir/file2,v <-- file2 initial revision: 1\.1 done" @@ -7793,7 +9325,7 @@ somewhat -a first-dir !first-dir/subdir EOF dotest modules4-8 "${testcvs} -q ci -m add-modules" \ "Checking in modules; -${TESTDIR}/cvsroot/CVSROOT/modules,v <-- 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" @@ -7811,7 +9343,11 @@ U first-dir/subdir/file2" dotest_fail modules4-11 "test -d first-dir/subdir" '' rm -r first-dir - if test "$remote" = no; then + if $remote; then + # But remote seems to do it the other way. + dotest modules4-11a "${testcvs} -q co somewhat" "U first-dir/file1" + dotest_fail modules4-11b "test -d first-dir/subdir" '' + else # This is strange behavior, in that the order of the # "!first-dir/subdir" and "first-dir" matter, and it isn't # clear that they should. I suspect it is long-standing @@ -7819,10 +9355,6 @@ U first-dir/subdir/file2" dotest modules4-11a "${testcvs} -q co somewhat" \ "U first-dir/file1 U first-dir/subdir/file2" - else - # But remote seems to do it the other way. - dotest modules4-11a "${testcvs} -q co somewhat" "U first-dir/file1" - dotest_fail modules4-11b "test -d first-dir/subdir" '' fi rm -r first-dir @@ -7835,7 +9367,7 @@ ${PROG} [a-z]*: Ignoring first-dir/subdir" cd 1/first-dir/subdir dotest modules4-13 "${testcvs} log file2" " -RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/file2,v Working file: file2 head: 1\.1 branch: @@ -7867,11 +9399,11 @@ add-it cd first-dir mkdir subdir dotest modules5-2 "${testcvs} add subdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/subdir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" cd subdir mkdir ssdir dotest modules5-3 "${testcvs} add ssdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/subdir/ssdir added to the repository" +"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 @@ -7881,16 +9413,16 @@ ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest modules5-5 "${testcvs} ci -m added" \ "${PROG} [a-z]*: Examining . ${PROG} [a-z]*: Examining ssdir -RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/a,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/a,v done Checking in a; -${TESTDIR}/cvsroot/first-dir/subdir/a,v <-- a +${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/b,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/b,v done Checking in b; -${TESTDIR}/cvsroot/first-dir/subdir/b,v <-- b +${CVSROOT_DIRNAME}/first-dir/subdir/b,v <-- b initial revision: 1\.1 done" @@ -7927,7 +9459,7 @@ EOF dotest modules5-7 "${testcvs} ci -m 'add modules' CVSROOT/modules" \ "" \ "Checking in CVSROOT/modules; -${TESTDIR}/cvsroot/CVSROOT/modules,v <-- 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" @@ -7935,7 +9467,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database" cd .. rm -rf first-dir # Test that real modules check out to realmodule/a, not subdir/a. - if test "$remote" = "yes"; then + if $remote; then dotest modules5-8 "${testcvs} co realmodule" \ "U realmodule/a ${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule.. @@ -7950,7 +9482,7 @@ args: realmodule" fi dotest modules5-9 "test -d realmodule && test -f realmodule/a" "" dotest_fail modules5-10 "test -f realmodule/b" "" - if test "$remote" = "yes"; then + if $remote; then dotest modules5-11 "${testcvs} -q co realmodule" \ "checkout script invoked in .* args: realmodule" @@ -7990,8 +9522,10 @@ args: ${CVSROOT_DIRNAME}/first-dir/subdir" Are you sure you want to release (and delete) directory .realmodule.: " dotest modules5-15 "${testcvs} -q rtag -Dnow MYTAG realmodule" \ "tag script invoked in ${TESTDIR}/1 +args: realmodule MYTAG" \ +"tag script invoked in $tmp/cvs-serv[0-9a-z]* args: realmodule MYTAG" - if test "$remote" = "yes"; then + if $remote; then dotest modules5-16 "${testcvs} -q export -r MYTAG realmodule" \ "U realmodule/a export script invoked in .* @@ -8010,7 +9544,7 @@ args: realmodule" # FIXCVS: The client gets confused in these cases and tries to # store the scripts in the wrong places. - if test "$remote" != "yes"; then + if $remote; then :; else # Now test the ability to check out a single file from a directory dotest modules5-18 "${testcvs} co dirmodule/a" \ "U dirmodule/a @@ -8149,7 +9683,7 @@ $PROG [a-z]*: Rebuilding administrative file database" echo "TopLevelAdmin=yes" >config dotest cvsadm-setup-2 "${testcvs} -q ci -m yes-top-level" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -8222,12 +9756,12 @@ ${PROG} [a-z]*: Examining CVSROOT" mkdir mod2-2 mkdir mod2-2/sub2-2 dotest cvsadm-2a "${testcvs} add mod1 mod1-2 mod2 mod2/sub2 mod2-2 mod2-2/sub2-2" \ -"Directory ${TESTDIR}/cvsroot/mod1 added to the repository -Directory ${TESTDIR}/cvsroot/mod1-2 added to the repository -Directory ${TESTDIR}/cvsroot/mod2 added to the repository -Directory ${TESTDIR}/cvsroot/mod2/sub2 added to the repository -Directory ${TESTDIR}/cvsroot/mod2-2 added to the repository -Directory ${TESTDIR}/cvsroot/mod2-2/sub2-2 added to the repository" +"Directory ${CVSROOT_DIRNAME}/mod1 added to the repository +Directory ${CVSROOT_DIRNAME}/mod1-2 added to the repository +Directory ${CVSROOT_DIRNAME}/mod2 added to the repository +Directory ${CVSROOT_DIRNAME}/mod2/sub2 added to the repository +Directory ${CVSROOT_DIRNAME}/mod2-2 added to the repository +Directory ${CVSROOT_DIRNAME}/mod2-2/sub2-2 added to the repository" # Populate the directories for the halibut echo "file1" > mod1/file1 @@ -8327,7 +9861,7 @@ U dir2d1/sub2d1/file1" dotest cvsadm-7b "cat CVS/Repository" \ "${AREP}\." dotest cvsadm-7d "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-7f "cat dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" rm -rf CVS dir2d1 @@ -8338,7 +9872,7 @@ U dir2d2/sub2d2/file2" dotest cvsadm-8b "cat CVS/Repository" \ "${AREP}\." dotest cvsadm-8d "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-8f "cat dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS dir2d2 @@ -8428,7 +9962,7 @@ U dir2d1/sub2d1/file1" "${AREP}mod1" # the usual for 2d1mod dotest cvsadm-13f "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}." dotest cvsadm-13h "cat dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" rm -rf CVS 1mod dir2d1 @@ -8446,7 +9980,7 @@ U dir2d2/sub2d2/file2" "${AREP}mod1" # the usual for 2d2mod dotest cvsadm-14f "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-14h "cat dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS 1mod dir2d2 @@ -8516,7 +10050,7 @@ U dir2d1/sub2d1/file1" "${AREP}mod2/sub2" # the usual for 2d1mod dotest cvsadm-18f "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}." dotest cvsadm-18h "cat dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" rm -rf CVS 2mod dir2d1 @@ -8534,7 +10068,7 @@ U dir2d2/sub2d2/file2" "${AREP}mod2/sub2" # the usual for 2d2mod dotest cvsadm-19f "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-19h "cat dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS 2mod dir2d2 @@ -8587,7 +10121,7 @@ U dir2d1/sub2d1/file1" "${AREP}mod1" # the usual for 2d1mod dotest cvsadm-22f "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-22h "cat dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" rm -rf CVS dir1d1 dir2d1 @@ -8605,7 +10139,7 @@ U dir2d2/sub2d2/file2" "${AREP}mod1" # the usual for 2d2mod dotest cvsadm-23f "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-23h "cat dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS dir1d1 dir2d2 @@ -8642,7 +10176,7 @@ U dir2d1/sub2d1/file1" "${AREP}mod2/sub2" # the usual for 2d1mod dotest cvsadm-25f "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-25h "cat dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" rm -rf CVS dir1d2 dir2d1 @@ -8660,7 +10194,7 @@ U dir2d2/sub2d2/file2" "${AREP}mod2/sub2" # the usual for 2d2mod dotest cvsadm-26f "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-26h "cat dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS dir1d2 dir2d2 @@ -8678,12 +10212,12 @@ U dir2d1-2/sub2d1-2/file1-2" "${AREP}\." # the usual for 2d1mod dotest cvsadm-27d "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-27f "cat dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" # the usual for 2d1mod dotest cvsadm-27h "cat dir2d1-2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-27j "cat dir2d1-2/sub2d1-2/CVS/Repository" \ "${AREP}mod1-2" rm -rf CVS dir2d1 dir2d1-2 @@ -8698,12 +10232,12 @@ U dir2d2/sub2d2/file2" "${AREP}\." # the usual for 2d1mod dotest cvsadm-28d "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-28f "cat dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" # the usual for 2d2mod dotest cvsadm-28h "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-28j "cat dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS dir2d1 dir2d2 @@ -8721,12 +10255,12 @@ U dir2d2-2/sub2d2-2/file2-2" "${AREP}\." # the usual for 2d2mod dotest cvsadm-29d "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-29f "cat dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" # the usual for 2d2mod dotest cvsadm-29h "cat dir2d2-2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2-2" dotest cvsadm-29j "cat dir2d2-2/sub2d2-2/CVS/Repository" \ "${AREP}mod2-2/sub2-2" rm -rf CVS dir2d2 dir2d2-2 @@ -8885,7 +10419,7 @@ U dir/dir2d1/sub2d1/file1" "${AREP}mod1" # the usual for 2d1mod dotest cvsadm-1d13h "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-1d13j "cat dir/dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" rm -rf CVS dir @@ -8905,7 +10439,7 @@ U dir/dir2d2/sub2d2/file2" "${AREP}mod1" # the usual for 2d2mod dotest cvsadm-1d14h "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-1d14j "cat dir/dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS dir @@ -8922,7 +10456,7 @@ U dir/2mod-2/file2-2" "${AREP}\." # the usual for the dir level dotest cvsadm-1d15d "cat dir/CVS/Repository" \ -"${AREP}\." +"${AREP}mod2" # the usual for 2mod dotest cvsadm-1d15f "cat dir/2mod/CVS/Repository" \ "${AREP}mod2/sub2" @@ -8940,7 +10474,7 @@ U dir/dir1d1/file1" "${AREP}\." # the usual for the dir level dotest cvsadm-1d16d "cat dir/CVS/Repository" \ -"${AREP}\." +"${AREP}mod2" # the usual for 2mod dotest cvsadm-1d16f "cat dir/2mod/CVS/Repository" \ "${AREP}mod2/sub2" @@ -8958,7 +10492,7 @@ U dir/dir1d2/file2" "${AREP}\." # the usual for the dir level dotest cvsadm-1d17d "cat dir/CVS/Repository" \ -"${AREP}\." +"${AREP}mod2" # the usual for 2mod dotest cvsadm-1d17f "cat dir/2mod/CVS/Repository" \ "${AREP}mod2/sub2" @@ -8976,13 +10510,13 @@ U dir/dir2d1/sub2d1/file1" "${AREP}\." # the usual for the dir level dotest cvsadm-1d18d "cat dir/CVS/Repository" \ -"${AREP}\." +"${AREP}mod2" # the usual for 2mod dotest cvsadm-1d18f "cat dir/2mod/CVS/Repository" \ "${AREP}mod2/sub2" # the usual for 2d1mod dotest cvsadm-1d18h "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-1d18j "cat dir/dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" rm -rf CVS dir @@ -8996,13 +10530,13 @@ U dir/dir2d2/sub2d2/file2" "${AREP}\." # the usual for the dir level dotest cvsadm-1d19d "cat dir/CVS/Repository" \ -"${AREP}\." +"${AREP}mod2" # the usual for 2mod dotest cvsadm-1d19f "cat dir/2mod/CVS/Repository" \ "${AREP}mod2/sub2" # the usual for 2d2mod dotest cvsadm-1d19h "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-1d19j "cat dir/dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS dir @@ -9061,7 +10595,7 @@ U dir/dir2d1/sub2d1/file1" "${AREP}mod1" # the usual for 2d1mod dotest cvsadm-1d22h "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-1d22j "cat dir/dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" rm -rf CVS dir @@ -9081,7 +10615,7 @@ U dir/dir2d2/sub2d2/file2" "${AREP}mod1" # the usual for 2d2mod dotest cvsadm-1d23h "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-1d23j "cat dir/dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS dir @@ -9098,7 +10632,7 @@ U dir/dir1d2-2/file2-2" "${AREP}\." # the usual for the dir level dotest cvsadm-1d24d "cat dir/CVS/Repository" \ -"${AREP}\." +"${AREP}mod2" # the usual for 1d2mod dotest cvsadm-1d24f "cat dir/dir1d2/CVS/Repository" \ "${AREP}mod2/sub2" @@ -9116,13 +10650,13 @@ U dir/dir2d1/sub2d1/file1" "${AREP}\." # the usual for the dir level dotest cvsadm-1d25d "cat dir/CVS/Repository" \ -"${AREP}\." +"${AREP}mod2" # the usual for 1d2mod dotest cvsadm-1d25f "cat dir/dir1d2/CVS/Repository" \ "${AREP}mod2/sub2" # the usual for 2d1mod dotest cvsadm-1d25h "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-1d25j "cat dir/dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" rm -rf CVS dir @@ -9136,13 +10670,13 @@ U dir/dir2d2/sub2d2/file2" "${AREP}\." # the usual for the dir level dotest cvsadm-1d26d "cat dir/CVS/Repository" \ -"${AREP}\." +"${AREP}mod2" # the usual for 1d2mod dotest cvsadm-1d26f "cat dir/dir1d2/CVS/Repository" \ "${AREP}mod2/sub2" # the usual for 2d2mod dotest cvsadm-1d26h "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-1d26j "cat dir/dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS dir @@ -9159,15 +10693,15 @@ U dir/dir2d1-2/sub2d1-2/file1-2" "${AREP}\." # the usual for the dir level dotest cvsadm-1d27d "cat dir/CVS/Repository" \ -"${AREP}\." +"${AREP}CVSROOT/Emptydir" # the usual for 2d1mod dotest cvsadm-1d27f "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-1d27h "cat dir/dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" # the usual for 2d1mod dotest cvsadm-1d27j "cat dir/dir2d1-2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-1d27l "cat dir/dir2d1-2/sub2d1-2/CVS/Repository" \ "${AREP}mod1-2" rm -rf CVS dir @@ -9181,15 +10715,15 @@ U dir/dir2d2/sub2d2/file2" "${AREP}\." # the usual for the dir level dotest cvsadm-1d28d "cat dir/CVS/Repository" \ -"${AREP}\." +"${AREP}CVSROOT/Emptydir" # the usual for 2d1mod dotest cvsadm-1d28f "cat dir/dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}\." dotest cvsadm-1d28h "cat dir/dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" # the usual for 2d2mod dotest cvsadm-1d28j "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-1d28l "cat dir/dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" rm -rf CVS dir @@ -9209,12 +10743,12 @@ U dir/dir2d2-2/sub2d2-2/file2-2" "${AREP}\." # the usual for 2d2mod dotest cvsadm-1d29f "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2" dotest cvsadm-1d29h "cat dir/dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" # the usual for 2d2mod dotest cvsadm-1d29j "cat dir/dir2d2-2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" +"${AREP}mod2-2" dotest cvsadm-1d29l "cat dir/dir2d2-2/sub2d2-2/CVS/Repository" \ "${AREP}mod2-2/sub2-2" rm -rf CVS dir @@ -9228,283 +10762,283 @@ U dir/dir2d2-2/sub2d2-2/file2-2" "${PROG} [a-z]*: cannot chdir to dir: No such file or directory ${PROG} [a-z]*: ignoring module 1mod" - if test "$remote" = no; then - # Remote can't handle this, even with the "mkdir dir". - # This was also true of CVS 1.9. + if $remote; then :; else + # Remote can't handle this, even with the "mkdir dir". + # This was also true of CVS 1.9. - mkdir dir - dotest cvsadm-2d3 "${testcvs} co -d dir/dir2 1mod" \ + mkdir dir + dotest cvsadm-2d3 "${testcvs} co -d dir/dir2 1mod" \ "${PROG} [a-z]*: Updating dir/dir2 U dir/dir2/file1" - dotest cvsadm-2d3b "cat CVS/Repository" \ + dotest cvsadm-2d3b "cat CVS/Repository" \ "${AREP}\." - dotest_fail cvsadm-2d3d "test -f dir/CVS/Repository" "" - dotest cvsadm-2d3f "cat dir/dir2/CVS/Repository" \ + dotest_fail cvsadm-2d3d "test -f dir/CVS/Repository" "" + dotest cvsadm-2d3f "cat dir/dir2/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir + rm -rf CVS dir - mkdir dir - dotest cvsadm-2d4 "${testcvs} co -d dir/dir2 2mod" \ + mkdir dir + dotest cvsadm-2d4 "${testcvs} co -d dir/dir2 2mod" \ "${PROG} [a-z]*: Updating dir/dir2 U dir/dir2/file2" - dotest cvsadm-2d4b "cat CVS/Repository" \ + dotest cvsadm-2d4b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-2d4f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-2d4f "cat dir/dir2/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir + rm -rf CVS dir - mkdir dir - dotest cvsadm-2d5 "${testcvs} co -d dir/dir2 1d1mod" \ + mkdir dir + dotest cvsadm-2d5 "${testcvs} co -d dir/dir2 1d1mod" \ "${PROG} [a-z]*: Updating dir/dir2 U dir/dir2/file1" - dotest cvsadm-2d5b "cat CVS/Repository" \ + dotest cvsadm-2d5b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-2d5f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-2d5f "cat dir/dir2/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir + rm -rf CVS dir - mkdir dir - dotest cvsadm-2d6 "${testcvs} co -d dir/dir2 1d2mod" \ + mkdir dir + dotest cvsadm-2d6 "${testcvs} co -d dir/dir2 1d2mod" \ "${PROG} [a-z]*: Updating dir/dir2 U dir/dir2/file2" - dotest cvsadm-2d6b "cat CVS/Repository" \ + dotest cvsadm-2d6b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-2d6f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-2d6f "cat dir/dir2/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir + rm -rf CVS dir - mkdir dir - dotest cvsadm-2d7 "${testcvs} co -d dir/dir2 2d1mod" \ + mkdir dir + dotest cvsadm-2d7 "${testcvs} co -d dir/dir2 2d1mod" \ "${PROG} [a-z]*: Updating dir/dir2 U dir/dir2/file1" - dotest cvsadm-2d7b "cat CVS/Repository" \ + dotest cvsadm-2d7b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-2d7f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-2d7f "cat dir/dir2/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir + rm -rf CVS dir - mkdir dir - dotest cvsadm-2d8 "${testcvs} co -d dir/dir2 2d2mod" \ + mkdir dir + dotest cvsadm-2d8 "${testcvs} co -d dir/dir2 2d2mod" \ "${PROG} [a-z]*: Updating dir/dir2 U dir/dir2/file2" - dotest cvsadm-2d8b "cat CVS/Repository" \ + dotest cvsadm-2d8b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-2d8f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-2d8f "cat dir/dir2/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir + rm -rf CVS dir - ################################################## - ## And now, a few of those tests revisited to - ## test the behavior of the -N flag. - ################################################## + ################################################## + ## And now, a few of those tests revisited to + ## test the behavior of the -N flag. + ################################################## - dotest cvsadm-N3 "${testcvs} co -N 1mod" \ + dotest cvsadm-N3 "${testcvs} co -N 1mod" \ "${PROG} [a-z]*: Updating 1mod U 1mod/file1" - dotest cvsadm-N3b "cat CVS/Repository" \ + dotest cvsadm-N3b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N3d "cat 1mod/CVS/Repository" \ + dotest cvsadm-N3d "cat 1mod/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS 1mod + rm -rf CVS 1mod - dotest cvsadm-N4 "${testcvs} co -N 2mod" \ + dotest cvsadm-N4 "${testcvs} co -N 2mod" \ "${PROG} [a-z]*: Updating 2mod U 2mod/file2" - dotest cvsadm-N4b "cat CVS/Repository" \ + dotest cvsadm-N4b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N4d "cat 2mod/CVS/Repository" \ + dotest cvsadm-N4d "cat 2mod/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS 2mod + rm -rf CVS 2mod - dotest cvsadm-N5 "${testcvs} co -N 1d1mod" \ + dotest cvsadm-N5 "${testcvs} co -N 1d1mod" \ "${PROG} [a-z]*: Updating dir1d1 U dir1d1/file1" - dotest cvsadm-N5b "cat CVS/Repository" \ + dotest cvsadm-N5b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N5d "cat dir1d1/CVS/Repository" \ + dotest cvsadm-N5d "cat dir1d1/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir1d1 + rm -rf CVS dir1d1 - dotest cvsadm-N6 "${testcvs} co -N 1d2mod" \ + dotest cvsadm-N6 "${testcvs} co -N 1d2mod" \ "${PROG} [a-z]*: Updating dir1d2 U dir1d2/file2" - dotest cvsadm-N6b "cat CVS/Repository" \ + dotest cvsadm-N6b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N6d "cat dir1d2/CVS/Repository" \ + dotest cvsadm-N6d "cat dir1d2/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir1d2 + rm -rf CVS dir1d2 - dotest cvsadm-N7 "${testcvs} co -N 2d1mod" \ + dotest cvsadm-N7 "${testcvs} co -N 2d1mod" \ "${PROG} [a-z]*: Updating dir2d1/sub2d1 U dir2d1/sub2d1/file1" - dotest cvsadm-N7b "cat CVS/Repository" \ + dotest cvsadm-N7b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N7d "cat dir2d1/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N7f "cat dir2d1/sub2d1/CVS/Repository" \ + dotest cvsadm-N7d "cat dir2d1/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N7f "cat dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir2d1 + rm -rf CVS dir2d1 - dotest cvsadm-N8 "${testcvs} co -N 2d2mod" \ + dotest cvsadm-N8 "${testcvs} co -N 2d2mod" \ "${PROG} [a-z]*: Updating dir2d2/sub2d2 U dir2d2/sub2d2/file2" - dotest cvsadm-N8b "cat CVS/Repository" \ + dotest cvsadm-N8b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N8d "cat dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N8f "cat dir2d2/sub2d2/CVS/Repository" \ + dotest cvsadm-N8d "cat dir2d2/CVS/Repository" \ +"${AREP}mod2" + dotest cvsadm-N8f "cat dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir2d2 + rm -rf CVS dir2d2 - ## the ones in one-deep directories + ## the ones in one-deep directories - dotest cvsadm-N1d3 "${testcvs} co -N -d dir 1mod" \ + dotest cvsadm-N1d3 "${testcvs} co -N -d dir 1mod" \ "${PROG} [a-z]*: Updating dir/1mod U dir/1mod/file1" - dotest cvsadm-N1d3b "cat CVS/Repository" \ + dotest cvsadm-N1d3b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N1d3d "cat dir/CVS/Repository" \ + dotest cvsadm-N1d3d "cat dir/CVS/Repository" \ "${AREP}\." - dotest cvsadm-N1d3f "cat dir/1mod/CVS/Repository" \ + dotest cvsadm-N1d3f "cat dir/1mod/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir + rm -rf CVS dir - dotest cvsadm-N1d4 "${testcvs} co -N -d dir 2mod" \ + dotest cvsadm-N1d4 "${testcvs} co -N -d dir 2mod" \ "${PROG} [a-z]*: Updating dir/2mod U dir/2mod/file2" - dotest cvsadm-N1d4b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d4d "cat dir/CVS/Repository" \ + dotest cvsadm-N1d4b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N1d4f "cat dir/2mod/CVS/Repository" \ + dotest cvsadm-N1d4d "cat dir/CVS/Repository" \ +"${AREP}mod2" + dotest cvsadm-N1d4f "cat dir/2mod/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir + rm -rf CVS dir - dotest cvsadm-N1d5 "${testcvs} co -N -d dir 1d1mod" \ + dotest cvsadm-N1d5 "${testcvs} co -N -d dir 1d1mod" \ "${PROG} [a-z]*: Updating dir/dir1d1 U dir/dir1d1/file1" - dotest cvsadm-N1d5b "cat CVS/Repository" \ + dotest cvsadm-N1d5b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N1d5d "cat dir/CVS/Repository" \ + dotest cvsadm-N1d5d "cat dir/CVS/Repository" \ "${AREP}\." - dotest cvsadm-N1d5d "cat dir/dir1d1/CVS/Repository" \ + dotest cvsadm-N1d5d "cat dir/dir1d1/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir + rm -rf CVS dir - dotest cvsadm-N1d6 "${testcvs} co -N -d dir 1d2mod" \ + dotest cvsadm-N1d6 "${testcvs} co -N -d dir 1d2mod" \ "${PROG} [a-z]*: Updating dir/dir1d2 U dir/dir1d2/file2" - dotest cvsadm-N1d6b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d6d "cat dir/CVS/Repository" \ + dotest cvsadm-N1d6b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N1d6f "cat dir/dir1d2/CVS/Repository" \ + dotest cvsadm-N1d6d "cat dir/CVS/Repository" \ +"${AREP}mod2" + dotest cvsadm-N1d6f "cat dir/dir1d2/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir + rm -rf CVS dir - dotest cvsadm-N1d7 "${testcvs} co -N -d dir 2d1mod" \ + dotest cvsadm-N1d7 "${testcvs} co -N -d dir 2d1mod" \ "${PROG} [a-z]*: Updating dir/dir2d1/sub2d1 U dir/dir2d1/sub2d1/file1" - dotest cvsadm-N1d7b "cat CVS/Repository" \ + dotest cvsadm-N1d7b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N1d7d "cat dir/CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N1d7f "cat dir/dir2d1/CVS/Repository" \ + dotest cvsadm-N1d7d "cat dir/CVS/Repository" \ "${AREP}CVSROOT/Emptydir" - dotest cvsadm-N1d7h "cat dir/dir2d1/sub2d1/CVS/Repository" \ + dotest cvsadm-N1d7f "cat dir/dir2d1/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N1d7h "cat dir/dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir + rm -rf CVS dir - dotest cvsadm-N1d8 "${testcvs} co -N -d dir 2d2mod" \ + dotest cvsadm-N1d8 "${testcvs} co -N -d dir 2d2mod" \ "${PROG} [a-z]*: Updating dir/dir2d2/sub2d2 U dir/dir2d2/sub2d2/file2" - dotest cvsadm-N1d8b "cat CVS/Repository" \ + dotest cvsadm-N1d8b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N1d8d "cat dir/CVS/Repository" \ + dotest cvsadm-N1d8d "cat dir/CVS/Repository" \ "${AREP}\." - dotest cvsadm-N1d8d "cat dir/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N1d8d "cat dir/dir2d2/sub2d2/CVS/Repository" \ + dotest cvsadm-N1d8d "cat dir/dir2d2/CVS/Repository" \ +"${AREP}mod2" + dotest cvsadm-N1d8d "cat dir/dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir + rm -rf CVS dir - ## the ones in two-deep directories + ## the ones in two-deep directories - mkdir dir - dotest cvsadm-N2d3 "${testcvs} co -N -d dir/dir2 1mod" \ + mkdir dir + dotest cvsadm-N2d3 "${testcvs} co -N -d dir/dir2 1mod" \ "${PROG} [a-z]*: Updating dir/dir2/1mod U dir/dir2/1mod/file1" - dotest cvsadm-N2d3b "cat CVS/Repository" \ + dotest cvsadm-N2d3b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N2d3f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-N2d3f "cat dir/dir2/CVS/Repository" \ "${AREP}\." - dotest cvsadm-N2d3h "cat dir/dir2/1mod/CVS/Repository" \ + dotest cvsadm-N2d3h "cat dir/dir2/1mod/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir + rm -rf CVS dir - mkdir dir - dotest cvsadm-N2d4 "${testcvs} co -N -d dir/dir2 2mod" \ + mkdir dir + dotest cvsadm-N2d4 "${testcvs} co -N -d dir/dir2 2mod" \ "${PROG} [a-z]*: Updating dir/dir2/2mod U dir/dir2/2mod/file2" - dotest cvsadm-N2d4b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d4f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-N2d4b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N2d4h "cat dir/dir2/2mod/CVS/Repository" \ + dotest cvsadm-N2d4f "cat dir/dir2/CVS/Repository" \ +"${AREP}mod2" + dotest cvsadm-N2d4h "cat dir/dir2/2mod/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir + rm -rf CVS dir - mkdir dir - dotest cvsadm-N2d5 "${testcvs} co -N -d dir/dir2 1d1mod" \ + mkdir dir + dotest cvsadm-N2d5 "${testcvs} co -N -d dir/dir2 1d1mod" \ "${PROG} [a-z]*: Updating dir/dir2/dir1d1 U dir/dir2/dir1d1/file1" - dotest cvsadm-N2d5b "cat CVS/Repository" \ + dotest cvsadm-N2d5b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N2d5f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-N2d5f "cat dir/dir2/CVS/Repository" \ "${AREP}\." - dotest cvsadm-N2d5h "cat dir/dir2/dir1d1/CVS/Repository" \ + dotest cvsadm-N2d5h "cat dir/dir2/dir1d1/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir + rm -rf CVS dir - mkdir dir - dotest cvsadm-N2d6 "${testcvs} co -N -d dir/dir2 1d2mod" \ + mkdir dir + dotest cvsadm-N2d6 "${testcvs} co -N -d dir/dir2 1d2mod" \ "${PROG} [a-z]*: Updating dir/dir2/dir1d2 U dir/dir2/dir1d2/file2" - dotest cvsadm-N2d6b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d6f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-N2d6b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N2d6h "cat dir/dir2/dir1d2/CVS/Repository" \ + dotest cvsadm-N2d6f "cat dir/dir2/CVS/Repository" \ +"${AREP}mod2" + dotest cvsadm-N2d6h "cat dir/dir2/dir1d2/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir + rm -rf CVS dir - mkdir dir - dotest cvsadm-N2d7 "${testcvs} co -N -d dir/dir2 2d1mod" \ + mkdir dir + dotest cvsadm-N2d7 "${testcvs} co -N -d dir/dir2 2d1mod" \ "${PROG} [a-z]*: Updating dir/dir2/dir2d1/sub2d1 U dir/dir2/dir2d1/sub2d1/file1" - dotest cvsadm-N2d7b "cat CVS/Repository" \ -"${AREP}\." - dotest cvsadm-N2d7f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-N2d7b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N2d7f "cat dir/dir2/dir2d1/CVS/Repository" \ + dotest cvsadm-N2d7f "cat dir/dir2/CVS/Repository" \ "${AREP}CVSROOT/Emptydir" - dotest cvsadm-N2d7h "cat dir/dir2/dir2d1/sub2d1/CVS/Repository" \ + dotest cvsadm-N2d7g "cat dir/dir2/dir2d1/CVS/Repository" \ +"${AREP}\." + dotest cvsadm-N2d7h "cat dir/dir2/dir2d1/sub2d1/CVS/Repository" \ "${AREP}mod1" - rm -rf CVS dir + rm -rf CVS dir - mkdir dir - dotest cvsadm-N2d8 "${testcvs} co -N -d dir/dir2 2d2mod" \ + mkdir dir + dotest cvsadm-N2d8 "${testcvs} co -N -d dir/dir2 2d2mod" \ "${PROG} [a-z]*: Updating dir/dir2/dir2d2/sub2d2 U dir/dir2/dir2d2/sub2d2/file2" - dotest cvsadm-N2d8b "cat CVS/Repository" \ + dotest cvsadm-N2d8b "cat CVS/Repository" \ "${AREP}\." - dotest cvsadm-N2d8f "cat dir/dir2/CVS/Repository" \ + dotest cvsadm-N2d8f "cat dir/dir2/CVS/Repository" \ "${AREP}\." - dotest cvsadm-N2d8h "cat dir/dir2/dir2d2/CVS/Repository" \ -"${AREP}CVSROOT/Emptydir" - dotest cvsadm-N2d8j "cat dir/dir2/dir2d2/sub2d2/CVS/Repository" \ + dotest cvsadm-N2d8h "cat dir/dir2/dir2d2/CVS/Repository" \ +"${AREP}mod2" + dotest cvsadm-N2d8j "cat dir/dir2/dir2d2/sub2d2/CVS/Repository" \ "${AREP}mod2/sub2" - rm -rf CVS dir + rm -rf CVS dir fi # end of tests to be skipped for remote @@ -9518,7 +11052,7 @@ U dir/dir2/dir2d2/sub2d2/file2" echo "# empty file" >config dotest cvsadm-cleanup-2 "${testcvs} -q ci -m cvsadm-cleanup" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -9547,9 +11081,10 @@ ${PROG} [a-z]*: Rebuilding administrative file database" dotest emptydir-1 "${testcvs} co CVSROOT/modules" \ "U CVSROOT/modules" echo "# Module defs for emptydir tests" > CVSROOT/modules - echo "2d1mod -d dir2d1/sub2d1 mod1" >> CVSROOT/modules + echo "2d1mod -d dir2d1/sub/sub2d1 mod1" >> CVSROOT/modules echo "2d1moda -d dir2d1/suba moda/modasub" >> CVSROOT/modules - echo "comb -a 2d1mod 2d1moda" >> CVSROOT/modules + echo "2d1modb -d dir2d1/suba mod1" >> CVSROOT/modules + echo "comb -a 2d1modb 2d1moda" >> CVSROOT/modules dotest emptydir-2 "${testcvs} ci -m add-modules" \ "${PROG} [a-z]*: Examining CVSROOT @@ -9570,7 +11105,7 @@ ${PROG} [a-z]*: Updating moda" echo "file1" > mod1/file1 mkdir moda/modasub dotest emptydir-3b "${testcvs} add moda/modasub" \ -"Directory ${TESTDIR}/cvsroot/moda/modasub added to the repository" +"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 @@ -9593,8 +11128,8 @@ done" # End Populate. dotest emptydir-6 "${testcvs} co 2d1mod" \ -"${PROG} [a-z]*: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" +"${PROG} [a-z]*: Updating dir2d1/sub/sub2d1 +U dir2d1/sub/sub2d1/file1" cd dir2d1 touch emptyfile # It doesn't make any sense to add a file (or do much of anything @@ -9602,10 +11137,10 @@ U dir2d1/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 ${TESTDIR}/cvsroot/CVSROOT/Emptydir" +"${PROG} \[[a-z]* aborted\]: cannot add to ${CVSROOT_DIRNAME}/CVSROOT/Emptydir" mkdir emptydir dotest_fail emptydir-8 "${testcvs} add emptydir" \ -"${PROG} \[[a-z]* aborted\]: cannot add to ${TESTDIR}/cvsroot/CVSROOT/Emptydir" +"${PROG} \[[a-z]* aborted\]: cannot add to ${CVSROOT_DIRNAME}/CVSROOT/Emptydir" cd .. rm -rf CVS dir2d1 @@ -9626,15 +11161,16 @@ U dir2d1/sub2d1/file1" mkdir 2; cd 2 dotest emptydir-12 "${testcvs} -q co 2d1moda" \ "U dir2d1/suba/filea" - # OK, this is the crux of the matter. Some people think - # it would be more logical if this showed "moda". But why - # "moda" (from module 2d1moda) and not "." (from module 2d1mod)? - dotest emptydir-13 "cat dir2d1/CVS/Repository" "CVSROOT/Emptydir" - dotest emptydir-14 "${testcvs} co comb" \ -"${PROG} [a-z]*: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1 + # OK, this is the crux of the matter. This used to show "Emptydir", + # but everyone seemed to think it should show "moda". This + # usually works better, but not always as shown by the following + # 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" - dotest emptydir-15 "cat dir2d1/CVS/Repository" "CVSROOT/Emptydir" + dotest emptydir-15 "cat dir2d1/CVS/Repository" "moda" cd .. rm -r 1 2 @@ -9692,14 +11228,14 @@ done" # Done. # Try checking out the module in a local directory - if test "$remote" = yes; then + if $remote; then dotest_fail abspath-2a "${testcvs} co -d ${TESTDIR}/1 mod1" \ "${PROG} \[server aborted\]: absolute pathname .${TESTDIR}/1. illegal for server" dotest abspath-2a-try2 "${testcvs} co -d 1 mod1" \ "${PROG} [a-z]*: Updating 1 U 1/file1" else - dotest abspath-2a "${testcvs} co -d ${TESTDIR}/1 mod1" \ + dotest abspath-2a "${testcvs} co -d ${TESTDIR}/1 mod1" \ "${PROG} [a-z]*: Updating ${TESTDIR}/1 U ${TESTDIR}/1/file1" fi # remote workaround @@ -9731,8 +11267,8 @@ U ${TESTDIR}/1/file1" # "touch 1/2/3" requires directories 1 and 1/2 to already # exist, we expect ${TESTDIR}/1 to already exist. I believe # this is the behavior of CVS 1.9 and earlier. - if test "$remote" = no; then - dotest_fail abspath-3.1 "${testcvs} co -d ${TESTDIR}/1/2 mod1" \ + if $remote; then :; else + dotest_fail abspath-3.1 "${testcvs} co -d ${TESTDIR}/1/2 mod1" \ "${PROG} [a-z]*: cannot chdir to 1: No such file or directory ${PROG} [a-z]*: ignoring module mod1" fi @@ -9741,7 +11277,7 @@ ${PROG} [a-z]*: ignoring module mod1" ${PROG} [a-z]*: ignoring module mod1" mkdir 1 - if test "$remote" = yes; then + if $remote; then # The server wants the directory to exist, but that is # a bug, it should only need to exist on the client side. # See also cvsadm-2d3. @@ -9774,8 +11310,8 @@ U ${TESTDIR}/1/2/file1" # Now try someplace where we don't have permission. mkdir ${TESTDIR}/barf chmod -w ${TESTDIR}/barf - if test "$remote" = yes; then - dotest_fail abspath-4 "${testcvs} co -d ${TESTDIR}/barf/sub mod1" \ + 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" \ @@ -9787,8 +11323,8 @@ U ${TESTDIR}/1/2/file1" # Try checking out two modules into the same directory. - if test "$remote" = yes; then - dotest abspath-5a "${testcvs} co -d 1 mod1 mod2" \ + if $remote; then + dotest abspath-5ar "${testcvs} co -d 1 mod1 mod2" \ "${PROG} [a-z]*: Updating 1/mod1 U 1/mod1/file1 ${PROG} [a-z]*: Updating 1/mod2 @@ -9811,8 +11347,8 @@ U ${TESTDIR}/1/mod2/file2" # Try checking out the top-level module. - if test "$remote" = yes; then - dotest abspath-6a "${testcvs} co -d 1 ." \ + if $remote; then + dotest abspath-6ar "${testcvs} co -d 1 ." \ "${PROG} [a-z]*: Updating 1 ${PROG} [a-z]*: Updating 1/CVSROOT ${DOTSTAR} @@ -9845,25 +11381,25 @@ U ${TESTDIR}/1/mod2/file2" # doesn't mess with the current working directory. mkdir 1 cd 1 - if test "$remote" = yes; then - dotest_fail abspath-7a "${testcvs} -q co -d ../2 mod2" \ + 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" cd .. - dotest abspath-7a-try2 "${testcvs} -q co -d 2 mod2" \ + dotest abspath-7a-try2r "${testcvs} -q co -d 2 mod2" \ "U 2/file2" cd 1 else - dotest abspath-7a "${testcvs} -q co -d ${TESTDIR}/2 mod2" \ + dotest abspath-7a "${testcvs} -q co -d ${TESTDIR}/2 mod2" \ "U ${TESTDIR}/2/file2" fi # remote workaround dotest abspath-7b "ls" "" dotest abspath-7c "${testcvs} -q co mod1" \ "U mod1/file1" cd mod1 - if test "$remote" = yes; then + if $remote; then cd ../.. - dotest abspath-7d "${testcvs} -q co -d 3 mod2" \ + dotest abspath-7dr "${testcvs} -q co -d 3 mod2" \ "U 3/file2" cd 1/mod1 else @@ -9902,7 +11438,7 @@ ${PROG} \[server aborted\]: than the 0 which Max-dotdot specified" echo "TopLevelAdmin=yes" >config dotest toplevel-1b "${testcvs} -q ci -m yes-top-level" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -9913,8 +11449,8 @@ ${PROG} [a-z]*: Rebuilding administrative file database" dotest toplevel-1 "${testcvs} -q co -l ." '' mkdir top-dir second-dir dotest toplevel-2 "${testcvs} add top-dir second-dir" \ -"Directory ${TESTDIR}/cvsroot/top-dir added to the repository -Directory ${TESTDIR}/cvsroot/second-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/top-dir added to the repository +Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" cd top-dir touch file1 @@ -9922,10 +11458,10 @@ Directory ${TESTDIR}/cvsroot/second-dir added to the repository" "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest toplevel-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/top-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/top-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/top-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/top-dir/file1,v <-- file1 initial revision: 1\.1 done" cd .. @@ -9936,10 +11472,10 @@ done" "${PROG} [a-z]*: scheduling file .file2. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest toplevel-4s "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/second-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/second-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/second-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/second-dir/file2,v <-- file2 initial revision: 1\.1 done" @@ -9998,6 +11534,7 @@ U top-dir/file1" "${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" @@ -10010,7 +11547,7 @@ ${PROG} [a-z]*: Updating top-dir" echo "# empty file" >config dotest toplevel-cleanup-2 "${testcvs} -q ci -m toplevel-cleanup" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -10031,7 +11568,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database" echo "TopLevelAdmin=no" >config dotest toplevel2-1b "${testcvs} -q ci -m no-top-level" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -10043,8 +11580,8 @@ ${PROG} [a-z]*: Rebuilding administrative file database" dotest toplevel2-1 "${testcvs} -q co -l ." '' mkdir top-dir second-dir dotest toplevel2-2 "${testcvs} add top-dir second-dir" \ -"Directory ${TESTDIR}/cvsroot/top-dir added to the repository -Directory ${TESTDIR}/cvsroot/second-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/top-dir added to the repository +Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" cd top-dir touch file1 @@ -10052,10 +11589,10 @@ Directory ${TESTDIR}/cvsroot/second-dir added to the repository" "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest toplevel2-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/top-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/top-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/top-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/top-dir/file1,v <-- file1 initial revision: 1\.1 done" cd .. @@ -10066,10 +11603,10 @@ done" "${PROG} [a-z]*: scheduling file .file2. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest toplevel2-4s "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/second-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/second-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/second-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/second-dir/file2,v <-- file2 initial revision: 1\.1 done" @@ -10106,7 +11643,7 @@ U top-dir/file1" echo "# empty file" >config dotest toplevel2-cleanup-2 "${testcvs} -q ci -m toplevel2-cleanup" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -10190,7 +11727,7 @@ EOF dotest editor-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest editor-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir touch file1 file2 dotest editor-3 "${testcvs} add file1 file2" \ @@ -10198,16 +11735,16 @@ EOF ${PROG} [a-z]*: scheduling file .file2. for addition ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest editor-4 "${testcvs} -e ${TESTDIR}/editme -q ci" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done" dotest editor-5 "${testcvs} -q tag -b br" "T file1 @@ -10216,7 +11753,7 @@ T file2" echo modify >>file1 dotest editor-7 "${testcvs} -e ${TESTDIR}/editme -q ci" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" # OK, now we want to make sure "ci -r" puts in the branch @@ -10228,12 +11765,12 @@ done" echo add a line >>file2 dotest editor-9 "${testcvs} -q -e ${TESTDIR}/editme ci -rbr file2" \ "Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" dotest editor-log-file1 "${testcvs} log -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -10246,7 +11783,6 @@ description: revision 1\.1 date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; branches: 1\.1\.2; -x xCVS: ---------------------------------------------------------------------- xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically xCVS: @@ -10258,7 +11794,6 @@ xCVS: ---------------------------------------------------------------------- ---------------------------- revision 1\.1\.2\.1 date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -x xCVS: ---------------------------------------------------------------------- xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically xCVS: @@ -10273,7 +11808,7 @@ xCVS: ---------------------------------------------------------------------- # The only difference between the two expect strings is the # presence or absence of "Committing in ." for 1.1.2.1. dotest editor-log-file2 "${testcvs} log -N file2" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v Working file: file2 head: 1\.1 branch: @@ -10286,7 +11821,6 @@ description: revision 1\.1 date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; branches: 1\.1\.2; -x xCVS: ---------------------------------------------------------------------- xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically xCVS: @@ -10298,7 +11832,6 @@ xCVS: ---------------------------------------------------------------------- ---------------------------- revision 1\.1\.2\.1 date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -x xCVS: ---------------------------------------------------------------------- xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically xCVS: @@ -10307,7 +11840,7 @@ xCVS: Tag: br xCVS: file2 xCVS: ---------------------------------------------------------------------- =============================================================================" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v Working file: file2 head: 1\.1 branch: @@ -10320,7 +11853,6 @@ description: revision 1\.1 date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; branches: 1\.1\.2; -x xCVS: ---------------------------------------------------------------------- xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically xCVS: @@ -10332,7 +11864,6 @@ xCVS: ---------------------------------------------------------------------- ---------------------------- revision 1\.1\.2\.1 date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -x xCVS: ---------------------------------------------------------------------- xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically xCVS: @@ -10393,20 +11924,11 @@ xCVS: ---------------------------------------------------------------------- fi cd ../../2/1dir - # FIXME: should be using dotest. - ${testcvs} -q update 2>../tst167.err - cat ../tst167.err >>${LOGFILE} - cat <../tst167.ans -${PROG} server: warning: foo is not (any longer) pertinent -${PROG} update: unable to remove ./foo: Permission denied -EOF - if cmp ../tst167.ans ../tst167.err >/dev/null || - ( echo "${PROG} [update aborted]: cannot rename file foo to CVS/,,foo: Permission denied" | cmp - ../tst167.err >/dev/null ) - then - pass 168 - else - fail 168 - fi + dotest 168 "${testcvs} -q update" \ +"${PROG} [a-z]*: 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" cd .. chmod u+w 1dir @@ -10428,7 +11950,7 @@ EOF dotest errmsg2-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest errmsg2-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir dotest_fail errmsg2-3 "${testcvs} add CVS" \ "${PROG} [a-z]*: cannot add special file .CVS.; skipping" @@ -10453,16 +11975,16 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" # Make sure that none of the error messages left droppings # which interfere with normal operation. dotest errmsg2-7 "${testcvs} -q ci -m add-file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" mkdir sdir cd .. dotest errmsg2-8 "${testcvs} add first-dir/sdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/sdir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" # while we're here... check commit with no CVS directory dotest_fail errmsg2-8a "${testcvs} -q ci first-dir nonexistant" \ "${PROG} [a-z]*: nothing known about .nonexistant' @@ -10478,13 +12000,13 @@ ${PROG} \[[a-z]* aborted\]: correct above errors first!" mkdir sdir10 dotest errmsg2-10 "${testcvs} add file10 sdir10" \ "${PROG} [a-z]*: scheduling file .file10. for addition -Directory ${TESTDIR}/cvsroot/first-dir/sdir10 added to the repository +Directory ${CVSROOT_DIRNAME}/first-dir/sdir10 added to the repository ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest errmsg2-11 "${testcvs} -q ci -m add-file10" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file10,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file10,v done Checking in file10; -${TESTDIR}/cvsroot/first-dir/file10,v <-- file10 +${CVSROOT_DIRNAME}/first-dir/file10,v <-- file10 initial revision: 1\.1 done" # Try to see that there are no droppings left by @@ -10496,7 +12018,7 @@ done" cd .. mkdir first-dir/sdir10/ssdir dotest errmsg2-13 "${testcvs} add first-dir/sdir10/ssdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/sdir10/ssdir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/sdir10/ssdir added to the repository" touch first-dir/sdir10/ssdir/ssfile dotest errmsg2-14 \ @@ -10527,26 +12049,23 @@ ${PROG} \[add aborted\]: no repository" # or directory which already is there. dotest errmsg2-17 "${testcvs} -q ci -m checkin" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file15,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file15,v done Checking in first-dir/file15; -${TESTDIR}/cvsroot/first-dir/file15,v <-- file15 +${CVSROOT_DIRNAME}/first-dir/file15,v <-- file15 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/sdir10/ssdir/ssfile,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir10/ssdir/ssfile,v done Checking in first-dir/sdir10/ssdir/ssfile; -${TESTDIR}/cvsroot/first-dir/sdir10/ssdir/ssfile,v <-- ssfile +${CVSROOT_DIRNAME}/first-dir/sdir10/ssdir/ssfile,v <-- ssfile initial revision: 1\.1 done" dotest errmsg2-18 "${testcvs} -Q tag test" '' - dotest_fail errmsg2-19 "${testcvs} annotate -rtest -Dyesterday" \ -"${PROG} \[[a-z]* aborted\]: rcsbuf_open: internal error" - # trying to import the repository - if test "$remote" = "no"; then + 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" @@ -10556,7 +12075,57 @@ done" cd .. rm -r 1 - rm -rf ${TESTDIR}/cvsroot/first-dir + rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + + adderrmsg) + # Test some of the error messages the 'add' command can return and + # their reactions to '-q'. + + # First the usual setup; create a directory first-dir. + mkdir 1; cd 1 + dotest adderrmsg-init1 "${testcvs} -q co -l ." '' + mkdir adderrmsg-dir + dotest adderrmsg-init2 "${testcvs} add adderrmsg-dir" \ +"Directory ${CVSROOT_DIRNAME}/adderrmsg-dir added to the repository" + cd adderrmsg-dir + + # try to add the admin dir + dotest_fail adderrmsg-1 "${testcvs} add CVS" \ +"${PROG} [a-z]*: cannot add special file .CVS.; skipping" + # might not want to see this message when you 'cvs add *' + dotest_fail adderrmsg-2 "${testcvs} -q add CVS" "" + + # 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" + + # add it twice + dotest_fail adderrmsg-4 "${testcvs} add file1" \ +"${PROG} [a-z]*: file1 has already been entered" + dotest_fail adderrmsg-5 "${testcvs} -q add file1" "" + + dotest adderrmsg-6 "${testcvs} -q ci -madd" \ +"RCS file: ${CVSROOT_DIRNAME}/adderrmsg-dir/file1,v +done +Checking in file1; +${CVSROOT_DIRNAME}/adderrmsg-dir/file1,v <-- file1 +initial revision: 1\.1 +done" + + # file in Entries & repository + dotest_fail adderrmsg-7 "${testcvs} add file1" \ +"${PROG} [a-z]*: file1 already exists, with version number 1\.1" + dotest_fail adderrmsg-8 "${testcvs} -q add file1" "" + + # clean up + cd ../.. + if $keep; then :; else + rm -r 1 + rm -rf ${CVSROOT_DIRNAME}/adderrmsg-dir + fi ;; devcom) @@ -10769,7 +12338,7 @@ U first-dir/abc' dotest_fail devcom-some3 "test -w first-dir/abc" '' cd .. - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -10922,7 +12491,7 @@ G@#..!@#=&" # Now test disconnected "cvs edit" and the format of the # CVS/Notify file. - if test "$remote" = yes; then + if $remote; then CVS_SERVER_SAVED=${CVS_SERVER} CVS_SERVER=${TESTDIR}/cvs-none; export CVS_SERVER @@ -10931,18 +12500,18 @@ G@#..!@#=&" # (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-9a "${testcvs} edit w1" \ + dotest_fail devcom3-9ar "${testcvs} edit w1" \ "${PROG} \[edit aborted\]: cannot exec ${TESTDIR}/cvs-none: ${DOTSTAR}" - dotest devcom3-9b "test -w w1" "" - dotest devcom3-9c "cat CVS/Notify" \ + 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 - dotest devcom3-9d "${testcvs} -q update" "" - dotest_fail devcom3-9e "test -f CVS/Notify" "" - dotest devcom3-9f "${testcvs} watchers w1" \ + dotest devcom3-9dr "${testcvs} -q update" "" + dotest_fail devcom3-9er "test -f CVS/Notify" "" + dotest devcom3-9fr "${testcvs} watchers w1" \ "w1 ${username} tedit tunedit tcommit" - dotest devcom3-9g "${testcvs} unedit w1" "" - dotest devcom3-9h "${testcvs} watchers w1" "" + dotest devcom3-9gr "${testcvs} unedit w1" "" + dotest devcom3-9hr "${testcvs} watchers w1" "" fi cd ../.. @@ -10969,7 +12538,7 @@ G@#..!@#=&" dotest watch4-0a "${testcvs} -q co -l ." '' mkdir first-dir dotest watch4-0b "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir dotest watch4-1 "${testcvs} watch on" '' @@ -10979,26 +12548,26 @@ G@#..!@#=&" "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest watch4-3 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" # Now test the analogous behavior for directories. mkdir subdir dotest watch4-4 "${testcvs} add subdir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/subdir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" 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" dotest watch4-6 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/sfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v done Checking in sfile; -${TESTDIR}/cvsroot/first-dir/subdir/sfile,v <-- sfile +${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v <-- sfile initial revision: 1\.1 done" cd ../../.. @@ -11017,13 +12586,13 @@ U first-dir/subdir/sfile" echo 'edited in 1' >file1 dotest watch4-12 "${testcvs} -q ci -m edit-in-1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" cd ../.. cd 2/first-dir dotest watch4-13 "${testcvs} -q update" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.1 retrieving revision 1\.2 Merging differences between 1\.1 and 1\.2 into file1 @@ -11075,7 +12644,7 @@ C file1" dotest watch5-0a "${testcvs} -q co -l ." '' mkdir first-dir dotest watch5-0b "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir dotest watch5-1 "${testcvs} watch on" '' @@ -11085,10 +12654,10 @@ C file1" "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest watch5-3 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" dotest watch5-4 "${testcvs} edit file1" '' @@ -11145,8 +12714,8 @@ ${PROG} unedit: run update to complete the unedit" dotest unedit-without-baserev-5 "cat CVS/Entries" \ "/$file/1\.1\.1\.1/${DOTSTAR}" - if test "$remote" = yes; then - dotest unedit-without-baserev-6 "${testcvs} -q update" "U m" + if $remote; then + dotest unedit-without-baserev-6r "${testcvs} -q update" "U m" else dotest unedit-without-baserev-6 "${testcvs} -q update" \ "${PROG} update: warning: m was lost @@ -11172,13 +12741,13 @@ U m" echo 'edited in 1' >m dotest unedit-without-baserev-12 "${testcvs} -q ci -m edit-in-1" \ "Checking in m; -${TESTDIR}/cvsroot/x/m,v <-- m +${CVSROOT_DIRNAME}/x/m,v <-- m new revision: 1\.2; previous revision: 1\.1 done" cd ../.. cd 2/x dotest unedit-without-baserev-13 "${testcvs} -q update" \ -"RCS file: ${TESTDIR}/cvsroot/x/m,v +"RCS file: ${CVSROOT_DIRNAME}/x/m,v retrieving revision 1\.1\.1\.1 retrieving revision 1\.2 Merging differences between 1\.1\.1\.1 and 1\.2 into m @@ -11189,8 +12758,8 @@ C m" echo yes | dotest unedit-without-baserev-14 "${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 test "$remote" = yes; then - dotest unedit-without-baserev-15 "${testcvs} -q update" "U m" + if $remote; then + dotest unedit-without-baserev-15r "${testcvs} -q update" "U m" else dotest unedit-without-baserev-15 "${testcvs} -q update" \ "${PROG} update: warning: m was lost @@ -11213,32 +12782,32 @@ U m" ignore) # On Windows, we can't check out CVSROOT, because the case # insensitivity means that this conflicts with cvsroot. - mkdir wnt - cd wnt + mkdir ignore + cd ignore - dotest 187a1 "${testcvs} -q co CVSROOT" "U CVSROOT/${DOTSTAR}" + dotest ignore-1 "${testcvs} -q co CVSROOT" "U CVSROOT/${DOTSTAR}" cd CVSROOT echo rootig.c >cvsignore - dotest 187a2 "${testcvs} add cvsignore" "${PROG}"' [a-z]*: scheduling file `cvsignore'"'"' for addition + 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' # As of Jan 96, local CVS prints "Examining ." and remote doesn't. # Accept either. - dotest 187a3 " ${testcvs} ci -m added" \ + dotest ignore-3 " ${testcvs} ci -m added" \ "${PROG} [a-z]*: Examining \. -RCS file: ${TESTDIR}/cvsroot/CVSROOT/cvsignore,v +RCS file: ${CVSROOT_DIRNAME}/CVSROOT/cvsignore,v done Checking in cvsignore; -${TESTDIR}/cvsroot/CVSROOT/cvsignore,v <-- cvsignore +${CVSROOT_DIRNAME}/CVSROOT/cvsignore,v <-- cvsignore initial revision: 1\.1 done ${PROG} [a-z]*: Rebuilding administrative file database" cd .. if echo "yes" | ${testcvs} release -d CVSROOT >>${LOGFILE} ; then - pass 187a4 + pass ignore-4 else - fail 187a4 + fail ignore-4 fi # CVS looks at the home dir from getpwuid, not HOME (is that correct @@ -11250,46 +12819,46 @@ ${PROG} [a-z]*: Rebuilding administrative file database" touch foobar.c bar.c rootig.c defig.o envig.c optig.c # We use sort because we can't predict the order in which # the files will be listed. - dotest_sort 188a "${testcvs} import -m m -I optig.c first-dir tag1 tag2" \ + dotest_sort ignore-5 "${testcvs} import -m m -I optig.c ignore/first-dir tag1 tag2" \ ' -I first-dir/defig.o -I first-dir/envig.c -I first-dir/optig.c -I first-dir/rootig.c -N first-dir/bar.c -N first-dir/foobar.c +I ignore/first-dir/defig.o +I ignore/first-dir/envig.c +I ignore/first-dir/optig.c +I ignore/first-dir/rootig.c +N ignore/first-dir/bar.c +N ignore/first-dir/foobar.c No conflicts created by this import' - dotest_sort 188b "${testcvs} import -m m -I ! second-dir tag3 tag4" \ + dotest_sort ignore-6 "${testcvs} import -m m -I ! ignore/second-dir tag3 tag4" \ ' -N second-dir/bar.c -N second-dir/defig.o -N second-dir/envig.c -N second-dir/foobar.c -N second-dir/optig.c -N second-dir/rootig.c +N ignore/second-dir/bar.c +N ignore/second-dir/defig.o +N ignore/second-dir/envig.c +N ignore/second-dir/foobar.c +N ignore/second-dir/optig.c +N ignore/second-dir/rootig.c No conflicts created by this import' cd .. rm -r dir-to-import mkdir 1 cd 1 - dotest 189a "${testcvs} -q co second-dir" \ + dotest ignore-7 "${testcvs} -q co -dsecond-dir ignore/second-dir" \ 'U second-dir/bar.c U second-dir/defig.o U second-dir/envig.c U second-dir/foobar.c U second-dir/optig.c U second-dir/rootig.c' - dotest 189b "${testcvs} -q co first-dir" 'U first-dir/bar.c + dotest ignore-8 "${testcvs} -q co -dfirst-dir ignore/first-dir" 'U first-dir/bar.c U first-dir/foobar.c' cd first-dir touch rootig.c defig.o envig.c optig.c notig.c - dotest 189c "${testcvs} -q update -I optig.c" "${QUESTION} notig.c" + dotest ignore-9 "${testcvs} -q update -I optig.c" "${QUESTION} notig.c" # The fact that CVS requires us to specify -I CVS here strikes me # as a bug. - dotest_sort 189d "${testcvs} -q update -I ! -I CVS" \ + dotest_sort ignore-10 "${testcvs} -q update -I ! -I CVS" \ "${QUESTION} defig.o ${QUESTION} envig.c ${QUESTION} notig.c @@ -11300,8 +12869,8 @@ ${QUESTION} rootig.c" # where appropriate. Only test this for remote, because local # CVS only prints it on update. rm optig.c - if test "x$remote" = xyes; then - dotest 189e "${testcvs} -q diff" "${QUESTION} notig.c" + if $remote; then + dotest ignore-11r "${testcvs} -q diff" "${QUESTION} notig.c" # Force the server to be contacted. Ugh. Having CVS # contact the server for the sole purpose of checking @@ -11312,7 +12881,7 @@ ${QUESTION} rootig.c" # contents. touch bar.c - dotest 189f "${testcvs} -q ci -m commit-it" "${QUESTION} notig.c" + dotest ignore-11r "${testcvs} -q ci -m commit-it" "${QUESTION} notig.c" fi # now test .cvsignore files @@ -11320,11 +12889,11 @@ ${QUESTION} rootig.c" echo notig.c >first-dir/.cvsignore echo foobar.c >second-dir/.cvsignore touch first-dir/notig.c second-dir/notig.c second-dir/foobar.c - dotest_sort 190 "${testcvs} -qn update" \ + dotest_sort ignore-12 "${testcvs} -qn update" \ "${QUESTION} first-dir/.cvsignore ${QUESTION} second-dir/.cvsignore ${QUESTION} second-dir/notig.c" - dotest_sort 191 "${testcvs} -qn update -I! -I CVS" \ + dotest_sort ignore-13 "${testcvs} -qn update -I! -I CVS" \ "${QUESTION} first-dir/.cvsignore ${QUESTION} first-dir/defig.o ${QUESTION} first-dir/envig.c @@ -11332,22 +12901,93 @@ ${QUESTION} first-dir/rootig.c ${QUESTION} second-dir/.cvsignore ${QUESTION} second-dir/notig.c" - echo yes | dotest ignore-192 "${testcvs} release -d first-dir" \ + echo yes | dotest ignore-14 "${testcvs} release -d first-dir" \ "${QUESTION} \.cvsignore You have \[0\] altered files in this repository. Are you sure you want to release (and delete) directory .first-dir': " echo add a line >>second-dir/foobar.c rm second-dir/notig.c second-dir/.cvsignore - echo yes | dotest ignore-194 "${testcvs} release -d second-dir" \ + echo yes | dotest ignore-15 "${testcvs} release -d second-dir" \ "M foobar.c You have \[1\] altered files in this repository. Are you sure you want to release (and delete) directory .second-dir': " + + cd ../.. + if $keep; then :; else + rm -r ignore + rm -rf ${CVSROOT_DIRNAME}/ignore + fi + ;; + + ignore-on-branch) + # Test that CVS _doesn't_ ignore files on branches because they were + # added to the trunk. + mkdir ignore-on-branch; cd ignore-on-branch + mkdir $CVSROOT_DIRNAME/ignore-on-branch + + # create file1 & file2 on trunk + dotest ignore-on-branch-setup-1 "$testcvs -q co -dsetup ignore-on-branch" '' + cd setup + echo file1 >file1 + dotest ignore-on-branch-setup-2 "$testcvs -q add file1" \ +"$PROG [a-z]*: use .cvs commit. to add this file permanently" + dotest ignore-on-branch-setup-3 "$testcvs -q ci -mfile1 file1" \ +"RCS file: $CVSROOT_DIRNAME/ignore-on-branch/file1,v +done +Checking in file1; +$CVSROOT_DIRNAME/ignore-on-branch/file1,v <-- file1 +initial revision: 1\.1 +done" + dotest ignore-on-branch-setup-4 "$testcvs -q tag -b branch" 'T file1' + echo file2 >file2 + dotest ignore-on-branch-setup-5 "$testcvs -q add file2" \ +"$PROG [a-z]*: use .cvs commit. to add this file permanently" + dotest ignore-on-branch-setup-6 "$testcvs -q ci -mtrunk file2" \ +"RCS file: $CVSROOT_DIRNAME/ignore-on-branch/file2,v +done +Checking in file2; +$CVSROOT_DIRNAME/ignore-on-branch/file2,v <-- file2 +initial revision: 1\.1 +done" + cd .. - rm -r 1 - cd .. - rm -r wnt - rm -rf ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/second-dir + + # Check out branch. + # + # - This was the original failure case - file2 would not be flagged + # with a '?' + dotest ignore-on-branch-1 "$testcvs -q co -rbranch ignore-on-branch" \ +'U ignore-on-branch/file1' + cd ignore-on-branch + echo file2 on branch >file2 + dotest ignore-on-branch-2 "$testcvs -nq update" '? file2' + + # Now set up for a join. One of the original fixes for this would + # print out a 'U' and a '?' during a join which added a file. + if $remote; then + dotest ignore-on-branch-3 "$testcvs -q tag -b branch2" \ +'? file2 +T file1' + else + dotest ignore-on-branch-3 "$testcvs -q tag -b branch2" 'T file1' + fi + dotest ignore-on-branch-4 "$testcvs -q add file2" \ +"$PROG [a-z]*: use .cvs commit. to add this file permanently" + 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" + dotest ignore-on-branch-7 "$testcvs -q up -jbranch" 'U file2' + + cd ../.. + if $keep; then :; else + rm -r ignore-on-branch + rm -rf $CVSROOT_DIRNAME/ignore-on-branch + fi ;; binfiles) @@ -11371,10 +13011,10 @@ Are you sure you want to release (and delete) directory .second-dir': " "${PROG}"' [a-z]*: scheduling file `binfile'\'' for addition '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest binfiles-3 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/binfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v done Checking in binfile; -${TESTDIR}/cvsroot/first-dir/binfile,v <-- binfile +${CVSROOT_DIRNAME}/first-dir/binfile,v <-- binfile initial revision: 1\.1 done" cd ../.. @@ -11390,7 +13030,7 @@ done" File: binfile Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/binfile,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb" @@ -11408,7 +13048,7 @@ File: binfile Status: Up-to-date File: binfile Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/binfile,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb" @@ -11419,7 +13059,7 @@ File: binfile Status: Up-to-date cp ../../1/binfile2.dat binfile dotest binfiles-6 "${testcvs} -q ci -m modify-it" \ "Checking in binfile; -${TESTDIR}/cvsroot/first-dir/binfile,v <-- binfile +${CVSROOT_DIRNAME}/first-dir/binfile,v <-- binfile new revision: 1\.2; previous revision: 1\.1 done" cd ../../1/first-dir @@ -11430,7 +13070,7 @@ done" cp ../binfile.dat binfile dotest binfiles-con0 "${testcvs} -q ci -m modify-it" \ "Checking in binfile; -${TESTDIR}/cvsroot/first-dir/binfile,v <-- binfile +${CVSROOT_DIRNAME}/first-dir/binfile,v <-- binfile new revision: 1\.3; previous revision: 1\.2 done" cd ../../2/first-dir @@ -11447,7 +13087,7 @@ C binfile" cp ../../1/binfile2.dat binfile dotest binfiles-con4 "${testcvs} -q ci -m resolve-it" \ "Checking in binfile; -${TESTDIR}/cvsroot/first-dir/binfile,v <-- binfile +${CVSROOT_DIRNAME}/first-dir/binfile,v <-- binfile new revision: 1\.4; previous revision: 1\.3 done" cd ../../1/first-dir @@ -11471,7 +13111,7 @@ done" File: binfile Status: Up-to-date Working revision: 1\.4.* - Repository revision: 1\.4 ${TESTDIR}/cvsroot/first-dir/binfile,v + Repository revision: 1\.4 ${CVSROOT_DIRNAME}/first-dir/binfile,v Sticky Tag: HEAD (revision: 1\.4) Sticky Date: (none) Sticky Options: -kb" @@ -11482,7 +13122,7 @@ File: binfile Status: Up-to-date echo 'this file is $''RCSfile$' >binfile dotest binfiles-14a "${testcvs} -q ci -m modify-it" \ "Checking in binfile; -${TESTDIR}/cvsroot/first-dir/binfile,v <-- binfile +${CVSROOT_DIRNAME}/first-dir/binfile,v <-- binfile new revision: 1\.5; previous revision: 1\.4 done" dotest binfiles-14b "cat binfile" 'this file is $''RCSfile$' @@ -11492,12 +13132,12 @@ done" File: binfile Status: Up-to-date Working revision: 1\.5.* - Repository revision: 1\.5 ${TESTDIR}/cvsroot/first-dir/binfile,v + Repository revision: 1\.5 ${CVSROOT_DIRNAME}/first-dir/binfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb" dotest binfiles-14d "${testcvs} admin -kv binfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/binfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v done" # cvs admin doesn't change the checked-out file or its sticky # kopts. There probably should be a way which does (but @@ -11509,7 +13149,7 @@ done" File: binfile Status: Up-to-date Working revision: 1\.5.* - Repository revision: 1\.5 ${TESTDIR}/cvsroot/first-dir/binfile,v + Repository revision: 1\.5 ${CVSROOT_DIRNAME}/first-dir/binfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb" @@ -11520,7 +13160,7 @@ File: binfile Status: Up-to-date File: binfile Status: Up-to-date Working revision: 1\.5.* - Repository revision: 1\.5 ${TESTDIR}/cvsroot/first-dir/binfile,v + Repository revision: 1\.5 ${CVSROOT_DIRNAME}/first-dir/binfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kv" @@ -11530,10 +13170,10 @@ File: binfile Status: Up-to-date dotest binfiles-sticky1 "${testcvs} -q add nibfile" \ "${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest binfiles-sticky2 "${testcvs} -q ci -m add-it nibfile" \ - "RCS file: ${TESTDIR}/cvsroot/first-dir/nibfile,v + "RCS file: ${CVSROOT_DIRNAME}/first-dir/nibfile,v done Checking in nibfile; -${TESTDIR}/cvsroot/first-dir/nibfile,v <-- nibfile +${CVSROOT_DIRNAME}/first-dir/nibfile,v <-- nibfile initial revision: 1\.1 done" dotest binfiles-sticky3 "${testcvs} -q update -kb nibfile" \ @@ -11543,7 +13183,7 @@ done" File: nibfile Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/nibfile,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/nibfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb" @@ -11556,12 +13196,12 @@ File: nibfile Status: Up-to-date File: nibfile Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/nibfile,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/nibfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none)" dotest binfiles-15 "${testcvs} -q admin -kb nibfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/nibfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/nibfile,v done" dotest binfiles-16 "${testcvs} -q update nibfile" "[UP] nibfile" dotest binfiles-17 "${testcvs} -q status nibfile" \ @@ -11569,23 +13209,23 @@ done" File: nibfile Status: Up-to-date Working revision: 1\.1.* - Repository revision: 1\.1 ${TESTDIR}/cvsroot/first-dir/nibfile,v + Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/nibfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb" dotest binfiles-o1 "${testcvs} admin -o1.3:: binfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/binfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v deleting revision 1\.5 deleting revision 1\.4 done" dotest binfiles-o2 "${testcvs} admin -o::1.3 binfile" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/binfile,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v deleting revision 1\.2 deleting revision 1\.1 done" dotest binfiles-o3 "${testcvs} -q log -h -N binfile" " -RCS file: ${TESTDIR}/cvsroot/first-dir/binfile,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v Working file: binfile head: 1\.3 branch: @@ -11652,22 +13292,22 @@ ${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" dotest binfiles2-1b "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/brmod,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod,v done Checking in brmod; -${TESTDIR}/cvsroot/first-dir/brmod,v <-- brmod +${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/brmod-trmod,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v done Checking in brmod-trmod; -${TESTDIR}/cvsroot/first-dir/brmod-trmod,v <-- brmod-trmod +${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/brmod-wdmod,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v done Checking in brmod-wdmod; -${TESTDIR}/cvsroot/first-dir/brmod-wdmod,v <-- brmod-wdmod +${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod initial revision: 1\.1 done" dotest binfiles2-2 "${testcvs} -q tag -b br" 'T brmod @@ -11682,26 +13322,26 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" cp ../binfile2 brmod-trmod cp ../binfile2 brmod-wdmod dotest binfiles2-5 "${testcvs} -q ci -m br-changes" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/binfile\.dat,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/binfile\.dat,v done Checking in binfile\.dat; -${TESTDIR}/cvsroot/first-dir/Attic/binfile\.dat,v <-- binfile\.dat +${CVSROOT_DIRNAME}/first-dir/Attic/binfile\.dat,v <-- binfile\.dat new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in brmod; -${TESTDIR}/cvsroot/first-dir/brmod,v <-- brmod +${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in brmod-trmod; -${TESTDIR}/cvsroot/first-dir/brmod-trmod,v <-- brmod-trmod +${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in brmod-wdmod; -${TESTDIR}/cvsroot/first-dir/brmod-wdmod,v <-- brmod-wdmod +${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]*: warning: binfile\.dat is not (any longer) pertinent +"${PROG} [a-z]*: binfile\.dat is no longer in the repository [UP] brmod [UP] brmod-trmod [UP] brmod-wdmod" @@ -11710,7 +13350,7 @@ done" cp ../binfile3 brmod-trmod dotest binfiles2-7a "${testcvs} -q ci -m tr-modify" \ "Checking in brmod-trmod; -${TESTDIR}/cvsroot/first-dir/brmod-trmod,v <-- brmod-trmod +${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod new revision: 1\.2; previous revision: 1\.1 done" cp ../binfile3 brmod-wdmod @@ -11738,38 +13378,38 @@ C brmod-wdmod" # Test that everything was properly scheduled. dotest binfiles2-10 "${testcvs} -q ci -m checkin" \ "Checking in binfile\.dat; -${TESTDIR}/cvsroot/first-dir/binfile\.dat,v <-- binfile\.dat +${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v <-- binfile\.dat new revision: 1\.2; previous revision: 1\.1 done Checking in brmod; -${TESTDIR}/cvsroot/first-dir/brmod,v <-- brmod +${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod new revision: 1\.2; previous revision: 1\.1 done Checking in brmod-trmod; -${TESTDIR}/cvsroot/first-dir/brmod-trmod,v <-- brmod-trmod +${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod new revision: 1\.3; previous revision: 1\.2 done Checking in brmod-wdmod; -${TESTDIR}/cvsroot/first-dir/brmod-wdmod,v <-- brmod-wdmod +${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod new revision: 1\.2; previous revision: 1\.1 done" dotest_fail binfiles2-o1 "${testcvs} -q admin -o :1.2 brmod-trmod" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/brmod-trmod,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v deleting revision 1\.2 -${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/brmod-trmod,v: can't remove branch point 1\.1 -${PROG} [a-z]*: cannot modify RCS file for .brmod-trmod." +${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\." dotest binfiles2-o2 "${testcvs} -q admin -o 1.1.2.1: brmod-trmod" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/brmod-trmod,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v deleting revision 1\.1\.2\.1 done" dotest binfiles2-o3 "${testcvs} -q admin -o :1.2 brmod-trmod" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/brmod-trmod,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v deleting revision 1\.2 deleting revision 1\.1 done" dotest binfiles2-o4 "${testcvs} -q log -N brmod-trmod" " -RCS file: ${TESTDIR}/cvsroot/first-dir/brmod-trmod,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v Working file: brmod-trmod head: 1\.3 branch: @@ -11804,10 +13444,10 @@ checkin "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest binfiles3-3 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" rm file1 @@ -11816,7 +13456,7 @@ done" ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" dotest binfiles3-5 "${testcvs} -q ci -m remove-it" \ "Removing file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: delete; previous revision: 1\.1 done" cp ../binfile.dat file1 @@ -11835,11 +13475,11 @@ D" dotest binfiles3-7 "${testcvs} -q ci -m readd-it" \ "${PROG} [a-z]*: changing keyword expansion mode to -kb Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.3; previous revision: 1\.2 done" dotest binfiles3-8 "${testcvs} -q log -h -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.3 branch: @@ -11859,17 +13499,17 @@ total revisions: 3 cp ../binfile4.dat file1 dotest binfiles3-9 "${testcvs} -q ci -m change" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.4; previous revision: 1\.3 done" cp ../binfile5.dat file1 dotest binfiles3-10 "${testcvs} -q ci -m change" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.5; previous revision: 1\.4 done" dotest binfiles3-11 "${testcvs} admin -o 1.3::1.5 file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v deleting revision 1\.4 done" dotest binfiles3-12 "${testcvs} -q update -r 1.3 file1" "U file1" @@ -11899,98 +13539,98 @@ done" # For the moment, remote CVS can't pass wrappers from CVSWRAPPERS # (see wrap_send). So skip these tests for remote. - if test "x$remote" = xno; then + if $remote; then :; else - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1; cd 1 - dotest mcopy-1 "${testcvs} -q co first-dir" '' - cd first-dir + mkdir ${CVSROOT_DIRNAME}/first-dir + mkdir 1; cd 1 + dotest mcopy-1 "${testcvs} -q co first-dir" '' + cd first-dir - # FIXCVS: unless a branch has at least one file on it, - # tag_check_valid won't know it exists. So if brmod didn't - # exist, we would have to invent it. - echo 'brmod initial contents' >brmod - echo 'brmod-trmod initial contents' >brmod-trmod - echo 'brmod-wdmod initial contents' >brmod-wdmod - echo "* -m 'COPY'" >.cvswrappers - dotest mcopy-1a \ + # FIXCVS: unless a branch has at least one file on it, + # tag_check_valid won't know it exists. So if brmod didn't + # exist, we would have to invent it. + echo 'brmod initial contents' >brmod + echo 'brmod-trmod initial contents' >brmod-trmod + echo 'brmod-wdmod initial contents' >brmod-wdmod + 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" - dotest mcopy-1b "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/\.cvswrappers,v + dotest mcopy-1b "${testcvs} -q ci -m add" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/\.cvswrappers,v done Checking in \.cvswrappers; -${TESTDIR}/cvsroot/first-dir/\.cvswrappers,v <-- \.cvswrappers +${CVSROOT_DIRNAME}/first-dir/\.cvswrappers,v <-- \.cvswrappers initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/brmod,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod,v done Checking in brmod; -${TESTDIR}/cvsroot/first-dir/brmod,v <-- brmod +${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/brmod-trmod,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v done Checking in brmod-trmod; -${TESTDIR}/cvsroot/first-dir/brmod-trmod,v <-- brmod-trmod +${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/brmod-wdmod,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v done Checking in brmod-wdmod; -${TESTDIR}/cvsroot/first-dir/brmod-wdmod,v <-- brmod-wdmod +${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod initial revision: 1\.1 done" - # NOTE: .cvswrappers files are broken (see comment in - # src/wrapper.c). So doing everything via the environment - # variable is a workaround. Better would be to test them - # both. - CVSWRAPPERS="* -m 'COPY'" - export CVSWRAPPERS - dotest mcopy-2 "${testcvs} -q tag -b br" 'T \.cvswrappers + # NOTE: .cvswrappers files are broken (see comment in + # src/wrapper.c). So doing everything via the environment + # variable is a workaround. Better would be to test them + # both. + CVSWRAPPERS="* -m 'COPY'" + export CVSWRAPPERS + dotest mcopy-2 "${testcvs} -q tag -b br" 'T \.cvswrappers T brmod T brmod-trmod T brmod-wdmod' - dotest mcopy-3 "${testcvs} -q update -r br" '' - echo 'modify brmod on br' >brmod - echo 'modify brmod-trmod on br' >brmod-trmod - echo 'modify brmod-wdmod on br' >brmod-wdmod - dotest mcopy-5 "${testcvs} -q ci -m br-changes" \ + dotest mcopy-3 "${testcvs} -q update -r br" '' + echo 'modify brmod on br' >brmod + echo 'modify brmod-trmod on br' >brmod-trmod + echo 'modify brmod-wdmod on br' >brmod-wdmod + dotest mcopy-5 "${testcvs} -q ci -m br-changes" \ "Checking in brmod; -${TESTDIR}/cvsroot/first-dir/brmod,v <-- brmod +${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in brmod-trmod; -${TESTDIR}/cvsroot/first-dir/brmod-trmod,v <-- brmod-trmod +${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in brmod-wdmod; -${TESTDIR}/cvsroot/first-dir/brmod-wdmod,v <-- brmod-wdmod +${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod new revision: 1\.1\.2\.1; previous revision: 1\.1 done" - dotest mcopy-6 "${testcvs} -q update -A" \ + dotest mcopy-6 "${testcvs} -q update -A" \ "[UP] brmod [UP] brmod-trmod [UP] brmod-wdmod" - dotest mcopy-7 "cat brmod brmod-trmod brmod-wdmod" \ + dotest mcopy-7 "cat brmod brmod-trmod brmod-wdmod" \ "brmod initial contents brmod-trmod initial contents brmod-wdmod initial contents" - echo 'modify brmod-trmod again on trunk' >brmod-trmod - dotest mcopy-7a "${testcvs} -q ci -m tr-modify" \ + echo 'modify brmod-trmod again on trunk' >brmod-trmod + dotest mcopy-7a "${testcvs} -q ci -m tr-modify" \ "Checking in brmod-trmod; -${TESTDIR}/cvsroot/first-dir/brmod-trmod,v <-- brmod-trmod +${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod new revision: 1\.2; previous revision: 1\.1 done" - echo 'modify brmod-wdmod in working dir' >brmod-wdmod + echo 'modify brmod-wdmod in working dir' >brmod-wdmod - dotest mcopy-8 "${testcvs} -q update -j br" \ + 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 @@ -12002,34 +13642,34 @@ ${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 C brmod-wdmod" - dotest mcopy-9 "cat brmod brmod-trmod brmod-wdmod" \ + dotest mcopy-9 "cat brmod brmod-trmod brmod-wdmod" \ "modify brmod on br modify brmod-trmod on br modify brmod-wdmod on br" - dotest mcopy-9a "cat .#brmod-trmod.1.2 .#brmod-wdmod.1.1" \ + dotest mcopy-9a "cat .#brmod-trmod.1.2 .#brmod-wdmod.1.1" \ "modify brmod-trmod again on trunk modify brmod-wdmod in working dir" - # Test that everything was properly scheduled. - dotest mcopy-10 "${testcvs} -q ci -m checkin" \ + # Test that everything was properly scheduled. + dotest mcopy-10 "${testcvs} -q ci -m checkin" \ "Checking in brmod; -${TESTDIR}/cvsroot/first-dir/brmod,v <-- brmod +${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod new revision: 1\.2; previous revision: 1\.1 done Checking in brmod-trmod; -${TESTDIR}/cvsroot/first-dir/brmod-trmod,v <-- brmod-trmod +${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod new revision: 1\.3; previous revision: 1\.2 done Checking in brmod-wdmod; -${TESTDIR}/cvsroot/first-dir/brmod-wdmod,v <-- brmod-wdmod +${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod new revision: 1\.2; previous revision: 1\.1 done" - cd .. - cd .. + cd .. + cd .. - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r 1 - unset CVSWRAPPERS + rm -rf ${CVSROOT_DIRNAME}/first-dir + rm -r 1 + unset CVSWRAPPERS fi # end of tests to be skipped for remote @@ -12063,7 +13703,7 @@ U first-dir/foo.exe' File: foo\.c Status: Up-to-date Working revision: 1\.1\.1\.1.* - Repository revision: 1\.1\.1\.1 ${TESTDIR}/cvsroot/first-dir/foo\.c,v + Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.c,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) @@ -12072,7 +13712,7 @@ File: foo\.c Status: Up-to-date File: foo\.exe Status: Up-to-date Working revision: 1\.1\.1\.1.* - Repository revision: 1\.1\.1\.1 ${TESTDIR}/cvsroot/first-dir/foo\.exe,v + Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.exe,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb" @@ -12108,7 +13748,7 @@ U first-dir/foo.exe' File: foo\.c Status: Up-to-date Working revision: 1\.1\.1\.1.* - Repository revision: 1\.1\.1\.1 ${TESTDIR}/cvsroot/first-dir/foo\.c,v + Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.c,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -ko @@ -12117,7 +13757,7 @@ File: foo\.c Status: Up-to-date File: foo\.exe Status: Up-to-date Working revision: 1\.1\.1\.1.* - Repository revision: 1\.1\.1\.1 ${TESTDIR}/cvsroot/first-dir/foo\.exe,v + Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.exe,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb" @@ -12231,7 +13871,7 @@ File: foo\.exe Status: Up-to-date echo "foo*.sb -k 'b'" > cvswrappers dotest binwrap3-2 "${testcvs} -q ci -m cvswrappers-mod" \ "Checking in cvswrappers; -${TESTDIR}/cvsroot/CVSROOT/cvswrappers,v <-- cvswrappers +${CVSROOT_DIRNAME}/CVSROOT/cvswrappers,v <-- cvswrappers new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* done ${PROG} [a-z]*: Rebuilding administrative file database" @@ -12265,16 +13905,16 @@ ${PROG} [a-z]*: Rebuilding administrative file database" ${PROG} [a-z]*: scheduling file .file1\.txt. for addition ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest binwrap3-2d "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/binwrap3/sub2/file1\.newbin,v +"RCS file: ${CVSROOT_DIRNAME}/binwrap3/sub2/file1\.newbin,v done Checking in file1\.newbin; -${TESTDIR}/cvsroot/binwrap3/sub2/file1\.newbin,v <-- file1\.newbin +${CVSROOT_DIRNAME}/binwrap3/sub2/file1\.newbin,v <-- file1\.newbin initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/binwrap3/sub2/file1\.txt,v +RCS file: ${CVSROOT_DIRNAME}/binwrap3/sub2/file1\.txt,v done Checking in file1\.txt; -${TESTDIR}/cvsroot/binwrap3/sub2/file1\.txt,v <-- file1\.txt +${CVSROOT_DIRNAME}/binwrap3/sub2/file1\.txt,v <-- file1\.txt initial revision: 1\.1 done" cd .. @@ -12390,7 +14030,7 @@ done" echo "* -m 'COPY'" >>cvswrappers dotest mwrap-c2 "${testcvs} -q ci -m wrapper-mod" \ "Checking in cvswrappers; -${TESTDIR}/cvsroot/CVSROOT/cvswrappers,v <-- cvswrappers +${CVSROOT_DIRNAME}/CVSROOT/cvswrappers,v <-- cvswrappers new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* done ${PROG} [a-z]*: Rebuilding administrative file database" @@ -12399,17 +14039,17 @@ ${PROG} [a-z]*: Rebuilding administrative file database" dotest mwrap-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest mwrap-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest mwrap-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v done Checking in aa; -${TESTDIR}/cvsroot/first-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa initial revision: 1\.1 done" cd ../.. @@ -12419,20 +14059,13 @@ done" echo "changed in m2" >aa dotest mwrap-6 "${testcvs} -q ci -m m2-mod" \ "Checking in aa; -${TESTDIR}/cvsroot/first-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa new revision: 1\.2; previous revision: 1\.1 done" cd ../.. cd m1/first-dir echo "changed in m1" >aa - if test "$remote" = no; then - 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 -C aa" - else + if $remote; then # The tagged text code swallows up "U aa" but isn't yet up to # trying to figure out how it interacts with the "C aa" and # other stuff. The whole deal of having both is pretty iffy. @@ -12442,6 +14075,13 @@ ${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 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 +C aa" fi dotest mwrap-8 "${testcvs} -q update" \ "U aa @@ -12456,7 +14096,7 @@ C aa" echo '# comment out' >cvswrappers dotest mwrap-ce "${testcvs} -q ci -m wrapper-mod" \ "Checking in cvswrappers; -${TESTDIR}/cvsroot/CVSROOT/cvswrappers,v <-- cvswrappers +${CVSROOT_DIRNAME}/CVSROOT/cvswrappers,v <-- cvswrappers new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* done ${PROG} [a-z]*: Rebuilding administrative file database" @@ -12505,7 +14145,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database" dotest info-3 "${testcvs} -q ci -m new-loginfo" \ "Checking in loginfo; -${TESTDIR}/cvsroot/CVSROOT/loginfo,v <-- 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" @@ -12520,28 +14160,28 @@ ${PROG} [a-z]*: Rebuilding administrative file database" '"${PROG}"' [a-z]*: 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: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done ${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}" echo line0 >>file1 dotest info-6b "${testcvs} -q -sOTHER=foo ci -m mod-it" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- 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}" echo line1 >>file1 dotest info-7 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.3; previous revision: 1\.2 done" cd .. - dotest info-9 "cat $TESTDIR/testlog" "xenv-valueyz=${username}=${TESTDIR}/cvsroot=" + dotest info-9 "cat $TESTDIR/testlog" "xenv-valueyz=${username}=${CVSROOT_DIRNAME}=" dotest info-10 "cat $TESTDIR/testlog2" 'first-dir file1,NONE,1.1 first-dir 1.1 first-dir file1 @@ -12562,7 +14202,7 @@ first-dir file1ux' echo '# do nothing' >loginfo dotest info-11 "${testcvs} -q -s ZEE=garbage ci -m nuke-loginfo" \ "Checking in loginfo; -${TESTDIR}/cvsroot/CVSROOT/loginfo,v <-- 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" @@ -12582,7 +14222,7 @@ EOF echo "^first-dir ${TESTDIR}/vscript" >>verifymsg dotest info-v1 "${testcvs} -q ci -m add-verification" \ "Checking in verifymsg; -${TESTDIR}/cvsroot/CVSROOT/verifymsg,v <-- 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" @@ -12599,7 +14239,7 @@ and many more lines after it EOF dotest info-v3 "${testcvs} -q ci -F ${TESTDIR}/comment.tmp" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.4; previous revision: 1\.3 done" cd .. @@ -12618,7 +14258,7 @@ ${PROG} \[[a-z]* aborted\]: Message verification failed" echo '# do nothing' >verifymsg dotest info-cleanup-verifymsg "${testcvs} -q ci -m nuke-verifymsg" \ "Checking in verifymsg; -${TESTDIR}/cvsroot/CVSROOT/verifymsg,v <-- 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" @@ -12666,7 +14306,7 @@ EOF echo "ALL ${TESTDIR}/1/loggit" >taginfo dotest taginfo-2 "${testcvs} -q ci -m check-in-taginfo" \ "Checking in taginfo; -${TESTDIR}/cvsroot/CVSROOT/taginfo,v <-- taginfo +${CVSROOT_DIRNAME}/CVSROOT/taginfo,v <-- taginfo new revision: 1\.2; previous revision: 1\.1 done ${PROG} [a-z]*: Rebuilding administrative file database" @@ -12685,10 +14325,10 @@ ${PROG} [a-z]*: Rebuilding administrative file database" "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest taginfo-5 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" dotest taginfo-6 "${testcvs} -q tag tag1" "T file1" @@ -12697,7 +14337,7 @@ done" echo add text on branch >>file1 dotest taginfo-9 "${testcvs} -q ci -m modify-on-br" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" dotest taginfo-10 "${testcvs} -q tag -F -c brtag" "T file1" @@ -12738,21 +14378,21 @@ ${PROG} \[[a-z]* aborted\]: correct the above errors first!" # I suppose passing "1.1.branch" or "branch" for "br" # would be an improvement. dotest taginfo-examine "cat ${TESTDIR}/1/taglog" \ -"tag1 add ${TESTDIR}/cvsroot/first-dir file1 1.1 -br add ${TESTDIR}/cvsroot/first-dir file1 1.1 -brtag mov ${TESTDIR}/cvsroot/first-dir file1 1.1.2.1 -tag1 del ${TESTDIR}/cvsroot/first-dir file1 1.1 -tag1 del ${TESTDIR}/cvsroot/first-dir -tag1 add ${TESTDIR}/cvsroot/first-dir file1 1.1 -tag1 del ${TESTDIR}/cvsroot/first-dir file1 1.1 -tag1 del ${TESTDIR}/cvsroot/first-dir" +"tag1 add ${CVSROOT_DIRNAME}/first-dir file1 1.1 +br add ${CVSROOT_DIRNAME}/first-dir file1 1.1 +brtag mov ${CVSROOT_DIRNAME}/first-dir file1 1.1.2.1 +tag1 del ${CVSROOT_DIRNAME}/first-dir file1 1.1 +tag1 del ${CVSROOT_DIRNAME}/first-dir +tag1 add ${CVSROOT_DIRNAME}/first-dir file1 1.1 +tag1 del ${CVSROOT_DIRNAME}/first-dir file1 1.1 +tag1 del ${CVSROOT_DIRNAME}/first-dir" cd .. cd CVSROOT echo '# Keep life simple' > taginfo dotest taginfo-cleanup-1 "${testcvs} -q ci -m check-in-taginfo" \ "Checking in taginfo; -${TESTDIR}/cvsroot/CVSROOT/taginfo,v <-- taginfo +${CVSROOT_DIRNAME}/CVSROOT/taginfo,v <-- taginfo new revision: 1\.3; previous revision: 1\.2 done ${PROG} [a-z]*: Rebuilding administrative file database" @@ -12778,23 +14418,23 @@ ${PROG} [a-z]*: Rebuilding administrative file database" # might need to modify CVSROOT/config dotest config-3 "${testcvs} -q ci -m change-to-bogus-line" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" echo 'BogusOption=yes' >config dotest config-4 "${testcvs} -q ci -m change-to-bogus-opt" \ -"${PROG} [a-z]*: syntax error in ${TESTDIR}/cvsroot/CVSROOT/config: line 'bogus line' is missing '=' +"${PROG} [a-z]*: syntax error in ${CVSROOT_DIRNAME}/CVSROOT/config: line 'bogus line' is missing '=' Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" echo '# No config is a good config' > config dotest config-5 "${testcvs} -q ci -m change-to-comment" \ -"${PROG} [a-z]*: ${TESTDIR}/cvsroot/CVSROOT/config: unrecognized keyword 'BogusOption' +"${PROG} [a-z]*: ${CVSROOT_DIRNAME}/CVSROOT/config: unrecognized keyword 'BogusOption' Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -12826,10 +14466,10 @@ ${PROG} [a-z]*: Rebuilding administrative file database" '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest serverpatch-3 "${testcvs} -q commit -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" @@ -12852,7 +14492,7 @@ done" echo '2' >> file1 dotest serverpatch-7 "${testcvs} -q ci -mx file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" @@ -12903,10 +14543,10 @@ U file1' echo ' ' >>${TESTDIR}/comment.tmp echo ' ' >>${TESTDIR}/comment.tmp dotest log-3 "${testcvs} -q commit -F ${TESTDIR}/comment.tmp" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" rm -f ${TESTDIR}/comment.tmp @@ -12914,7 +14554,7 @@ done" echo 'second revision' > file1 dotest log-4 "${testcvs} -q ci -m2 file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" @@ -12923,7 +14563,7 @@ done" echo 'third revision' > file1 dotest log-6 "${testcvs} -q ci -m3 file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.3; previous revision: 1\.2 done" @@ -12932,7 +14572,7 @@ done" echo 'first branch revision' > file1 dotest log-8 "${testcvs} -q ci -m1b file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2\.2\.1; previous revision: 1\.2 done" @@ -12941,19 +14581,25 @@ done" echo 'second branch revision' > file1 dotest log-10 "${testcvs} -q ci -m2b file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1 done" # Set up a bunch of shell variables to make the later tests # easier to describe.= log_header=" -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.3 branch: locks: strict access list:" + rlog_header=" +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +head: 1\.3 +branch: +locks: strict +access list:" log_tags='symbolic names: tag: 1\.2\.2\.1 branch: 1\.2\.0\.2' @@ -13077,6 +14723,13 @@ total revisions: 5; selected revisions: 1 description: ${log_rev3} ${log_trailer}" + dotest log-14f "${testcvs} log -r:: file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" dotest log-15 "${testcvs} log -r1.2 file1" \ "${log_header} @@ -13151,6 +14804,15 @@ ${log_rev3} ${log_rev2} ${log_trailer}" + dotest log-20a "${testcvs} log -r1.2:: file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + dotest log-21 "${testcvs} log -r:1.2 file1" \ "${log_header} ${log_tags} @@ -13161,6 +14823,15 @@ ${log_rev2} ${log_rev1} ${log_trailer}" + dotest log-21a "${testcvs} log -r::1.2 file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev1} +${log_trailer}" + dotest log-22 "${testcvs} log -r1.1:1.2 file1" \ "${log_header} ${log_tags} @@ -13171,14 +14842,253 @@ ${log_rev2} ${log_rev1} ${log_trailer}" + dotest log-22a "${testcvs} log -r1.1::1.2 file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-22b "${testcvs} log -r1.1::1.3 file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev2} +${log_trailer}" + + # Now the same tests but with rlog + + dotest log-r11 "${testcvs} rlog first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 5 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-r12 "${testcvs} rlog -N first-dir/file1" \ +"${rlog_header} +${log_header2} +total revisions: 5; selected revisions: 5 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-r13 "${testcvs} rlog -b first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 3 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-r14 "${testcvs} rlog -r first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest log-r14a "${testcvs} rlog -rHEAD first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest_fail log-r14b "${testcvs} rlog -r HEAD first-dir/file1" \ +"${PROG} [a-z]*: cannot find module .HEAD. - ignored +${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest log-r14c "${testcvs} rlog -r: first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + dotest log-r14d "${testcvs} rlog -r, first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + dotest log-r14e "${testcvs} rlog -r. first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + dotest log-r14f "${testcvs} rlog -r:: first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-r15 "${testcvs} rlog -r1.2 first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev2} +${log_trailer}" + + dotest log-r16 "${testcvs} rlog -r1.2.2 first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-r17 "${testcvs} rlog -rbranch first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-r18 "${testcvs} rlog -r1.2.2. first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev2b} +${log_trailer}" + + dotest log-r18a "${testcvs} rlog -r1.2.2.2 -r1.3:1.3 first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev3} +${log_rev2b} +${log_trailer}" + + dotest log-r19 "${testcvs} rlog -rbranch. first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev2b} +${log_trailer}" + + dotest log-r20 "${testcvs} rlog -r1.2: first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev3} +${log_rev2} +${log_trailer}" + + dotest log-r20a "${testcvs} rlog -r1.2:: first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest log-r21 "${testcvs} rlog -r:1.2 first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-r21a "${testcvs} rlog -r::1.2 first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev1} +${log_trailer}" + + dotest log-r22 "${testcvs} rlog -r1.1:1.2 first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-r22a "${testcvs} rlog -r1.1::1.2 first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 0 +description: +${log_trailer}" + + dotest log-r22b "${testcvs} rlog -r1.1::1.3 first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev2} +${log_trailer}" + + # Now test outdating revisions + dotest log-o0 "${testcvs} admin -o 1.2.2.2:: file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" dotest log-o1 "${testcvs} admin -o ::1.2.2.1 file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" dotest log-o2 "${testcvs} admin -o 1.2.2.1:: file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v deleting revision 1\.2\.2\.2 done" dotest log-o3 "${testcvs} log file1" \ @@ -13192,6 +15102,17 @@ ${log_rev2} ${log_rev1} ${log_rev1b} ${log_trailer}" + dotest log-ro3 "${testcvs} rlog first-dir/file1" \ +"${rlog_header} +${log_tags} +${log_header2} +total revisions: 4; selected revisions: 4 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev1b} +${log_trailer}" dotest log-o4 "${testcvs} -q update -p -r 1.2.2.1 file1" \ "first branch revision" cd .. @@ -13211,18 +15132,18 @@ ${log_trailer}" "${PROG}"' [a-z]*: scheduling file `file1'\'' for addition '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' dotest log2-3 "${testcvs} -q commit -m 1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" # Setting the file description with add -m doesn't yet work # client/server, so skip log2-4 for remote. - if test "x$remote" = xno; then + if $remote; then :; else - dotest log2-4 "${testcvs} log -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v + dotest log2-4 "${testcvs} log -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -13241,10 +15162,10 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; fi # end of tests skipped for remote dotest log2-5 "${testcvs} admin -t-change-description file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" dotest log2-6 "${testcvs} log -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -13263,12 +15184,12 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; echo 'longer description' >${TESTDIR}/descrip echo 'with two lines' >>${TESTDIR}/descrip dotest log2-7 "${testcvs} admin -t${TESTDIR}/descrip file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" dotest_fail log2-7a "${testcvs} admin -t${TESTDIR}/nonexist file1" \ "${PROG} \[[a-z]* aborted\]: can't stat ${TESTDIR}/nonexist: No such file or directory" dotest log2-8 "${testcvs} log -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -13292,7 +15213,7 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; dotest log2-9 "echo change from stdin | ${testcvs} admin -t -q file1" "" dotest log2-10 "${testcvs} log -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -13321,17 +15242,17 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; dotest logopt-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest logopt-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest logopt-4 "${testcvs} -q ci -m add file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" cd .. @@ -13339,19 +15260,19 @@ done" dotest logopt-5 "${testcvs} log -R -d 2038-01-01" \ "${PROG} [a-z]*: Logging \. ${PROG} [a-z]*: Logging first-dir -${TESTDIR}/cvsroot/first-dir/file1,v" +${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 -${TESTDIR}/cvsroot/first-dir/file1,v" +${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 -${TESTDIR}/cvsroot/first-dir/file1,v" +${CVSROOT_DIRNAME}/first-dir/file1,v" dotest logopt-7 "${testcvs} log -s Exp -R" \ "${PROG} [a-z]*: Logging \. ${PROG} [a-z]*: Logging first-dir -${TESTDIR}/cvsroot/first-dir/file1,v" +${CVSROOT_DIRNAME}/first-dir/file1,v" cd .. rm -r 1 @@ -13367,7 +15288,7 @@ ${TESTDIR}/cvsroot/first-dir/file1,v" dotest ann-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest ann-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir cat >file1 <file1 <> $file dotest ann-id-5 "$testcvs -Q ci -m . $file" \ "Checking in $file; -${TESTDIR}/cvsroot/$module/$file,v <-- $file +${CVSROOT_DIRNAME}/$module/$file,v <-- $file new revision: 1\.2; previous revision: 1\.1 done" @@ -13546,7 +15513,36 @@ done" # Because this test is all about -d options and such, it # at least to some extent needs to be different for remote vs. # local. - if test "x$remote" = "xno"; then + if $remote; then + + # For remote, just create the repository. We don't yet do + # the various other tests above for remote but that should be + # changed. + mkdir crerepos + mkdir crerepos/CVSROOT + + # Use :ext: rather than :fork:. Most of the tests use :fork:, + # so we want to make sure that we test :ext: _somewhere_. + + # Maybe a bit dubious in the sense that people need to + # have rsh working to run the tests, but at least it + # isn't inetd :-). Might want to think harder about this - + # maybe try :ext:, and if it fails, print a (single, nice) + # message and fall back to :fork:. Maybe testing :ext: + # with our own CVS_RSH rather than worrying about a system one + # would do the trick. + + # Note that we set CVS_SERVER at the beginning. + CREREPOS_ROOT=:ext:`hostname`:${TESTDIR}/crerepos + + # 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 + exit 1 + fi + + else # First, if the repository doesn't exist at all... dotest_fail crerepos-1 \ @@ -13587,65 +15583,47 @@ ${testcvs} -d ${TESTDIR}/crerepos release -d CVSROOT >>${LOGFILE}; then CREREPOS_ROOT=${TESTDIR}/crerepos - else - # For remote, just create the repository. We don't yet do - # the various other tests above for remote but that should be - # changed. - mkdir crerepos - mkdir crerepos/CVSROOT - - # Use :ext: rather than :fork:. Most of the tests use :fork:, - # so we want to make sure that we test :ext: _somewhere_. - - # Maybe a bit dubious in the sense that people need to - # have rsh working to run the tests, but at least it - # isn't inetd :-). Might want to think harder about this - - # maybe try :ext:, and if it fails, print a (single, nice) - # message and fall back to :fork:. Maybe testing :ext: - # with our own CVS_RSH rather than worrying about a system one - # would do the trick. - - # Note that we set CVS_SERVER at the beginning. - CREREPOS_ROOT=:ext:`hostname`:${TESTDIR}/crerepos - - # 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 \`rsh $host' fails." >&2 - exit 1 - fi fi - if test "x$remote" = "xno"; then + if $remote; then # Test that CVS rejects a relative path in CVSROOT. mkdir 1; cd 1 - dotest_fail crerepos-6a "${testcvs} -q -d ../crerepos get ." \ -"${PROG} \[[a-z]* aborted\]: CVSROOT ../crerepos must be an absolute pathname" + # Note that having the client reject the pathname (as :fork: + # does), does _not_ test for the bugs we are trying to catch + # here. The point is that malicious clients might send all + # manner of things and the server better protect itself. + dotest_fail crerepos-6a-r \ +"${testcvs} -q -d :ext:`hostname`:../crerepos get ." \ +"${PROG} [a-z]*: CVSROOT (\":ext:${hostname}:\.\./crerepos\") +${PROG} [a-z]*: may only specify a positive, non-zero, integer port (not \"\.\.\")\. +${PROG} [a-z]*: perhaps you entered a relative pathname${QUESTION} +${PROG} \[[a-z]* aborted\]: Bad CVSROOT\." cd .. rm -r 1 mkdir 1; cd 1 - dotest_fail crerepos-6b "${testcvs} -d crerepos init" \ -"${PROG} \[[a-z]* aborted\]: CVSROOT crerepos must be an absolute pathname" + dotest_fail crerepos-6b-r \ +"${testcvs} -d :ext:`hostname`:crerepos init" \ +"${PROG} [a-z]*: CVSROOT (\":ext:${hostname}:crerepos\") +${PROG} [a-z]*: requires a path spec +${PROG} [a-z]*: :(gserver|kserver|pserver):\[\[user\]\[:password\]@\]host\[:\[port\]\]/path +${PROG} [a-z]*: \[:(ext|server):\]\[\[user\]@\]host\[:\]/path +${PROG} \[[a-z]* aborted\]: Bad CVSROOT\." cd .. rm -r 1 - else # remote + else # local # Test that CVS rejects a relative path in CVSROOT. mkdir 1; cd 1 - # Note that having the client reject the pathname (as :fork: - # does), does _not_ test for the bugs we are trying to catch - # here. The point is that malicious clients might send all - # manner of things and the server better protect itself. - dotest_fail crerepos-6a \ -"${testcvs} -q -d :ext:`hostname`:../crerepos get ." \ -"Root ../crerepos must be an absolute pathname" + # piping the output of this test to /dev/null since we have no way of knowing + # what error messages different rsh implementations will output. + dotest_fail crerepos-6a "${testcvs} -q -d ../crerepos get . >/dev/null 2>&1" "" cd .. rm -r 1 mkdir 1; cd 1 - dotest_fail crerepos-6b \ -"${testcvs} -d :ext:`hostname`:crerepos init" \ -"Root crerepos must be an absolute pathname" + dotest_fail crerepos-6b "${testcvs} -d crerepos init" \ +"${PROG} [a-z]*: CVSROOT \"crerepos\" must be an absolute pathname +${PROG} \[[a-z]* aborted\]: Bad CVSROOT\." cd .. rm -r 1 fi # end of tests to be skipped for remote @@ -13662,17 +15640,17 @@ ${testcvs} -d ${TESTDIR}/crerepos release -d CVSROOT >>${LOGFILE}; then dotest crerepos-8 "${testcvs} -q co -l ." '' mkdir first-dir dotest crerepos-9 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest crerepos-11 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" cd ../.. @@ -13711,7 +15689,7 @@ ${PROG} [a-z]*: Updating crerepos-dir" cd .. - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -13820,7 +15798,7 @@ EOF dotest rcs-1 "${testcvs} -q co first-dir" 'U first-dir/file1' cd first-dir dotest rcs-2 "${testcvs} -q log" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.3 branch: @@ -13854,7 +15832,7 @@ add file1 # ISO8601 format. There are many, many, other variations # specified by ISO8601 which we should be testing too. dotest rcs-3 "${testcvs} -q log -d '1996-12-11<'" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.3 branch: @@ -13874,7 +15852,7 @@ delete second line; modify twelfth line # RFC822 format (as amended by RFC1123). dotest rcs-4 "${testcvs} -q log -d '<3 Apr 2000 00:00'" \ " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.3 branch: @@ -13966,13 +15944,13 @@ EOF echo "next branch revision" > file2 dotest rcs-6b "${testcvs} -q ci -m mod file2" \ "Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.2\.6\.2; previous revision: 1\.2\.6\.1 done" # Now get rid of the default branch, it will get in the way. dotest rcs-7 "${testcvs} admin -b file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" # But we do want to make sure that "cvs admin" leaves the newphrases # in the file. @@ -14118,7 +16096,7 @@ next branch revision # OK, now make sure cvs log doesn't have any trouble with the # newphrases and such. dotest rcs-14 "${testcvs} -q log file2" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v Working file: file2 head: 1\.5 branch: @@ -14304,14 +16282,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 ${TESTDIR}/cvsroot/first-dir/file1,v" +"${PROG} \[[a-z]* aborted\]: EOF while looking for value in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" cat <${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 ${TESTDIR}/cvsroot/first-dir/file1,v" +"${PROG} \[[a-z]* aborted\]: unexpected '.x6c' reading revision number in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" cat <${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@ @@ -14319,7 +16297,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 ${TESTDIR}/cvsroot/first-dir/file1,v" +"${PROG} \[[a-z]* aborted\]: EOF while looking for value in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" cat <${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@ @@ -14338,13 +16316,13 @@ EOF # See remote code above for rationale for cd. cd first-dir dotest rcs3-6 "${testcvs} log -R file1" \ -"${TESTDIR}/cvsroot/first-dir/file1,v" +"${CVSROOT_DIRNAME}/first-dir/file1,v" # OK, now put an extraneous '\0' at the end. ${AWK} >${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 ${TESTDIR}/cvsroot/first-dir/file1,v" +"${PROG} \[[a-z]* aborted\]: unexpected '.x0' reading revision number in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" cd ../.. rm -r 1 @@ -14373,7 +16351,7 @@ EOF echo "LockDir=${TESTDIR}/locks" >config dotest lockfiles-4 "${testcvs} -q ci -m config-it" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -14410,7 +16388,7 @@ ${PROG} \[[a-z]* aborted\]: cannot stat ${TESTDIR}/locks: No such file or direct echo "# nobody here but us comments" >config dotest lockfiles-cleanup-1 "${testcvs} -q ci -m config-it" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -14450,25 +16428,25 @@ ${PROG} [a-z]*: Rebuilding administrative file database" dotest backuprecover-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest backuprecover-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir mkdir dir dotest backuprecover-3 "${testcvs} add dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir added to the repository" +"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" dotest backuprecover-5 "${testcvs} -q ci -mtest" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/file2,v done Checking in dir/file2; -${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 initial revision: 1\.1 done" echo "Line one" >>file1 @@ -14485,11 +16463,11 @@ done" echo " God only knows" >>dir/file2 dotest backuprecover-6 "${testcvs} -q ci -mtest" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done Checking in dir/file2; -${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 new revision: 1\.2; previous revision: 1\.1 done" @@ -14499,8 +16477,8 @@ done" mkdir 2; cd 2 dotest backuprecover-7 "${testcvs} -Q co first-dir" '' cd first-dir - sed -e"s/looks like/just looks like/" file1 >tmp; mv tmp file1 - sed -e"s/don't use/don't just use/" dir/file2 >tmp; mv tmp dir/file2 + sed -e "s/looks like/just looks like/" file1 >tmp; mv tmp file1 + sed -e "s/don't use/don't just use/" dir/file2 >tmp; mv tmp dir/file2 # developer 1 is on a roll cd ../../1/first-dir @@ -14512,16 +16490,16 @@ done" echo " a word that fits here would be something like dials" >>dir/file2 dotest backuprecover-8 "${testcvs} -q ci -mtest" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.3; previous revision: 1\.2 done Checking in dir/file2; -${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 new revision: 1\.3; previous revision: 1\.2 done" # Save a backup copy - cp -r ${TESTDIR}/cvsroot/first-dir ${TESTDIR}/cvsroot/backup + cp -r ${CVSROOT_DIRNAME}/first-dir ${TESTDIR}/cvsroot/backup # Simulate developer 3 cd ../.. @@ -14536,11 +16514,11 @@ done" echo " I think you should quit and get a job in the foundry" >>dir/file2 dotest backuprecover-9b "${testcvs} -q ci -mtest" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.4; previous revision: 1\.3 done Checking in dir/file2; -${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 new revision: 1\.4; previous revision: 1\.3 done" @@ -14549,7 +16527,7 @@ done" mkdir 4; cd 4 dotest backuprecover-10 "${testcvs} -Q co first-dir" '' cd first-dir - sed -e"s/quit and/be fired so he can/" dir/file2 >tmp; mv tmp dir/file2 + sed -e "s/quit and/be fired so he can/" dir/file2 >tmp; mv tmp dir/file2 # And back to developer 1 cd ../../1/first-dir @@ -14566,21 +16544,21 @@ done" echo " once you find what's in store!" >>dir/file2 dotest backuprecover-12 "${testcvs} -q ci -mtest" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.5; previous revision: 1\.4 done Checking in dir/file2; -${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 new revision: 1\.5; previous revision: 1\.4 done" # developer 3'll do a bit of work that never gets checked in cd ../../3/first-dir dotest backuprecover-13 "${testcvs} -Q update" '' - sed -e"s/very/some extremely/" file1 >tmp; mv tmp file1 + sed -e "s/very/some extremely/" file1 >tmp; mv tmp file1 dotest backuprecover-14 "${testcvs} -q ci -mtest" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.6; previous revision: 1\.5 done" echo >>file1 @@ -14591,8 +16569,8 @@ done" echo " You've got an ill, and I have the cure!" >>dir/file2 # Slag the original and restore it a few revisions back - rm -rf ${TESTDIR}/cvsroot/first-dir - mv ${TESTDIR}/cvsroot/backup ${TESTDIR}/cvsroot/first-dir + rm -rf ${CVSROOT_DIRNAME}/first-dir + mv ${CVSROOT_DIRNAME}/backup ${TESTDIR}/cvsroot/first-dir # Have developer 1 try an update and lose some data # @@ -14610,7 +16588,7 @@ U dir/file2" 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 ${TESTDIR}/cvsroot/first-dir/file1,v" +${PROG} \[[a-z]* aborted\]: could not find desired version 1\.6 in ${CVSROOT_DIRNAME}/first-dir/file1,v" # create our workspace fixin' script cd ../.. @@ -14645,11 +16623,11 @@ done" >fixit cd first-dir dotest backuprecover-19 "${testcvs} -q ci -mrecover/merge" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.4; previous revision: 1\.3 done Checking in dir/file2; -${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 new revision: 1\.4; previous revision: 1\.3 done" @@ -14657,7 +16635,7 @@ done" cd ../../4/first-dir dotest backuprecover-20 "${testcvs} update" \ "${PROG} [a-z]*: Updating \. -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +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 @@ -14665,7 +16643,7 @@ rcsmerge: warning: conflicts during merge ${PROG} [a-z]*: conflicts found in file1 C file1 ${PROG} [a-z]*: Updating dir -RCS file: ${TESTDIR}/cvsroot/first-dir/dir/file2,v +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 @@ -14681,28 +16659,28 @@ C dir/file2" s/quit and/be fired so he can/" dir/file2 >tmp; mv tmp dir/file2 dotest backuprecover-21 "${testcvs} -q ci -mrecover/merge" \ "Checking in dir/file2; -${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 new revision: 1\.5; previous revision: 1\.4 done" # go back and commit developer 2's stuff to prove it can still be done cd ../../2/first-dir dotest backuprecover-22 "${testcvs} -Q update" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.2 retrieving revision 1\.4 Merging differences between 1\.2 and 1\.4 into file1 -RCS file: ${TESTDIR}/cvsroot/first-dir/dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/file2,v retrieving revision 1\.2 retrieving revision 1\.5 Merging differences between 1\.2 and 1\.5 into file2" dotest backuprecover-23 "${testcvs} -q ci -mtest" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.5; previous revision: 1\.4 done Checking in dir/file2; -${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 new revision: 1\.6; previous revision: 1\.5 done" @@ -14829,10 +16807,10 @@ O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= /\*" "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest big-3 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" cd .. @@ -14843,7 +16821,7 @@ done" echo "add a line to the end" >>file1 dotest big-5 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" cd ../2/first-dir @@ -14852,7 +16830,7 @@ done" dotest big-6 "${testcvs} -q update" "[UP] file1" cd ../.. - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -14879,20 +16857,20 @@ done" dotest modes-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest modes-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest modes-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v done Checking in aa; -${TESTDIR}/cvsroot/first-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa initial revision: 1\.1 done" - dotest modes-5 "ls -l ${TESTDIR}/cvsroot/first-dir/aa,v" \ + dotest modes-5 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \ "-r--r--r-- .*" # Test for whether we can set the execute bit. @@ -14900,24 +16878,24 @@ done" echo change it >>aa dotest modes-6 "${testcvs} -q ci -m set-execute-bit" \ "Checking in aa; -${TESTDIR}/cvsroot/first-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa new revision: 1\.2; previous revision: 1\.1 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 ${TESTDIR}/cvsroot/first-dir/aa,v" \ + dotest modes-7 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \ "-r--r--r-- .*" # OK, now manually change the modes and see what happens. - chmod g=r,o= ${TESTDIR}/cvsroot/first-dir/aa,v + chmod g=r,o= ${CVSROOT_DIRNAME}/first-dir/aa,v echo second line >>aa dotest modes-7a "${testcvs} -q ci -m set-execute-bit" \ "Checking in aa; -${TESTDIR}/cvsroot/first-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa new revision: 1\.3; previous revision: 1\.2 done" - dotest modes-7b "ls -l ${TESTDIR}/cvsroot/first-dir/aa,v" \ + dotest modes-7b "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \ "-r--r----- .*" CVSUMASK=007 @@ -14929,20 +16907,20 @@ done" "${PROG} [a-z]*: scheduling file .ab. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest modes-9 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/ab,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/ab,v done Checking in ab; -${TESTDIR}/cvsroot/first-dir/ab,v <-- ab +${CVSROOT_DIRNAME}/first-dir/ab,v <-- ab initial revision: 1\.1 done" - if test "x$remote" = xyes; then + if $remote; then # 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-10 "ls -l ${TESTDIR}/cvsroot/first-dir/ab,v" \ + dotest modes-10r "ls -l ${CVSROOT_DIRNAME}/first-dir/ab,v" \ "-r-xr-x---.*" "-r-xr-xr-x.*" else - dotest modes-10 "ls -l ${TESTDIR}/cvsroot/first-dir/ab,v" \ + dotest modes-10 "ls -l ${CVSROOT_DIRNAME}/first-dir/ab,v" \ "-r-xr-x---.*" fi @@ -14959,25 +16937,25 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" # when we are just now adding the file; as far as I know # that is longstanding CVS behavior, for what it's worth. dotest modes-14 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/Attic/ac,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v done Checking in ac; -${TESTDIR}/cvsroot/first-dir/Attic/ac,v <-- ac +${CVSROOT_DIRNAME}/first-dir/Attic/ac,v <-- ac new revision: 1\.1\.2\.1; previous revision: 1\.1 done" - if test "x$remote" = xyes; then + if $remote; then # 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. The # 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-15 \ -"ls -l ${TESTDIR}/cvsroot/first-dir/Attic/ac,v" \ + dotest modes-15r \ +"ls -l ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v" \ "-r--r--r--.*" "-r--r-----.*" else dotest modes-15 \ -"ls -l ${TESTDIR}/cvsroot/first-dir/Attic/ac,v" \ +"ls -l ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v" \ "-r--r-----.*" fi @@ -14997,23 +16975,23 @@ done" dotest modes2-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest modes2-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest modes2-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v done Checking in aa; -${TESTDIR}/cvsroot/first-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa initial revision: 1\.1 done" echo "more money" >> aa dotest modes2-5 "${testcvs} -q ci -m add" \ "Checking in aa; -${TESTDIR}/cvsroot/first-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa new revision: 1\.2; previous revision: 1\.1 done" @@ -15044,31 +17022,31 @@ done" dotest modes3-1 "${testcvs} -q co -l ." '' mkdir first-dir second-dir dotest modes3-2 "${testcvs} add first-dir second-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository -Directory ${TESTDIR}/cvsroot/second-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository +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" dotest modes3-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v done Checking in first-dir/aa; -${TESTDIR}/cvsroot/first-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/second-dir/ab,v +RCS file: ${CVSROOT_DIRNAME}/second-dir/ab,v done Checking in second-dir/ab; -${TESTDIR}/cvsroot/second-dir/ab,v <-- ab +${CVSROOT_DIRNAME}/second-dir/ab,v <-- ab initial revision: 1\.1 done" - chmod a= ${TESTDIR}/cvsroot/first-dir + 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 ${TESTDIR}/cvsroot/first-dir: Permission denied +${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" @@ -15082,14 +17060,14 @@ ${PROG} [a-z]*: Updating second-dir" ${PROG} [a-z]*: Updating CVSROOT U ${DOTSTAR} ${PROG} [a-z]*: Updating first-dir -${PROG} [a-z]*: cannot open directory ${TESTDIR}/cvsroot/first-dir: Permission denied +${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" cd .. rm -r 1 - chmod u+rwx ${TESTDIR}/cvsroot/first-dir - rm -rf ${TESTDIR}/cvsroot/first-dir ${TESTDIR}/cvsroot/second-dir + chmod u+rwx ${CVSROOT_DIRNAME}/first-dir + rm -rf ${CVSROOT_DIRNAME}/first-dir ${TESTDIR}/cvsroot/second-dir ;; stamps) @@ -15098,7 +17076,7 @@ ${PROG} [a-z]*: Updating second-dir" dotest stamps-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest stamps-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir touch aa echo '$''Id$' >kw @@ -15121,16 +17099,16 @@ ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" "cmp ${TESTDIR}/1/stamp.kw.touch ${TESTDIR}/1/stamp.kw.add" '' sleep 60 dotest stamps-5 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v done Checking in aa; -${TESTDIR}/cvsroot/first-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/kw,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/kw,v done Checking in kw; -${TESTDIR}/cvsroot/first-dir/kw,v <-- kw +${CVSROOT_DIRNAME}/first-dir/kw,v <-- kw initial revision: 1\.1 done" ls -l aa >${TESTDIR}/1/stamp.aa.ci @@ -15177,11 +17155,11 @@ U first-dir/kw" echo add a line >>kw dotest stamps-9 "${testcvs} -q ci -m change-them" \ "Checking in aa; -${TESTDIR}/cvsroot/first-dir/aa,v <-- aa +${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa new revision: 1\.2; previous revision: 1\.1 done Checking in kw; -${TESTDIR}/cvsroot/first-dir/kw,v <-- kw +${CVSROOT_DIRNAME}/first-dir/kw,v <-- kw new revision: 1\.2; previous revision: 1\.1 done" ls -l aa >${TESTDIR}/1/stamp.aa.ci2 @@ -15223,7 +17201,7 @@ done" cd ../.. - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -15242,7 +17220,7 @@ done" dotest perms-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest perms-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir touch foo @@ -15254,7 +17232,7 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" "RCS file: ${CVSROOT_DIRNAME}/first-dir/foo,v done Checking in foo; -${TESTDIR}/cvsroot/first-dir/foo,v <-- foo +${CVSROOT_DIRNAME}/first-dir/foo,v <-- foo initial revision: 1\.1 done" @@ -15263,7 +17241,7 @@ done" mkdir 2; cd 2 dotest perms-5 "${testcvs} -q co first-dir" "U first-dir/foo" cd first-dir - if test "$remote" = no; then + if $remote; then :; else # PreservePermissions not yet implemented for remote. dotest perms-6 "ls -l foo" "-r---wx--x .* foo" fi @@ -15287,24 +17265,24 @@ done" dotest symlinks-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest symlinks-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir 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" - if test "$remote" = yes; then + if $remote; then # Remote doesn't implement PreservePermissions, and in its # absence the correct behavior is to follow the symlink. - dotest_fail symlinks-4 "${testcvs} -q ci -m ''" \ + dotest_fail symlinks-4r "${testcvs} -q ci -m ''" \ "${PROG} \[commit aborted\]: reading slink: No such file or directory" else dotest symlinks-4 "${testcvs} -q ci -m ''" \ "RCS file: ${CVSROOT_DIRNAME}/first-dir/slink,v done Checking in slink; -${TESTDIR}/cvsroot/first-dir/slink,v <-- slink +${CVSROOT_DIRNAME}/first-dir/slink,v <-- slink initial revision: 1\.1 done" @@ -15334,7 +17312,7 @@ done" dotest symlinks2-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest symlinks2-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir echo nonsymlink > slink dotest symlinks2-3 "${testcvs} add slink" \ @@ -15344,7 +17322,7 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" "RCS file: ${CVSROOT_DIRNAME}/first-dir/slink,v done Checking in slink; -${TESTDIR}/cvsroot/first-dir/slink,v <-- slink +${CVSROOT_DIRNAME}/first-dir/slink,v <-- slink initial revision: 1\.1 done" rm slink @@ -15353,7 +17331,7 @@ done" dotest symlinks2-5 "ln -s cvslog.file2 slink" "" dotest symlinks2-6 "${testcvs} -q ci -m linkify" \ "Checking in slink; -${TESTDIR}/cvsroot/first-dir/slink,v <-- slink +${CVSROOT_DIRNAME}/first-dir/slink,v <-- slink new revision: 1\.2; previous revision: 1\.1 done" dotest symlinks2-7 "${testcvs} -q update -r 1.1 slink" "[UP] slink" @@ -15375,7 +17353,7 @@ done" dotest hardlinks-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest hardlinks-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir # Make up some ugly filenames, to test that they get @@ -15411,32 +17389,32 @@ ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" "RCS file: ${CVSROOT_DIRNAME}/first-dir/aaaa,v done Checking in aaaa; -${TESTDIR}/cvsroot/first-dir/aaaa,v <-- aaaa +${CVSROOT_DIRNAME}/first-dir/aaaa,v <-- aaaa initial revision: 1\.1 done RCS file: ${CVSROOT_DIRNAME}/first-dir/b\.b\.b\.b,v done Checking in b\.b\.b\.b; -${TESTDIR}/cvsroot/first-dir/b\.b\.b\.b,v <-- b\.b\.b\.b +${CVSROOT_DIRNAME}/first-dir/b\.b\.b\.b,v <-- b\.b\.b\.b initial revision: 1\.1 done RCS file: ${CVSROOT_DIRNAME}/first-dir/dd dd dd,v done Checking in dd dd dd; -${TESTDIR}/cvsroot/first-dir/dd dd dd,v <-- dd dd dd +${CVSROOT_DIRNAME}/first-dir/dd dd dd,v <-- dd dd dd initial revision: 1\.1 done" # Test checking out hardlinked files. cd ../.. mkdir 2; cd 2 - if test "$remote" = yes; then + if $remote; then # Remote does not implement PreservePermissions. - dotest hardlinks-5 "${testcvs} -q co first-dir" \ + dotest hardlinks-5r "${testcvs} -q co first-dir" \ "U first-dir/aaaa U first-dir/b\.b\.b\.b U first-dir/dd dd dd" cd first-dir - dotest hardlinks-6 "ls -l [abd]*" \ + dotest hardlinks-6r "ls -l [abd]*" \ "-[rwx\-]* *1 .* aaaa -[rwx\-]* *1 .* b\.b\.b\.b -[rwx\-]* *1 .* dd dd dd" @@ -15476,7 +17454,7 @@ U first-dir/dd dd dd" dotest sticky-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest sticky-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir touch file1 @@ -15484,17 +17462,17 @@ U first-dir/dd dd dd" "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest sticky-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" dotest sticky-5 "${testcvs} -q tag tag1" "T file1" echo add a line >>file1 dotest sticky-6 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" dotest sticky-7 "${testcvs} -q update -r tag1" "[UP] file1" @@ -15511,10 +17489,10 @@ ${QUESTION} file2" "${QUESTION} file2 "${PROG} [a-z]*: scheduling file .file2. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest sticky-14 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done" @@ -15580,7 +17558,7 @@ U file1" "U file1" dotest keyword-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest keyword-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir echo '$''Author$' > file1 @@ -15605,22 +17583,22 @@ U file1" "U file1" "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest keyword-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" dotest keyword-5 "cat file1" \ '\$'"Author: ${username} "'\$'" "'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" -"'\$'"Header: ${TESTDIR}/cvsroot/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" +"'\$'"Header: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" "'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" "'\$'"Locker: "'\$'" "'\$'"Name: "'\$'" "'\$'"RCSfile: file1,v "'\$'" "'\$'"Revision: 1\.1 "'\$'" -"'\$'"Source: ${TESTDIR}/cvsroot/first-dir/file1,v "'\$'" +"'\$'"Source: ${CVSROOT_DIRNAME}/first-dir/file1,v "'\$'" "'\$'"State: Exp "'\$'" "'\$'"Nonkey"'\$'" "'\$'"Date @@ -15634,7 +17612,7 @@ xx" # vs. -kkv. CVS does not normally lock RCS files, but some # people use cvs admin to enforce reserved checkouts. dotest keyword-6 "${testcvs} admin -l file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 locked done" @@ -15642,13 +17620,13 @@ done" dotest keyword-8 "cat file1" \ '\$'"Author: ${username} "'\$'" "'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" -"'\$'"Header: ${TESTDIR}/cvsroot/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" +"'\$'"Header: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" "'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" "'\$'"Locker: "'\$'" "'\$'"Name: "'\$'" "'\$'"RCSfile: file1,v "'\$'" "'\$'"Revision: 1\.1 "'\$'" -"'\$'"Source: ${TESTDIR}/cvsroot/first-dir/file1,v "'\$'" +"'\$'"Source: ${CVSROOT_DIRNAME}/first-dir/file1,v "'\$'" "'\$'"State: Exp "'\$'" "'\$'"Nonkey"'\$'" "'\$'"Date @@ -15662,13 +17640,13 @@ xx" dotest keyword-10 "cat file1" \ '\$'"Author: ${username} "'\$'" "'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" -"'\$'"Header: ${TESTDIR}/cvsroot/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp ${username} "'\$'" +"'\$'"Header: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp ${username} "'\$'" "'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp ${username} "'\$'" "'\$'"Locker: ${username} "'\$'" "'\$'"Name: "'\$'" "'\$'"RCSfile: file1,v "'\$'" "'\$'"Revision: 1\.1 "'\$'" -"'\$'"Source: ${TESTDIR}/cvsroot/first-dir/file1,v "'\$'" +"'\$'"Source: ${CVSROOT_DIRNAME}/first-dir/file1,v "'\$'" "'\$'"State: Exp "'\$'" "'\$'"Nonkey"'\$'" "'\$'"Date @@ -15702,13 +17680,13 @@ xx" dotest keyword-14 "cat file1" \ "${username} [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] -${TESTDIR}/cvsroot/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp +${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp file1,v 1\.1 -${TESTDIR}/cvsroot/first-dir/file1,v +${CVSROOT_DIRNAME}/first-dir/file1,v Exp "'\$'"Nonkey"'\$'" "'\$'"Date @@ -15742,24 +17720,24 @@ xx "'\$'"Log"'\$' echo '$''Name$' > file1 dotest keyword-18 "${testcvs} ci -m modify file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" dotest keyword-19 "${testcvs} -q tag tag1" "T file1" echo "change" >> file1 dotest keyword-20 "${testcvs} -q ci -m mod2 file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${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" dotest keyword-22 "cat file1" '\$'"Name: tag1 "'\$' - if test "$remote" = yes; then + if $remote; then # Like serverpatch-8. Not sure there is anything much we # can or should do about this. - dotest keyword-23 "${testcvs} update -A file1" "P file1 + dotest keyword-23r "${testcvs} update -A file1" "P file1 ${PROG} update: checksum failure after patch to \./file1; will refetch ${PROG} client: refetching unpatchable files U file1" @@ -15780,7 +17758,7 @@ change" dotest keywordlog-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest keywordlog-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir echo initial >file1 dotest keywordlog-3 "${testcvs} add file1" \ @@ -15789,10 +17767,10 @@ ${PROG} [a-z]*: 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" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.3 done" @@ -15815,7 +17793,7 @@ ${PROG} \[[a-z]* aborted\]: correct above errors first!" dotest keywordlog-5 "${testcvs} ci -F ${TESTDIR}/comment.tmp file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.4; previous revision: 1\.3 done" rm -f ${TESTDIR}/comment.tmp @@ -15842,7 +17820,7 @@ xx" echo "change" >> file1 dotest keywordlog-10 "${testcvs} ci -m modify file1" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.5; previous revision: 1\.4 done" dotest keywordlog-11 "cat file1" \ @@ -15876,7 +17854,7 @@ change" echo br-change >>file1 dotest keywordlog-15 "${testcvs} -q ci -m br-modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.4\.2\.1; previous revision: 1\.4 done" dotest keywordlog-16 "cat file1" \ @@ -15973,7 +17951,7 @@ xx" dotest keywordlog-24 \ "${testcvs} admin -oHEAD 1/first-dir/file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v deleting revision 1\.5 done" @@ -15986,7 +17964,7 @@ xx First log line xx Second log line xx" - if test $keep = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -16009,7 +17987,7 @@ xx" dotest keyword2-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest keyword2-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir echo '$''Revision$' >> file1 @@ -16039,16 +18017,16 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest keyword2-6 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/binfile\.dat,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v done Checking in binfile\.dat; -${TESTDIR}/cvsroot/first-dir/binfile\.dat,v <-- binfile\.dat +${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v <-- binfile\.dat initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" @@ -16059,7 +18037,7 @@ T file1" sed -e 's/our/the best of and the worst of/' file1 >f; mv f file1 dotest keyword2-8 "${testcvs} -q ci -m change" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" @@ -16068,14 +18046,14 @@ done" echo "what else do we have?" >>file1 dotest keyword2-10 "${testcvs} -q ci -m change" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" # Okay, first a conflict in file1 - should be okay with binfile.dat dotest keyword2-11 "${testcvs} -q update -A -j branch" \ "U file1 -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +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 @@ -16084,7 +18062,7 @@ rcsmerge: warning: conflicts during merge" dotest_fail keyword2-12 "${testcvs} diff file1" \ "Index: file1 =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.2 diff -r1\.2 file1 0a1 @@ -16098,11 +18076,11 @@ diff -r1\.2 file1 # Here's the problem... shouldn't -kk a binary file... rm file1 - if test "$remote" = yes; then - dotest keyword2-13 "${testcvs} -q update -A -kk -j branch" \ + if $remote; then + dotest keyword2-13r "${testcvs} -q update -A -kk -j branch" \ "U binfile.dat U file1 -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +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" @@ -16111,7 +18089,7 @@ Merging differences between 1\.1 and 1\.1\.2\.1 into file1" "U binfile.dat ${PROG} [a-z]*: warning: file1 was lost U file1 -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +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" @@ -16121,7 +18099,7 @@ Merging differences between 1\.1 and 1\.1\.2\.1 into file1" # have been checked in if it had changed on the branch... dotest keyword2-14 "${testcvs} -q ci -m change" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.3; previous revision: 1\.2 done" @@ -16141,12 +18119,12 @@ T file1" >binfile.dat dotest keyword2-19 "${testcvs} -q ci -m badbadbad" \ "Checking in binfile\.dat; -${TESTDIR}/cvsroot/first-dir/binfile\.dat,v <-- binfile\.dat +${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v <-- binfile\.dat new revision: 1\.1\.4\.1; previous revision: 1\.1 done" dotest keyword2-20 "${testcvs} -q update -A -kk -j branch2" \ "U binfile\.dat -RCS file: ${TESTDIR}/cvsroot/first-dir/binfile\.dat,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v retrieving revision 1\.1 retrieving revision 1\.1\.4\.1 Merging differences between 1\.1 and 1\.1\.4\.1 into binfile\.dat @@ -16190,7 +18168,7 @@ U first-dir/file2" echo 'add a line on trunk' >> file1 dotest head-3 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" dotest head-4 "${testcvs} -q tag trunktag" "T file1 @@ -16198,7 +18176,7 @@ T file2" echo 'add a line on trunk after trunktag' >> file1 dotest head-5 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.3; previous revision: 1\.2 done" dotest head-6 "${testcvs} -q tag -b br1" "T file1 @@ -16207,7 +18185,7 @@ T file2" echo 'modify on branch' >>file1 dotest head-8 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.3\.2\.1; previous revision: 1\.3 done" dotest head-9 "${testcvs} -q tag brtag" "T file1 @@ -16215,7 +18193,7 @@ T file2" echo 'modify on branch after brtag' >>file1 dotest head-10 "${testcvs} -q ci -m modify" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.3\.2\.2; previous revision: 1\.3\.2\.1 done" # With no sticky tags, HEAD is the head of the trunk. @@ -16229,12 +18207,12 @@ add a line on trunk after trunktag" dotest_fail head-trunk-diff "${testcvs} -q diff -c -r HEAD -r br1" \ "Index: file1 =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.3 retrieving revision 1\.3\.2\.2 diff -c -r1\.3 -r1\.3\.2\.2 -\*\*\* file1 [0-9/]* [0-9:]* 1\.3 ---- file1 [0-9/]* [0-9:]* 1\.3\.2\.2 +\*\*\* file1 ${RFCDATE} 1\.3 +--- file1 ${RFCDATE} 1\.3\.2\.2 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1,3 \*\*\*\* --- 1,5 ---- @@ -16282,12 +18260,12 @@ add a line on trunk after trunktag" "${testcvs} -q diff -c -r HEAD -r br1" \ "Index: file1 =================================================================== -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v retrieving revision 1\.3 retrieving revision 1\.3\.2\.2 diff -c -r1\.3 -r1\.3\.2\.2 -\*\*\* file1 [0-9/]* [0-9:]* 1\.3 ---- file1 [0-9/]* [0-9:]* 1\.3\.2\.2 +\*\*\* file1 ${RFCDATE} 1\.3 +--- file1 ${RFCDATE} 1\.3\.2\.2 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\* 1,3 \*\*\*\* --- 1,5 ---- @@ -16306,10 +18284,10 @@ ${PLUS} modify on branch after brtag" # a revision (file1) and the case where it does not (file2) dotest_fail head-o0a "${testcvs} admin -o ::br1" \ "${PROG} [a-z]*: Administrating \. -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +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]*: cannot modify RCS file for .file1. -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +${PROG} [a-z]*: 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 \. @@ -16317,10 +18295,10 @@ D file1 D file2" dotest head-o1 "${testcvs} admin -o ::br1" \ "${PROG} [a-z]*: Administrating \. -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v deleting revision 1\.3\.2\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" cd ../.. rm -r 1 @@ -16348,7 +18326,7 @@ done" dotest tagdate-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest tagdate-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir echo trunk-1 >file1 @@ -16356,10 +18334,10 @@ done" "${PROG} [a-z]*: scheduling file .file1. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest tagdate-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" dotest tagdate-5 "${testcvs} -q tag -b br1" "T file1" @@ -16367,7 +18345,7 @@ done" echo trunk-2 >file1 dotest tagdate-7 "${testcvs} -q ci -m modify-on-trunk" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.2; previous revision: 1\.1 done" # We are testing -r -D where br1 is a (magic) branch without @@ -16378,7 +18356,7 @@ done" echo br2-1 >file1 dotest tagdate-10 "${testcvs} -q ci -m modify-on-br2" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.4\.1; previous revision: 1\.1 done" @@ -16406,7 +18384,7 @@ done" echo br2-2 >file1 dotest tagdate-13 "${testcvs} -q ci -m modify-2-on-br2" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.4\.2; previous revision: 1\.1\.4\.1 done" cd ../.. @@ -16427,7 +18405,7 @@ done" \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* 1\.1\.4\.2 (${username} *[0-9a-zA-Z-]*): br2-2" - if test $keep = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -16446,7 +18424,7 @@ done" dotest multibranch2-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest multibranch2-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir echo trunk-1 >file1 @@ -16456,16 +18434,16 @@ done" ${PROG} [a-z]*: scheduling file .file2. for addition ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest multibranch2-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done" dotest multibranch2-5 "${testcvs} -q tag -b A" "T file1 @@ -16478,11 +18456,11 @@ T file2" echo branch-B >file2 dotest multibranch2-8 "${testcvs} -q ci -m modify-on-B" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.4\.1; previous revision: 1\.1 done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.1\.4\.1; previous revision: 1\.1 done" @@ -16492,13 +18470,13 @@ done" # When using cvs-1.9.20, this commit gets a failed assertion in rcs.c. dotest multibranch2-10 "${testcvs} -q ci -m modify-on-A" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" dotest multibranch2-11 "${testcvs} -q log file1" \ " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -16528,7 +18506,7 @@ modify-on-A # This one is more concise. dotest multibranch2-12 "${testcvs} -q log -r1.1 file1" \ " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -16555,13 +18533,13 @@ add [UP] file2" dotest multibranch2-14 "${testcvs} -q update -r A -j B file2" \ "[UP] file2 -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v retrieving revision 1.1 retrieving revision 1.1.4.1 Merging differences between 1.1 and 1.1.4.1 into file2" dotest multibranch2-15 "${testcvs} -q ci -m commit-on-A file2" \ "Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" cd ../.. @@ -16594,10 +18572,10 @@ done" "${PROG} [a-z]*: scheduling file .$file. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest tag8k-4 "$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" @@ -16605,7 +18583,7 @@ done" echo a > $file dotest tag8k-5 "$testcvs -Q ci -m . $file" \ "Checking in $file; -${TESTDIR}/cvsroot/$module/$file,v <-- $file +${CVSROOT_DIRNAME}/$module/$file,v <-- $file new revision: 1\.2; previous revision: 1\.1 done" @@ -16629,7 +18607,7 @@ done" dotest tag8k-16 "$testcvs -Q tag $t-a $file" '' # Extract the author value. - name=`sed -n 's/.*; author \([^;]*\);.*/\1/p' ${TESTDIR}/cvsroot/$module/$file,v|head -1` + name=`sed -n 's/.*; author \([^;]*\);.*/\1/p' ${CVSROOT_DIRNAME}/$module/$file,v|head -1` # Form a suffix string of length (16 - length($name)). # CAREFUL: this will lose if $name is longer than 16. @@ -16645,7 +18623,7 @@ done" echo a >> $file dotest tag8k-18 "$testcvs -Q ci -m . $file" \ "Checking in $file; -${TESTDIR}/cvsroot/$module/$file,v <-- $file +${CVSROOT_DIRNAME}/$module/$file,v <-- $file new revision: 1\.3; previous revision: 1\.2 done" cd ../.. @@ -16682,7 +18660,7 @@ done" dotest admin-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest admin-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir dotest_fail admin-3 "${testcvs} -q admin -i file1" \ @@ -16700,16 +18678,16 @@ ${PROG} \[admin aborted\]: specify ${PROG} -H admin for usage information" ${PROG} [a-z]*: scheduling file .file2. for addition ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest admin-6 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done" dotest admin-7 "${testcvs} -q tag -b br" "T file1 @@ -16718,7 +18696,7 @@ T file2" echo 'add a line on the branch' >> file1 dotest admin-9 "${testcvs} -q ci -m modify-on-branch" \ "Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" dotest admin-10 "${testcvs} -q update -A" "U file1" @@ -16735,12 +18713,12 @@ ${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: ${TESTDIR}/cvsroot/first-dir/file1,v -${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/file1,v: Symbolic name BOGUS is undefined. -${PROG} [a-z]*: cannot modify RCS file for .file1. -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v -${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/file2,v: Symbolic name BOGUS is undefined. -${PROG} [a-z]*: cannot modify RCS file for .file2." +"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\. +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\." # Note that -s option applies to the new default branch, not # the old one. @@ -16749,10 +18727,10 @@ ${PROG} [a-z]*: cannot modify RCS file for .file2." # to change that once CVS parses options. dotest admin-11 "${testcvs} -q admin -afoo,bar -abaz \ -b1.1.2 -cxx -U -sfoo file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" dotest admin-11a "${testcvs} log -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: 1\.1\.2 @@ -16775,10 +18753,10 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: foo; lines: ${PLUS}1 -0 modify-on-branch =============================================================================" dotest admin-12 "${testcvs} -q admin -bbr file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" dotest admin-12a "${testcvs} log -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: 1\.1\.2 @@ -16859,10 +18837,10 @@ add a line on the branch @" dotest admin-14 "${testcvs} -q admin -aauth3 -aauth2,foo \ -soneone:1.1 -m1.1:changed-log-message -ntagone: file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" dotest admin-15 "${testcvs} -q log file2" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v Working file: file2 head: 1\.1 branch: @@ -16885,10 +18863,10 @@ changed-log-message dotest admin-16 "${testcvs} -q admin \ -A${CVSROOT_DIRNAME}/first-dir/file2,v -b -L -Nbr:1.1 file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" dotest admin-17 "${testcvs} -q log file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -16916,14 +18894,14 @@ modify-on-branch =============================================================================" dotest_fail admin-18 "${testcvs} -q admin -nbr:1.1.2 file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v -${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/file1,v: symbolic name br already bound to 1\.1 -${PROG} [a-z]*: cannot modify RCS file for .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\." dotest admin-19 "${testcvs} -q admin -ebaz -ebar,auth3 -nbr file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" dotest admin-20 "${testcvs} -q log file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -16952,19 +18930,18 @@ modify-on-branch # relative pathnames in admin -A? dotest_fail admin-19a-nonexist \ "${testcvs} -q admin -A${TESTDIR}/foo/bar file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"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" # In the remote case, we are cd'd off into the temp directory # and so these tests give "No such file or directory" errors. - if test "x$remote" = xno; then - - dotest admin-19a-admin "${testcvs} -q admin -A../../cvsroot/first-dir/file2,v file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v + if $remote; then :; else + dotest admin-19a-admin "${testcvs} -q admin -A../../cvsroot/first-dir/file2,v file1" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" - dotest admin-19a-log "${testcvs} -q log -h -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v + dotest admin-19a-log "${testcvs} -q log -h -N file1" " +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -16980,10 +18957,10 @@ total revisions: 2 # Now test that plain -e works right. dotest admin-19a-2 "${testcvs} -q admin -e file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" dotest admin-19a-3 "${testcvs} -q log -h -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -16995,18 +18972,18 @@ total revisions: 2 # Put the access list back, to avoid special cases later. dotest admin-19a-4 "${testcvs} -q admin -afoo,auth2 file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done" # Add another revision to file2, so we can delete one. echo 'add a line' >> file2 dotest admin-21 "${testcvs} -q ci -m modify file2" \ "Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.2; previous revision: 1\.1 done" dotest admin-22 "${testcvs} -q admin -o1.1 file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v deleting revision 1\.1 done" # Test admin -o. More variants that we could be testing: @@ -17020,48 +18997,48 @@ done" "${PROG} [a-z]*: scheduling file .aaa. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest admin-22-o2 "${testcvs} -q ci -m first aaa" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aaa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v done Checking in aaa; -${TESTDIR}/cvsroot/first-dir/aaa,v <-- aaa +${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa initial revision: 1\.1 done" echo second rev >> aaa dotest admin-22-o3 "${testcvs} -q ci -m second aaa" \ "Checking in aaa; -${TESTDIR}/cvsroot/first-dir/aaa,v <-- aaa +${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa new revision: 1\.2; previous revision: 1\.1 done" echo third rev >> aaa dotest admin-22-o4 "${testcvs} -q ci -m third aaa" \ "Checking in aaa; -${TESTDIR}/cvsroot/first-dir/aaa,v <-- aaa +${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa new revision: 1\.3; previous revision: 1\.2 done" echo fourth rev >> aaa dotest admin-22-o5 "${testcvs} -q ci -m fourth aaa" \ "Checking in aaa; -${TESTDIR}/cvsroot/first-dir/aaa,v <-- aaa +${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa new revision: 1\.4; previous revision: 1\.3 done" echo fifth rev >>aaa dotest admin-22-o6 "${testcvs} -q ci -m fifth aaa" \ "Checking in aaa; -${TESTDIR}/cvsroot/first-dir/aaa,v <-- aaa +${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa new revision: 1\.5; previous revision: 1\.4 done" echo sixth rev >> aaa dotest admin-22-o7 "${testcvs} -q ci -m sixth aaa" \ "Checking in aaa; -${TESTDIR}/cvsroot/first-dir/aaa,v <-- aaa +${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa new revision: 1\.6; previous revision: 1\.5 done" dotest admin-22-o8 "${testcvs} admin -l1.6 aaa" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aaa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v 1\.6 locked done" dotest admin-22-o9 "${testcvs} log -r1.6 aaa" " -RCS file: ${TESTDIR}/cvsroot/first-dir/aaa,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v Working file: aaa head: 1\.6 branch: @@ -17078,20 +19055,20 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 sixth =============================================================================" dotest_fail admin-22-o10 "${testcvs} admin -o1.5: aaa" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aaa,v -${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/aaa,v: can't remove locked revision 1\.6 -${PROG} [a-z]*: cannot modify RCS file for .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\." dotest admin-22-o11 "${testcvs} admin -u aaa" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aaa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v 1\.6 unlocked done" dotest admin-22-o12 "${testcvs} admin -o1.5: aaa" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aaa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v deleting revision 1\.6 deleting revision 1\.5 done" dotest admin-22-o13 "${testcvs} log aaa" " -RCS file: ${TESTDIR}/cvsroot/first-dir/aaa,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v Working file: aaa head: 1\.4 branch: @@ -17124,18 +19101,18 @@ first echo new branch rev >> aaa dotest admin-22-o16 "${testcvs} ci -m new-branch aaa" \ "Checking in aaa; -${TESTDIR}/cvsroot/first-dir/aaa,v <-- aaa +${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa new revision: 1\.3\.2\.1; previous revision: 1\.3 done" dotest_fail admin-22-o17 "${testcvs} admin -o1.2:1.4 aaa" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aaa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v deleting revision 1\.4 -${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/aaa,v: can't remove branch point 1\.3 -${PROG} [a-z]*: cannot modify RCS file for .aaa." +${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\." dotest admin-22-o18 "${testcvs} update -p -r1.4 aaa" \ "=================================================================== Checking out aaa -RCS: ${TESTDIR}/cvsroot/first-dir/aaa,v +RCS: ${CVSROOT_DIRNAME}/first-dir/aaa,v VERS: 1\.4 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* first rev @@ -17145,29 +19122,29 @@ fourth rev" echo second branch rev >> aaa dotest admin-22-o19 "${testcvs} ci -m branch-two aaa" \ "Checking in aaa; -${TESTDIR}/cvsroot/first-dir/aaa,v <-- aaa +${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa new revision: 1\.3\.2\.2; previous revision: 1\.3\.2\.1 done" echo third branch rev >> aaa dotest admin-22-o20 "${testcvs} ci -m branch-three aaa" \ "Checking in aaa; -${TESTDIR}/cvsroot/first-dir/aaa,v <-- aaa +${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa new revision: 1\.3\.2\.3; previous revision: 1\.3\.2\.2 done" echo fourth branch rev >> aaa dotest admin-22-o21 "${testcvs} ci -m branch-four aaa" \ "Checking in aaa; -${TESTDIR}/cvsroot/first-dir/aaa,v <-- aaa +${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa new revision: 1\.3\.2\.4; previous revision: 1\.3\.2\.3 done" dotest admin-22-o22 "${testcvs} admin -o:1.3.2.3 aaa" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/aaa,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v deleting revision 1\.3\.2\.1 deleting revision 1\.3\.2\.2 deleting revision 1\.3\.2\.3 done" dotest admin-22-o23 "${testcvs} log aaa" " -RCS file: ${TESTDIR}/cvsroot/first-dir/aaa,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v Working file: aaa head: 1\.4 branch: @@ -17215,7 +19192,7 @@ fourth branch rev" # wonder whether the "cvs admin -o" should give a warning in # this case. dotest admin-23 "${testcvs} -q log file2" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v Working file: file2 head: 1\.2 branch: @@ -17287,27 +19264,27 @@ add a line on the branch # tagtwo should be a revision # dotest admin-26-1 "${testcvs} admin -ntagtwo:tagone file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" # br1 should be a branch # dotest admin-26-2 "${testcvs} admin -nbr1:br file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" # Attach some tags using RCS versions # dotest admin-26-3 "${testcvs} admin -ntagthree:1.1 file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" dotest admin-26-4 "${testcvs} admin -nbr2:1.1.2 file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" dotest admin-26-5 "${testcvs} admin -nbr4:1.1.0.2 file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" # Check results so far @@ -17317,7 +19294,7 @@ done" File: file2 Status: Up-to-date Working revision: 1\.2.* - Repository revision: 1\.2 ${TESTDIR}/cvsroot/first-dir/file2,v + Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file2,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) @@ -17337,68 +19314,74 @@ File: file2 Status: Up-to-date echo "nuthr_line" >> file2 dotest admin-27-1 "${testcvs} commit -m nuthr_line file2" \ "Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.3; previous revision: 1\.2 done" echo "yet_another" >> file2 dotest admin-27-2 "${testcvs} commit -m yet_another file2" \ "Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 new revision: 1\.4; previous revision: 1\.3 done" # Fail trying to reattach existing tag with -n # dotest admin-27-3 "${testcvs} admin -ntagfour:1.1 file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" dotest_fail admin-27-4 "${testcvs} admin -ntagfour:1.3 file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v -${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/file2,v: symbolic name tagfour already bound to 1\.1 -${PROG} [a-z]*: cannot modify RCS file for .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\." # Succeed at reattaching existing tag, using -N # dotest admin-27-5 "${testcvs} admin -Ntagfour:1.3 file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done" # Fail on some bogus operations # Try to attach to nonexistant tag # - dotest_fail admin-28-1 "${testcvs} admin -ntagsix:tagfive file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v -${PROG} \[[a-z]* aborted\]: tag .tagfive. does not exist" + 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\." # Try a some nonexisting numeric target tags # dotest_fail admin-28-2 "${testcvs} admin -ntagseven:2.1 file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v ${PROG} \[[a-z]* aborted\]: revision .2\.1. does not exist" dotest_fail admin-28-3 "${testcvs} admin -ntageight:2.1.2 file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v ${PROG} \[[a-z]* 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: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v ${PROG} \[[a-z]* aborted\]: tag .1\.a\.2. must start with a letter" - dotest_fail admin-28-5 "${testcvs} admin -ntagten:BO+GUS file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v -${PROG} \[[a-z]* aborted\]: tag .BO${PLUS}GUS. does not exist" - + # 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\. +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v +done" + dotest_fail admin-28-6 "${testcvs} admin -nq.werty:tagfour file2" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v ${PROG} \[[a-z]* aborted\]: tag .q\.werty. must not contain the characters ..*" # Verify the archive # - dotest admin-29 "cat ${TESTDIR}/cvsroot/first-dir/file2,v" \ + dotest admin-29 "cat ${CVSROOT_DIRNAME}/first-dir/file2,v" \ "head 1\.4; access auth3 @@ -17487,26 +19470,26 @@ text dotest reserved-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest reserved-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" 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" dotest reserved-4 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done" dotest reserved-5 "${testcvs} -q admin -l file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 locked done" dotest reserved-6 "${testcvs} log -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -17525,12 +19508,12 @@ add # Note that this just tests the owner of the lock giving # it up. It doesn't test breaking a lock. dotest reserved-7 "${testcvs} -q admin -u file1" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 unlocked done" dotest reserved-8 "${testcvs} log -N file1" " -RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v Working file: file1 head: 1\.1 branch: @@ -17562,7 +19545,7 @@ if test -z "\$line"; then else user=\`echo \$line | sed -e 's/locks \\(${author}\\):[0-9.]*;.*/\\1/'\` version=\`echo \$line | sed -e 's/locks ${author}:\\([0-9.]*\\);.*/\\1/'\` - echo "\$user has file a-lock locked for version \$version" + echo "\$user has file a-lock locked for version \$version" >&2 exit 1 fi EOF @@ -17573,10 +19556,10 @@ EOF "${PROG} [a-z]*: scheduling file .a-lock. for addition ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" dotest reserved-10 "${testcvs} -q ci -m new a-lock" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/a-lock,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v done Checking in a-lock; -${TESTDIR}/cvsroot/first-dir/a-lock,v <-- a-lock +${CVSROOT_DIRNAME}/first-dir/a-lock,v <-- a-lock initial revision: 1\.1 done" # FIXME: the contents of CVSROOT fluctuate a lot @@ -17593,7 +19576,7 @@ done" echo "DEFAULT ${TESTDIR}/lockme" >>commitinfo dotest reserved-12 "${testcvs} -q ci -m rcslock commitinfo" \ "Checking in commitinfo; -${TESTDIR}/cvsroot/CVSROOT/commitinfo,v <-- commitinfo +${CVSROOT_DIRNAME}/CVSROOT/commitinfo,v <-- commitinfo new revision: 1\.2; previous revision: 1\.1 done ${PROG} [a-z]*: Rebuilding administrative file database" @@ -17601,10 +19584,10 @@ ${PROG} [a-z]*: Rebuilding administrative file database" # 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;/' ${TESTDIR}/cvsroot/first-dir/a-lock,v > a-lock,v - chmod 644 ${TESTDIR}/cvsroot/first-dir/a-lock,v - dotest reserved-13 "mv a-lock,v ${TESTDIR}/cvsroot/first-dir/a-lock,v" - chmod 444 ${TESTDIR}/cvsroot/first-dir/a-lock,v + 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 + dotest reserved-13 "mv a-lock,v ${CVSROOT_DIRNAME}/first-dir/a-lock,v" + chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v echo more stuff >> a-lock dotest_fail reserved-13b "${testcvs} ci -m '' a-lock" \ "fred has file a-lock locked for version 1\.1 @@ -17613,31 +19596,31 @@ ${PROG} \[[a-z]* 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: ${TESTDIR}/cvsroot/first-dir/a-lock,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v ${PROG} \[[a-z]* aborted\]: Revision 1\.1 is already locked by fred" dotest reserved-14 "${testcvs} admin -u1.1 a-lock" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/a-lock,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v 1\.1 unlocked done" dotest reserved-15 "${testcvs} -q ci -m success a-lock" \ "Checking in a-lock; -${TESTDIR}/cvsroot/first-dir/a-lock,v <-- a-lock +${CVSROOT_DIRNAME}/first-dir/a-lock,v <-- a-lock new revision: 1\.2; previous revision: 1\.1 done" # Now test for a bug involving branches and locks - sed -e 's/locks; strict;/locks fred:1.2; strict;/' ${TESTDIR}/cvsroot/first-dir/a-lock,v > a-lock,v - chmod 644 ${TESTDIR}/cvsroot/first-dir/a-lock,v + sed -e 's/locks; strict;/locks fred:1.2; strict;/' ${CVSROOT_DIRNAME}/first-dir/a-lock,v > a-lock,v + chmod 644 ${CVSROOT_DIRNAME}/first-dir/a-lock,v dotest reserved-16 \ -"mv a-lock,v ${TESTDIR}/cvsroot/first-dir/a-lock,v" "" - chmod 444 ${TESTDIR}/cvsroot/first-dir/a-lock,v +"mv a-lock,v ${CVSROOT_DIRNAME}/first-dir/a-lock,v" "" + chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v dotest reserved-17 "${testcvs} -q tag -b br a-lock" "T a-lock" dotest reserved-18 "${testcvs} -q update -r br a-lock" "" echo edit it >>a-lock dotest reserved-19 "${testcvs} -q ci -m modify a-lock" \ "Checking in a-lock; -${TESTDIR}/cvsroot/first-dir/a-lock,v <-- a-lock +${CVSROOT_DIRNAME}/first-dir/a-lock,v <-- a-lock new revision: 1\.2\.2\.1; previous revision: 1\.2 done" @@ -17646,7 +19629,7 @@ done" echo '# vanilla commitinfo' >commitinfo dotest reserved-cleanup-1 "${testcvs} -q ci -m back commitinfo" \ "Checking in commitinfo; -${TESTDIR}/cvsroot/CVSROOT/commitinfo,v <-- commitinfo +${CVSROOT_DIRNAME}/CVSROOT/commitinfo,v <-- commitinfo new revision: 1\.3; previous revision: 1\.2 done ${PROG} [a-z]*: Rebuilding administrative file database" @@ -17691,149 +19674,152 @@ ${PROG} [a-z]*: Rebuilding administrative file database" mkdir diffmerge1 cd diffmerge1 - # The text of the file is inlined here because `echo' loses - # newlines, and I don't know how portable the -e flag is. - # - # This is the file we both start out with: - echo "// Button.java - -package random.application; - -import random.util.star; - -public class Button -{ - /star Instantiates a Button with origin (0, 0) and zero width and height. - star You must call an initializer method to properly initialize the Button. - star/ - public Button () - { - super (); - - _titleColor = Color.black; - _disabledTitleColor = Color.gray; - _titleFont = Font.defaultFont (); - } - - /star Convenience constructor for instantiating a Button with - star bounds x, y, width, and height. Equivalent to - star foo = new Button (); - star foo.init (x, y, width, height); - star/ - public Button (int x, int y, int width, int height) - { - this (); - init (x, y, width, height); - } -}" > the_file + # These are the files we both start out with: + mkdir import + cd import + diffmerge_create_older_files dotest diffmerge1_import \ "${testcvs} import -m import diffmerge1 tag1 tag2" \ "${DOTSTAR}No conflicts created by this import" cd .. - rm -rf diffmerge1 - # Check out two working copies, one for "you" and one for "me" + # Check out two working copies, one for "you" and one for + # "me". If no branch is used and cvs detects that only one + # of the two people made changes, then cvs does not run the + # merge algorithm. But if a branch is used, then cvs does run + # the merge algorithm (even in this case of only one of the two + # people having made changes). CVS used to have a bug in this + # case. Therefore, it is important to test this case by + # using a branch: + ${testcvs} rtag -b tag diffmerge1 >/dev/null 2>&1 + ${testcvs} checkout -r tag diffmerge1 >/dev/null 2>&1 + mv diffmerge1 yours ${testcvs} checkout diffmerge1 >/dev/null 2>&1 - mv diffmerge1 diffmerge1_yours - ${testcvs} checkout diffmerge1 >/dev/null 2>&1 - mv diffmerge1 diffmerge1_mine - - # In your working copy, you'll remove the Button() method, and - # then check in your change before I check in mine: - cd diffmerge1_yours - echo "// Button.java - -package random.application; - -import random.util.star; - -public class Button -{ - /star Instantiates a Button with origin (0, 0) and zero width and height. - star You must call an initializer method to properly initialize the Button. - star/ - public Button () - { - super (); - - _titleColor = Color.black; - _disabledTitleColor = Color.gray; - _titleFont = Font.defaultFont (); - } -}" > the_file - dotest diffmerge1_yours \ - "${testcvs} ci -m yours" \ - "${DOTSTAR}hecking in ${DOTSTAR}" + mv diffmerge1 mine + + # In your working copy, you'll make changes, and + # then check in your changes before I check in mine: + cd yours + diffmerge_create_your_files + dotest diffmerge1_yours "${testcvs} -q ci -m yours" \ +"Checking in testcase01; +${CVSROOT_DIRNAME}/diffmerge1/testcase01,v <-- testcase01 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done +Checking in testcase02; +${CVSROOT_DIRNAME}/diffmerge1/testcase02,v <-- testcase02 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done +Checking in testcase03; +${CVSROOT_DIRNAME}/diffmerge1/testcase03,v <-- testcase03 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done +Checking in testcase04; +${CVSROOT_DIRNAME}/diffmerge1/testcase04,v <-- testcase04 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done +Checking in testcase05; +${CVSROOT_DIRNAME}/diffmerge1/testcase05,v <-- testcase05 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done +Checking in testcase06; +${CVSROOT_DIRNAME}/diffmerge1/testcase06,v <-- testcase06 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done +Checking in testcase07; +${CVSROOT_DIRNAME}/diffmerge1/testcase07,v <-- testcase07 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done +Checking in testcase08; +${CVSROOT_DIRNAME}/diffmerge1/testcase08,v <-- testcase08 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done +Checking in testcase09; +${CVSROOT_DIRNAME}/diffmerge1/testcase09,v <-- testcase09 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done +Checking in testcase10; +${CVSROOT_DIRNAME}/diffmerge1/testcase10,v <-- testcase10 +new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 +done" - # My working copy still has the Button() method, but I - # comment out some code at the top of the class. Then I + # Change my copy. Then I # update, after both my modifications and your checkin: - cd ../diffmerge1_mine - echo "// Button.java - -package random.application; - -import random.util.star; - -public class Button -{ - /star Instantiates a Button with origin (0, 0) and zero width and height. - star You must call an initializer method to properly initialize the Button. - star/ - public Button () - { - super (); - - // _titleColor = Color.black; - // _disabledTitleColor = Color.gray; - // _titleFont = Font.defaultFont (); - } - - /star Convenience constructor for instantiating a Button with - star bounds x, y, width, and height. Equivalent to - star foo = new Button (); - star foo.init (x, y, width, height); - star/ - public Button (int x, int y, int width, int height) - { - this (); - init (x, y, width, height); - } -}" > the_file - dotest diffmerge1_mine \ - "${testcvs} update" \ - "${DOTSTAR}erging${DOTSTAR}" + cd ../mine + diffmerge_create_my_files + dotest diffmerge1_mine "${testcvs} -q update -j tag" \ +"M testcase01 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase01,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 testcase01 +M testcase02 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase02,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 testcase02 +M testcase03 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase03,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 testcase03 +M testcase04 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase04,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 testcase04 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase05,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 testcase05 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase06,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 testcase06 +M testcase07 +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 +M testcase08 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase08,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 testcase08 +M testcase09 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase09,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 testcase09 +M testcase10 +RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase10,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 testcase10" # So if your changes didn't make it into my working copy, or - # in any case if the file does not look like the final text as - # quoted below, then the test flunks: - echo "// Button.java - -package random.application; - -import random.util.star; - -public class Button -{ - /star Instantiates a Button with origin (0, 0) and zero width and height. - star You must call an initializer method to properly initialize the Button. - star/ - public Button () - { - super (); + # in any case if the files do not look like the final text + # in the files in directory comp_me, then the test flunks: + cd .. + mkdir comp_me + cd comp_me + diffmerge_create_expected_files + cd .. + rm mine/.#* - // _titleColor = Color.black; - // _disabledTitleColor = Color.gray; - // _titleFont = Font.defaultFont (); - } -}" > comp_me - dotest diffmerge1_cmp "cmp the_file comp_me" '' + # If you have GNU's version of diff, you may try + # uncommenting the following line which will give more + # fine-grained information about how cvs differed from the + # correct result: + #dotest diffmerge1_cmp "diff -u --recursive --exclude=CVS comp_me mine" '' + dotest diffmerge1_cmp "directory_cmp comp_me mine" # Clean up after ourselves: cd .. - rm -rf diffmerge1_yours diffmerge1_mine ${CVSROOT_DIRNAME}/diffmerge1 - + if $keep; then :; else + rm -rf diffmerge1 ${CVSROOT_DIRNAME}/diffmerge1 + fi ;; diffmerge2) @@ -18537,18 +20523,18 @@ d472 12 dotest release-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest release-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir mkdir dir1 dotest release-3 "${testcvs} add dir1" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir1 added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" mkdir dir2 dotest release-4 "${testcvs} add dir2" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir2 added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/dir2 added to the repository" cd dir2 mkdir dir3 dotest release-5 "${testcvs} add dir3" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir2/dir3 added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/dir2/dir3 added to the repository" cd ../.. dotest release-6 "${testcvs} release -d first-dir/dir2/dir3 first-dir/dir1" \ @@ -18569,11 +20555,11 @@ ${PROG} [a-z]*: Updating first-dir/dir2" cd first-dir mkdir dir1 dotest release-10 "${testcvs} add dir1" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir1 added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" cd dir2 mkdir dir3 dotest release-11 "${testcvs} add dir3" \ -"Directory ${TESTDIR}/cvsroot/first-dir/dir2/dir3 added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir/dir2/dir3 added to the repository" cd ../.. dotest release-12 "${testcvs} release first-dir/dir2/dir3 first-dir/dir1" \ @@ -18613,7 +20599,7 @@ ${PROG} [a-z]*: Updating first-dir" CVSROOT2_DIRNAME=${TESTDIR}/root2 CVSROOT1=${CVSROOT1_DIRNAME} ; export CVSROOT1 CVSROOT2=${CVSROOT2_DIRNAME} ; export CVSROOT2 - if test "x$remote" = xyes; then + if $remote; then CVSROOT1=:fork:${CVSROOT1_DIRNAME} ; export CVSROOT1 CVSROOT2=:fork:${CVSROOT2_DIRNAME} ; export CVSROOT2 fi @@ -18808,7 +20794,11 @@ ${PROG} [a-z]*: cannot open directory ${TESTDIR}/root2/mod1-2: No such file or d ${PROG} [a-z]*: skipping directory mod2-2/mod1-2" else # non-RELATIVE_REPOS. - if test "$remote" = no; then + if $remote; then + # Hmm, this one is specific to non-RELATIVE_REPOS too I think. + dotest_fail multiroot-update-1ar "${testcvs1} update" \ +"protocol error: directory '${TESTDIR}/root2/mod2-2' not within root '${TESTDIR}/root1'" + else # The basic idea is that -d overrides CVS/Root. # With RELATIVE_REPOS, CVS could print an error when it # tries to recurse to mod2-2, which doesn't exist in @@ -18823,14 +20813,13 @@ ${PROG} [a-z]*: Updating mod1-2/mod2-2 ${PROG} [a-z]*: Updating mod2-1 ${PROG} [a-z]*: Updating mod2-2 ${PROG} [a-z]*: Updating mod2-2/mod1-2" - else - # Hmm, this one is specific to non-RELATIVE_REPOS too I think. - dotest_fail multiroot-update-1a "${testcvs1} update" \ -"protocol error: directory '${TESTDIR}/root2/mod2-2' not within root '${TESTDIR}/root1'" - fi # non-remote + fi # remote # Same deal but with -d ${CVSROOT2}. - if test "$remote" = no; then + if $remote; then + dotest_fail multiroot-update-1b "${testcvs2} update" \ +"protocol error: directory '${TESTDIR}/root1' not within root '${TESTDIR}/root2'" + else dotest multiroot-update-1b "${testcvs2} update" \ "${PROG} update: Updating \. ${PROG} [a-z]*: Updating mod1-1 @@ -18839,10 +20828,7 @@ ${PROG} [a-z]*: Updating mod1-2/mod2-2 ${PROG} [a-z]*: Updating mod2-1 ${PROG} [a-z]*: Updating mod2-2 ${PROG} [a-z]*: Updating mod2-2/mod1-2" - else - dotest_fail multiroot-update-1b "${testcvs2} update" \ -"protocol error: directory '${TESTDIR}/root1' not within root '${TESTDIR}/root2'" - fi # non-remote + fi # remote fi # non-RELATIVE_REPOS # modify all files and do a diff @@ -19005,31 +20991,31 @@ ${PROG} [a-z]*: Tagging mod2-2" echo anotherfile1-2 > mod2-2/mod1-2/anotherfile1-2 echo anotherfile2-2 > mod1-2/mod2-2/anotherfile2-2 - if test "x$remote" = xno; then - 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" - else + if $remote; then cd mod1-1 - dotest multiroot-add-1a "${testcvs} add anotherfile1-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" cd ../mod2-1 - dotest multiroot-add-1b "${testcvs} add anotherfile2-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" cd ../mod2-2/mod1-2 - dotest multiroot-add-1c "${testcvs} add anotherfile1-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" cd ../../mod1-2/mod2-2 - dotest multiroot-add-1d "${testcvs} add anotherfile2-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" 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" fi dotest multiroot-status-1 "${testcvs} status -v" \ @@ -19786,7 +21772,7 @@ anyone # refer to parts of our checked-out tree (e.g. "cvs update # mod1-1 mod2-2") - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -19806,7 +21792,7 @@ anyone CVSROOT2_DIRNAME=${TESTDIR}/root2 CVSROOT1=${CVSROOT1_DIRNAME} ; export CVSROOT1 CVSROOT2=${CVSROOT2_DIRNAME} ; export CVSROOT2 - if test "x$remote" = xyes; then + if $remote; then CVSROOT1=:fork:${CVSROOT1_DIRNAME} ; export CVSROOT1 CVSROOT2=:fork:${CVSROOT2_DIRNAME} ; export CVSROOT2 fi @@ -19869,12 +21855,12 @@ ${PROG} server: Updating dir1/sdir/ssdir" # also prints some trace messages, and (2) the server trace # messages are subject to out-of-order bugs (this one is hard # to work around). - if test "$remote" = no; then + if $remote; then :; else dotest multiroot2-9 "${testcvs} -t update" \ -"${PROG} update: notice: main loop with CVSROOT=${TESTDIR}/root1 +" -> main loop with CVSROOT=${TESTDIR}/root1 ${PROG} update: Updating \. ${PROG} update: Updating dir1 -${PROG} update: notice: main loop with CVSROOT=${TESTDIR}/root2 + -> main loop with CVSROOT=${TESTDIR}/root2 ${PROG} update: Updating dir1/sdir ${PROG} update: Updating dir1/sdir/ssdir" fi @@ -19906,8 +21892,8 @@ RCS file: ${TESTDIR}/root1/dir1/file1,v retrieving revision 1\.1\.1\.1 retrieving revision 1\.2 diff -u -r1\.1\.1\.1 -r1\.2 ---- dir1/file1 [0-9/]* [0-9:]* 1\.1\.1\.1 -${PLUS}${PLUS}${PLUS} dir1/file1 [0-9/]* [0-9:]* 1\.2 +--- dir1/file1 ${RFCDATE} 1\.1\.1\.1 +${PLUS}${PLUS}${PLUS} dir1/file1 ${RFCDATE} 1\.2 @@ -1 ${PLUS}1,2 @@ file1 ${PLUS}change it @@ -19917,13 +21903,13 @@ RCS file: ${TESTDIR}/root2/sdir/sfile,v retrieving revision 1\.1\.1\.1 retrieving revision 1\.2 diff -u -r1\.1\.1\.1 -r1\.2 ---- dir1/sdir/sfile [0-9/]* [0-9:]* 1\.1\.1\.1 -${PLUS}${PLUS}${PLUS} dir1/sdir/sfile [0-9/]* [0-9:]* 1\.2 +--- dir1/sdir/sfile ${RFCDATE} 1\.1\.1\.1 +${PLUS}${PLUS}${PLUS} dir1/sdir/sfile ${RFCDATE} 1\.2 @@ -1 ${PLUS}1,2 @@ sfile ${PLUS}change him too" - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -19941,7 +21927,7 @@ ${PLUS}change him too" # Not drastically different from multiroot but it covers somewhat # different stuff. - if test "x$remote" = xyes; then + if $remote; then CVSROOT1=:fork:${TESTDIR}/root1 ; export CVSROOT1 CVSROOT2=:fork:${TESTDIR}/root2 ; export CVSROOT2 else @@ -19964,7 +21950,7 @@ ${PLUS}change him too" # I suppose because of the "rm -r". # For local this fixes it up. dotest multiroot3-6 "${testcvs} -d ${CVSROOT1} -q co dir1" "" - if test "$remote" = yes; then + if $remote; then # For remote that doesn't do it. Use the quick and dirty fix. echo "D/dir1////" >CVS/Entries echo "D/dir2////" >>CVS/Entries @@ -19974,7 +21960,7 @@ ${PLUS}change him too" "Directory ${TESTDIR}/root2/dir2 added to the repository" touch dir1/file1 dir2/file2 - if test "$remote" = yes; then + if $remote; then # Trying to add them both in one command doesn't work, # because add.c doesn't do multiroot (it doesn't use recurse.c). # Furthermore, it can't deal with the parent directory @@ -20019,7 +22005,7 @@ ${PROG} [a-z]*: failed to obtain dir lock in repository .${TESTDIR}/root1/dir2' ${PROG} \[[a-z]* aborted\]: read lock failed - giving up" else # Not RELATIVE_REPOS. - if test "$remote" = yes; then + if $remote; then # This is good behavior - we are asking CVS to do something # which doesn't make sense. dotest_fail multiroot3-10 \ @@ -20067,7 +22053,7 @@ ${PROG} \[[a-z]* aborted\]: illegal source repository" cd ../.. - if test "$keep" = yes; then + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 fi @@ -20082,7 +22068,7 @@ ${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 test "x$remote" = xyes; then + if $remote; then CVSROOT1=:fork:${TESTDIR}/root1 ; export CVSROOT1 CVSROOT2=:fork:${TESTDIR}/root2 ; export CVSROOT2 else @@ -20163,7 +22149,7 @@ done" dotest rmroot-setup-1 "${testcvs} -q co -l ." '' mkdir first-dir dotest rmroot-setup-2 "${testcvs} add first-dir" \ -"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" +"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" cd first-dir touch file1 file2 dotest rmroot-setup-3 "${testcvs} add file1 file2" \ @@ -20171,16 +22157,16 @@ done" ${PROG} [a-z]*: scheduling file .file2. for addition ${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest rmroot-setup-4 "${testcvs} -q commit -minit" \ -"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v done Checking in file1; -${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 initial revision: 1\.1 done -RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v done Checking in file2; -${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 initial revision: 1\.1 done" rm CVS/Root @@ -20195,7 +22181,7 @@ done" # Similar to crerepos but that test is probably getting big # enough. - if test "x$remote" = xyes; then + if $remote; then CVSROOT1=:fork:${TESTDIR}/root1 ; export CVSROOT1 CVSROOT_MOVED=:fork:${TESTDIR}/root-moved ; export CVSROOT1 else @@ -20226,19 +22212,26 @@ No conflicts created by this import" # There were some duplicated warnings and such; only test # for the part of the error message which makes sense. # Bug: "skipping directory " without filename. - if test "$remote" = no; then + if $remote; then + dotest_fail reposmv-2r "${testcvs} update" \ +"Cannot access ${TESTDIR}/root1/CVSROOT +No such file or directory" + else dotest reposmv-2 "${testcvs} update" "${DOTSTAR} ${PROG} update: ignoring CVS/Root because it specifies a non-existent repository ${TESTDIR}/root1 -${PROG} update: cannot open directory ${TESTDIR}/cvsroot/dir1: No such file or directory +${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1: No such file or directory ${PROG} update: skipping directory " - else - dotest_fail reposmv-2 "${testcvs} update" \ -"Cannot access ${TESTDIR}/root1/CVSROOT -No such file or directory" fi # CVS/Root overrides $CVSROOT - if test "$remote" = no; then + if $remote; then + CVSROOT_SAVED=${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 + else CVSROOT_SAVED=${CVSROOT} CVSROOT=${TESTDIR}/root-moved; export CVSROOT dotest reposmv-3 "${testcvs} update" \ @@ -20247,16 +22240,16 @@ ${PROG} update: ignoring CVS/Root because it specifies a non-existent repository ${PROG} update: Updating \. ${DOTSTAR}" CVSROOT=${CVSROOT_SAVED}; export CVSROOT - else + fi + + if $remote; then CVSROOT_SAVED=${CVSROOT} - CVSROOT=:fork:${TESTDIR}/root-moved; export CVSROOT - dotest_fail reposmv-3 "${testcvs} update" \ + 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 - fi - - if test "$remote" = no; then + else # CVS/Root doesn't seem to quite completely override $CVSROOT # Bug? Not necessarily a big deal if it only affects error # messages. @@ -20267,13 +22260,6 @@ No such file or 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 - else - CVSROOT_SAVED=${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 fi # -d overrides CVS/Root @@ -20297,7 +22283,7 @@ No such file or directory" pserver) # Test basic pserver functionality. - if test "$remote" = yes; then + if $remote; then # First set SystemAuth=no. Not really necessary, I don't # think, but somehow it seems like the clean thing for # the testsuite. @@ -20307,7 +22293,7 @@ No such file or directory" echo "SystemAuth=no" >config dotest pserver-2 "${testcvs} -q ci -m config-it" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -20437,7 +22423,7 @@ EOF echo "# comments only" >config dotest pserver-cleanup-1 "${testcvs} -q ci -m config-it" \ "Checking in config; -${TESTDIR}/cvsroot/CVSROOT/config,v <-- 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" @@ -20449,7 +22435,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database" server) # Some tests of the server (independent of the client). - if test "$remote" = yes; then + if $remote; then dotest server-1 "${testcvs} server" \ "E Protocol error: Root request missing error " <${TESTDIR}/serveme <cvs + chmod a+x cvs + save_PATH=$PATH; PATH=.:$PATH + dotest fork-1 "$testcvs -d:fork:$CVSROOT_DIRNAME version" \ +'Client: \(.*\) +Server: \1' + CVS_SERVER=${testcvs}; export CVS_SERVER + PATH=$save_PATH; unset save_PATH + cd .. + if $keep; then :; else + rm -rf fork + fi + fi + ;; + *) 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 + echo "OK, all tests completed." # TODO: -# * use "test" not "[" and see if all test's support `-z' # * Test `cvs update -d foo' (where foo does not exist). # * Test `cvs update foo bar' (where foo and bar are both from the # same directory in the repository). Suppose one is a branch--make @@ -20829,10 +22850,24 @@ echo "OK, all tests completed." # this needs to be documented in cvs.texinfo, but is not) # - Test that unrecognized files in CVS directories (e.g. CVS/Foobar) # are ignored (per cvs.texinfo). +# - Test 'cvs history' with symlinks in the path to the working directory. +# - Remove most of the CVS_SERVER stuff after a reasonable amount of time. +# The "fork" & "client" series of tests should be left. 4/2/00, CVS +# 1.11.0.1 was altered so that it would default to program_name (set from +# argv[0]) rather than "cvs", but I'd like this script to work on legacy +# versions of CVS for awhile. +# - Testsuite doesn't work with usernames over eight characters in length. +# Fix it. # End of TODO list. +# Exit if keep set +if $keep; then + echo "Keeping ${TESTDIR} and exiting due to -k (keep) option." + exit 0 +fi + # Remove the test directory, but first change out of it. -cd /tmp +cd `dirname ${TESTDIR}` rm -rf ${TESTDIR} # end of sanity.sh diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c index e1af5e4..bb38f4d 100644 --- a/contrib/cvs/src/server.c +++ b/contrib/cvs/src/server.c @@ -16,50 +16,19 @@ #include "getline.h" #include "buffer.h" -#ifdef SERVER_SUPPORT - -#ifdef HAVE_WINSOCK_H -#include -#endif - -#if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) -#include -#endif - -#ifdef HAVE_KERBEROS -# include -# include -# ifndef HAVE_KRB_GET_ERR_TEXT -# define krb_get_err_text(status) krb_err_txt[status] -# endif - -/* Information we need if we are going to use Kerberos encryption. */ -static C_Block kblock; -static Key_schedule sched; - -#endif - -#ifdef HAVE_GSSAPI - -#include - -#ifdef HAVE_GSSAPI_H -#include -#endif -#ifdef HAVE_GSSAPI_GSSAPI_H -#include -#endif -#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H -#include -#endif - -#ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE -#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name -#endif - +#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) +# ifdef HAVE_GSSAPI +/* This stuff isn't included solely with SERVER_SUPPORT since some of these + * functions (encryption & the like) get compiled with or without server + * support. + * + * FIXME - They should be in a different file. + */ +# include +# include "xgssapi.h" /* We use Kerberos 5 routines to map the GSSAPI credential to a user name. */ -#include +# include /* We need this to wrap data. */ static gss_ctx_id_t gcontext; @@ -69,37 +38,46 @@ static void gserver_authenticate_connection PROTO((void)); /* Whether we are already wrapping GSSAPI communication. */ static int cvs_gssapi_wrapping; -# ifdef ENCRYPTION +# ifdef ENCRYPTION /* Whether to encrypt GSSAPI communication. We use a global variable like this because we use the same buffer type (gssapi_wrap) to handle both authentication and encryption, and we don't want multiple instances of that buffer in the communication stream. */ int cvs_gssapi_encrypt; -# endif +# endif +# endif /* HAVE_GSSAPI */ +#endif /* defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) */ +#ifdef SERVER_SUPPORT + +#ifdef HAVE_WINSOCK_H +#include #endif -/* for select */ -#include -#ifdef HAVE_SYS_BSDTYPES_H -#include +#if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) +#include #endif -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif +#ifdef HAVE_SYSLOG_H +#include #endif -#if HAVE_SYS_SELECT_H -#include +#ifdef HAVE_KERBEROS +# include +# include +# ifndef HAVE_KRB_GET_ERR_TEXT +# define krb_get_err_text(status) krb_err_txt[status] +# endif + +/* Information we need if we are going to use Kerberos encryption. */ +static C_Block kblock; +static Key_schedule sched; + #endif +/* for select */ +#include "xselect.h" + #ifndef O_NONBLOCK #define O_NONBLOCK O_NDELAY #endif @@ -112,18 +90,16 @@ int cvs_gssapi_encrypt; #define blocking_error(err) ((err) == EAGAIN) #endif -#ifdef AUTH_SERVER_SUPPORT -#ifdef HAVE_GETSPNAM -#include -#endif -#endif /* AUTH_SERVER_SUPPORT */ - /* For initgroups(). */ #if HAVE_INITGROUPS #include #endif /* HAVE_INITGROUPS */ - -#ifdef AUTH_SERVER_SUPPORT + +# ifdef AUTH_SERVER_SUPPORT + +# ifdef HAVE_GETSPNAM +# include +# endif /* The cvs username sent by the client, which might or might not be the same as the system username the server eventually switches to @@ -139,7 +115,7 @@ static char *Pserver_Repos = NULL; CVSROOT/config. */ int system_auth = 1; -#endif /* AUTH_SERVER_SUPPORT */ +# endif /* AUTH_SERVER_SUPPORT */ /* While processing requests, this buffer accumulates data to be sent to @@ -420,10 +396,10 @@ create_adm_p (base_dir, dir) differently. */ char *empty; - empty = malloc (strlen (CVSroot_directory) + empty = malloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) + sizeof (CVSNULLREPOS) - + 10); + + 3); if (! empty) { retval = ENOMEM; @@ -431,7 +407,7 @@ create_adm_p (base_dir, dir) } /* Create the directory name. */ - (void) sprintf (empty, "%s/%s/%s", CVSroot_directory, + (void) sprintf (empty, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, CVSNULLREPOS); /* Create the directory if it doesn't exist. */ @@ -597,10 +573,16 @@ print_error (status) int status; { char *msg; + char tmpstr[80]; + buf_output0 (buf_to_net, "error "); msg = strerror (status); - if (msg) - buf_output0 (buf_to_net, msg); + if (msg == NULL) + { + sprintf (tmpstr, "unknown error %d", status); + msg = tmpstr; + } + buf_output0 (buf_to_net, msg); buf_append_char (buf_to_net, '\n'); buf_flush (buf_to_net, 0); @@ -767,7 +749,7 @@ serve_root (arg) new connection. Doing this would cause interoperability headaches, so it should be a different request, if there is any reason why such a feature is needed. */ - if (CVSroot_directory != NULL) + if (current_parsed_root != NULL) { if (alloc_pending (80 + strlen (arg))) sprintf (pending_error_text, @@ -790,21 +772,24 @@ E Protocol error: Root says \"%s\" but pserver says \"%s\"", } } #endif - set_local_cvsroot (arg); + + if (current_parsed_root != NULL) + free_cvsroot_t (current_parsed_root); + current_parsed_root = local_cvsroot (arg); /* For pserver, this will already have happened, and the call will do nothing. But for rsh, we need to do it now. */ - parse_config (CVSroot_directory); + parse_config (current_parsed_root->directory); - path = malloc (strlen (CVSroot_directory) + path = malloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) - + 10); + + 2); if (path == NULL) { pending_error = ENOMEM; return; } - (void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM); + (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM); if (!isaccessible (path, R_OK | X_OK)) { int save_errno = errno; @@ -815,13 +800,13 @@ E Protocol error: Root says \"%s\" but pserver says \"%s\"", free (path); #ifdef HAVE_PUTENV - env = malloc (strlen (CVSROOT_ENV) + strlen (CVSroot_directory) + 1 + 1); + env = malloc (strlen (CVSROOT_ENV) + strlen (current_parsed_root->directory) + 2); if (env == NULL) { pending_error = ENOMEM; return; } - (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot_directory); + (void) sprintf (env, "%s=%s", CVSROOT_ENV, current_parsed_root->directory); (void) putenv (env); /* do not free env, as putenv has control of it */ #endif @@ -864,14 +849,14 @@ server_pathname_check (path) static int outside_root PROTO ((char *)); /* Is file or directory REPOS an absolute pathname within the - CVSroot_directory? If yes, return 0. If no, set pending_error + current_parsed_root->directory? If yes, return 0. If no, set pending_error and return 1. */ static int outside_root (repos) char *repos; { size_t repos_len = strlen (repos); - size_t root_len = strlen (CVSroot_directory); + 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 @@ -886,15 +871,15 @@ E protocol error: %s is not absolute", repos); } if (repos_len < root_len - || strncmp (CVSroot_directory, repos, root_len) != 0) + || strncmp (current_parsed_root->directory, repos, root_len) != 0) { not_within: - if (alloc_pending (strlen (CVSroot_directory) + if (alloc_pending (strlen (current_parsed_root->directory) + strlen (repos) + 80)) sprintf (pending_error_text, "\ E protocol error: directory '%s' not within root '%s'", - repos, CVSroot_directory); + repos, current_parsed_root->directory); return 1; } if (repos_len > root_len) @@ -1097,8 +1082,9 @@ dirswitch (dir, repos) (e.g., an entry like ``world -a .'') by putting /. at the end of the Repository file, so we do the same. */ if (strcmp (dir, ".") == 0 - && CVSroot_directory != NULL - && strcmp (CVSroot_directory, repos) == 0) + && current_parsed_root != NULL + && current_parsed_root->directory != NULL + && strcmp (current_parsed_root->directory, repos) == 0) { if (fprintf (f, "/.") < 0) { @@ -2428,6 +2414,9 @@ error ENOMEM Virtual memory exhausted.\n"; /* If this gives an error, not much we could do. syslog() it? */ write (STDOUT_FILENO, msg, sizeof (msg) - 1); +#ifdef HAVE_SYSLOG_H + syslog (LOG_DAEMON | LOG_ERR, "virtual memory exhausted"); +#endif error_exit (); } @@ -2485,13 +2474,13 @@ check_command_legal_p (cmd_name) int found_it = 0; /* else */ - flen = strlen (CVSroot_directory) + flen = strlen (current_parsed_root->directory) + strlen (CVSROOTADM) + strlen (CVSROOTADM_READERS) + 3; fname = xmalloc (flen); - (void) sprintf (fname, "%s/%s/%s", CVSroot_directory, + (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, CVSROOTADM_READERS); fp = fopen (fname, "r"); @@ -2537,13 +2526,13 @@ check_command_legal_p (cmd_name) /* Now check the writers file. */ - flen = strlen (CVSroot_directory) + flen = strlen (current_parsed_root->directory) + strlen (CVSROOTADM) + strlen (CVSROOTADM_WRITERS) + 3; fname = xmalloc (flen); - (void) sprintf (fname, "%s/%s/%s", CVSroot_directory, + (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, CVSROOTADM_WRITERS); fp = fopen (fname, "r"); @@ -2785,7 +2774,9 @@ error \n"); close (stderr_pipe[0]); close (stderr_pipe[1]); close (protocol_pipe[0]); + close_on_exec (protocol_pipe[1]); #ifdef SERVER_FLOWCONTROL + close_on_exec (flowcontrol_pipe[0]); close (flowcontrol_pipe[1]); #endif /* SERVER_FLOWCONTROL */ @@ -2802,11 +2793,11 @@ error \n"); exitstatus = (*command) (argument_count, argument_vector); /* Output any partial lines. If the client doesn't support - "MT", we just throw out the partial line, like old versions - of CVS did, since the protocol can't support this. */ - if (supported_response ("MT") && ! buf_empty_p (saved_output)) + "MT", we go ahead and just tack on a newline since the + protocol doesn't support anything better. */ + if (! buf_empty_p (saved_output)) { - buf_output0 (protocol, "MT text "); + buf_output0 (protocol, supported_response ("MT") ? "MT text " : "M "); buf_append_buffer (protocol, saved_output); buf_output (protocol, "\n", 1); buf_send_counted (protocol); @@ -2829,7 +2820,7 @@ error \n"); struct buffer *protocol_inbuf; /* Number of file descriptors to check in select (). */ int num_to_check; - int count_needed = 0; + int count_needed = 1; #ifdef SERVER_FLOWCONTROL int have_flowcontrolled = 0; #endif /* SERVER_FLOWCONTROL */ @@ -2917,13 +2908,16 @@ error \n"); while (stdout_pipe[0] >= 0 || stderr_pipe[0] >= 0 - || protocol_pipe[0] >= 0) + || protocol_pipe[0] >= 0 + || count_needed <= 0) { fd_set readfds; fd_set writefds; int numfds; #ifdef SERVER_FLOWCONTROL int bufmemsize; + struct timeval *timeout_ptr; + struct timeval timeout; /* * See if we are swamping the remote client and filling our VM. @@ -2944,8 +2938,24 @@ error \n"); FD_ZERO (&readfds); FD_ZERO (&writefds); + + if (count_needed <= 0) + { + /* there is data pending which was read from the protocol pipe + * so don't block if we don't find any data + */ + timeout.tv_sec = 0; + timeout.tv_usec = 0; + timeout_ptr = &timeout; + } + else + { + /* block indefinately */ + timeout_ptr = NULL; + } + if (! buf_empty_p (buf_to_net)) - FD_SET (STDOUT_FILENO, &writefds); + FD_SET (STDOUT_FILENO, &writefds); if (stdout_pipe[0] >= 0) { @@ -2961,28 +2971,34 @@ error \n"); } /* This process of selecting on the three pipes means that - we might not get output in the same order in which it - was written, thus producing the well-known - "out-of-order" bug. If the child process uses - cvs_output and cvs_outerr, it will send everything on - the protocol_pipe and avoid this problem, so the - solution is to use cvs_output and cvs_outerr in the - child process. */ + we might not get output in the same order in which it + was written, thus producing the well-known + "out-of-order" bug. If the child process uses + cvs_output and cvs_outerr, it will send everything on + the protocol_pipe and avoid this problem, so the + solution is to use cvs_output and cvs_outerr in the + 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. */ numfds = select (num_to_check, &readfds, &writefds, - (fd_set *)0, (struct timeval *)NULL); + (fd_set *)0, timeout_ptr); if (numfds < 0 - && errno != EINTR) + && errno != EINTR) { buf_output0 (buf_to_net, "E select failed\n"); print_error (errno); goto error_exit; } } while (numfds < 0); - + + if (numfds == 0) + { + FD_ZERO (&readfds); + FD_ZERO (&writefds); + } + if (FD_ISSET (STDOUT_FILENO, &writefds)) { /* What should we do with errors? syslog() them? */ @@ -2994,7 +3010,6 @@ error \n"); { int status; int count_read; - int special; status = buf_input_data (protocol_inbuf, &count_read); @@ -3017,29 +3032,49 @@ error \n"); * have. */ count_needed -= count_read; - while (count_needed <= 0) - { - count_needed = buf_copy_counted (buf_to_net, + } + /* this is still part of the protocol pipe procedure, but it is + * outside the above conditional so that unprocessed data can be + * left in the buffer and stderr/stdout can be read when a flush + * signal is received and control can return here without passing + * through the select code and maybe blocking + */ + while (count_needed <= 0) + { + int special = 0; + + count_needed = buf_copy_counted (buf_to_net, protocol_inbuf, &special); - /* What should we do with errors? syslog() them? */ - buf_send_output (buf_to_net); + /* What should we do with errors? syslog() them? */ + buf_send_output (buf_to_net); - /* If SPECIAL got set to -1, it means that the child - wants us to flush the pipe. We don't want to block - on the network, but we flush what we can. If the - client supports the 'F' command, we send it. */ - if (special == -1) + /* If SPECIAL got set to <0, it means that the child + * wants us to flush the pipe & maybe stderr or stdout. + * + * After that we break to read stderr & stdout again before + * going back to the protocol pipe + * + * Upon breaking, count_needed = 0, so the next pass will only + * perform a non-blocking select before returning here to finish + * processing data we already read from the protocol buffer + */ + if (special == -1) + { + cvs_flushout(); + break; + } + if (special == -2) + { + /* If the client supports the 'F' command, we send it. */ + if (supported_response ("F")) { - if (supported_response ("F")) - { - buf_append_char (buf_to_net, 'F'); - buf_append_char (buf_to_net, '\n'); - } - - cvs_flusherr (); + buf_append_char (buf_to_net, 'F'); + buf_append_char (buf_to_net, '\n'); } + cvs_flusherr (); + break; } } @@ -3426,6 +3461,11 @@ server_scratch (fname) * two different cases. Using the last one which happens is almost * surely correct; I haven't tracked down why they both happen (or * even verified that they are for the same file). + * + * Don't know if this is what whoever wrote the above comment was + * talking about, but this can happen in the case where a join + * removes a file - the call to Register puts the '-vers' into the + * Entries file after the file is removed */ if (entries_line != NULL) { @@ -3585,6 +3625,15 @@ serve_log (arg) } static void +serve_rlog (arg) + char *arg; +{ + /* Tell cvslog() to behave like rlog not log. */ + command_name = "rlog"; + do_cvs_command ("rlog", cvslog); +} + +static void serve_add (arg) char *arg; { @@ -3623,7 +3672,9 @@ static void serve_rtag (arg) char *arg; { - do_cvs_command ("rtag", rtag); + /* Tell cvstag() to behave like rtag not tag. */ + command_name = "rtag"; + do_cvs_command ("rtag", cvstag); } static void @@ -3747,7 +3798,10 @@ serve_init (arg) /* Fall through to do_cvs_command which will return the actual error. */ } - set_local_cvsroot (arg); + + if (current_parsed_root != NULL) + free_cvsroot_t (current_parsed_root); + current_parsed_root = local_cvsroot (arg); do_cvs_command ("init", init); } @@ -3760,6 +3814,17 @@ serve_annotate (arg) { do_cvs_command ("annotate", annotate); } + +static void serve_rannotate PROTO ((char *)); + +static void +serve_rannotate (arg) + char *arg; +{ + /* Tell annotate() to behave like rannotate not annotate. */ + command_name = "rannotate"; + do_cvs_command ("rannotate", annotate); +} static void serve_co (arg) @@ -4157,6 +4222,23 @@ CVS server internal error: unhandled case in server_updated"); output_dir (finfo->update_dir, finfo->repository); buf_output0 (protocol, finfo->file); buf_output (protocol, "\n", 1); + /* keep the vers structure up to date in case we do a join + * - if there isn't a file, it can't very well have a version number, can it? + * + * we do it here on the assumption that since we just told the client + * to remove the file/entry, it will, and we want to remember that. + * If it fails, that's the client's problem, not ours + */ + if (vers && vers->vn_user != NULL) + { + free (vers->vn_user); + vers->vn_user = NULL; + } + if (vers && vers->ts_user != NULL) + { + free (vers->ts_user); + vers->ts_user = NULL; + } } else if (scratched_file == NULL && entries_line == NULL) { @@ -4490,7 +4572,7 @@ serve_expand_modules (arg) for (i = 1; i < argument_count; i++) err += do_module (db, argument_vector[i], CHECKOUT, "Updating", expand_proc, - NULL, 0, 0, 0, + NULL, 0, 0, 0, 0, (char *) NULL); close_module (db); server_expanding = 0; @@ -4691,6 +4773,7 @@ struct request requests[] = REQ_LINE("update", serve_update, RQ_ESSENTIAL), REQ_LINE("diff", serve_diff, 0), REQ_LINE("log", serve_log, 0), + REQ_LINE("rlog", serve_rlog, 0), REQ_LINE("add", serve_add, 0), REQ_LINE("remove", serve_remove, 0), REQ_LINE("update-patches", serve_ignore, 0), @@ -4712,6 +4795,7 @@ struct request requests[] = REQ_LINE("editors", serve_editors, 0), REQ_LINE("init", serve_init, RQ_ROOTLESS), REQ_LINE("annotate", serve_annotate, 0), + REQ_LINE("rannotate", serve_rannotate, 0), REQ_LINE("noop", serve_noop, RQ_ROOTLESS), REQ_LINE("version", serve_version, RQ_ROOTLESS), REQ_LINE(NULL, NULL, 0) @@ -4745,7 +4829,7 @@ serve_valid_requests (arg) buf_flush (buf_to_net, 1); } -#ifdef sun +#ifdef SUNOS_KLUDGE /* * Delete temporary files. SIG is the signal making this happen, or * 0 if not called as a result of a signal. @@ -4759,7 +4843,7 @@ static void wait_sig (sig) if (r == command_pid) command_pid_is_dead++; } -#endif +#endif /* SUNOS_KLUDGE */ void server_cleanup (sig) @@ -4803,7 +4887,7 @@ server_cleanup (sig) /* What a bogus kludge. This disgusting code makes all kinds of assumptions about SunOS, and is only for a bug in that system. So only enable it on Suns. */ -#ifdef sun +#ifdef SUNOS_KLUDGE if (command_pid > 0) { /* To avoid crashes on SunOS due to bugs in SunOS tmpfs @@ -4876,7 +4960,7 @@ server_cleanup (sig) } } } -#endif +#endif /* SUNOS_KLUDGE */ CVS_CHDIR (Tmpdir); /* Temporarily clear noexec, so that we clean up our temp directory @@ -5014,19 +5098,25 @@ error ENOMEM Virtual memory exhausted.\n"); pending_error = status; } #ifndef CHMOD_BROKEN - else + else if (chmod (server_temp_dir, S_IRWXU) < 0) { - if (chmod (server_temp_dir, S_IRWXU) < 0) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (server_temp_dir))) - sprintf (pending_error_text, + int save_errno = errno; + if (alloc_pending (80 + strlen (server_temp_dir))) + sprintf (pending_error_text, "E cannot change permissions on temporary directory %s", - server_temp_dir); - pending_error = save_errno; - } + server_temp_dir); + pending_error = save_errno; } #endif + else if (CVS_CHDIR (server_temp_dir) < 0) + { + int save_errno = errno; + if (alloc_pending (80 + strlen (server_temp_dir))) + sprintf (pending_error_text, +"E cannot change to temporary directory %s", + server_temp_dir); + pending_error = save_errno; + } } } @@ -5122,7 +5212,7 @@ error ENOMEM Virtual memory exhausted.\n"); continue; if (!(rq->flags & RQ_ROOTLESS) - && CVSroot_directory == NULL) + && current_parsed_root == NULL) { /* For commands which change the way in which data is sent and received, for example Gzip-stream, @@ -5256,10 +5346,10 @@ error 0 %s: no such user\n", username); #endif #if HAVE_PUTENV - /* Set LOGNAME and USER in the environment, in case they are - already set to something else. */ + /* Set LOGNAME, USER and CVS_USER in the environment, in case they + are already set to something else. */ { - char *env; + char *env, *cvs_user; env = xmalloc (sizeof "LOGNAME=" + strlen (username)); (void) sprintf (env, "LOGNAME=%s", username); @@ -5268,6 +5358,11 @@ error 0 %s: no such user\n", username); env = xmalloc (sizeof "USER=" + strlen (username)); (void) sprintf (env, "USER=%s", username); (void) putenv (env); + + cvs_user = NULL != CVS_Username ? CVS_Username : ""; + env = xmalloc (sizeof "CVS_USER=" + strlen (cvs_user)); + (void) sprintf (env, "CVS_USER=%s", cvs_user); + (void) putenv (env); } #endif /* HAVE_PUTENV */ } @@ -5302,7 +5397,7 @@ check_repository_password (username, password, repository, host_user_ptr) int found_it = 0; int namelen; - /* We don't use CVSroot_directory because it hasn't been set yet + /* We don't use current_parsed_root->directory because it hasn't been set yet * -- our `repository' argument came from the authentication * protocol, not the regular CVS protocol. */ @@ -5632,8 +5727,13 @@ pserver_authenticate_connection () { int on = 1; - (void) setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, - (char *) &on, sizeof on); + if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, + (char *) &on, sizeof on) < 0) + { +#ifdef HAVE_SYSLOG_H + syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m"); +#endif + } } #endif @@ -5689,13 +5789,13 @@ pserver_authenticate_connection () error (1, 0, "bad auth protocol end: %s", tmp); } if (!root_allow_ok (repository)) - /* Just give a generic I HATE YOU. This is because CVS 1.9.10 - and older clients do not support "error". Once more recent - clients are more widespread, probably want to fix this (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 %s: no such repository\n", repository); +#ifdef HAVE_SYSLOG_H + syslog (LOG_DAEMON | LOG_NOTICE, "login refused for %s", repository); +#endif goto i_hate_you; + } /* OK, now parse the config file, so we can use it to control how to check passwords. If there was an error parsing the config @@ -5711,6 +5811,13 @@ pserver_authenticate_connection () free (descrambled_password); if (host_user == NULL) { +#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 i_hate_you: printf ("I HATE YOU\n"); fflush (stdout); @@ -5792,8 +5899,13 @@ error %s getpeername or getsockname failed\n", strerror (errno)); { int on = 1; - (void) setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, - (char *) &on, sizeof on); + if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, + (char *) &on, sizeof on) < 0) + { +#ifdef HAVE_SYSLOG_H + syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m"); +#endif + } } #endif @@ -6389,13 +6501,20 @@ cvs_flusherr () #ifdef SERVER_SUPPORT if (error_use_protocol) { + /* skip the actual stderr flush in this case since the parent process + * on the server should only be writing to stdout anyhow + */ /* Flush what we can to the network, but don't block. */ buf_flush (buf_to_net, 0); } else if (server_active) { + /* make sure stderr is flushed before we send the flush count on the + * protocol pipe + */ + fflush (stderr); /* Send a special count to tell the parent to flush. */ - buf_send_special_count (protocol, -1); + buf_send_special_count (protocol, -2); } else #endif @@ -6421,7 +6540,13 @@ cvs_flushout () cvs_flushout replaces, setting stdout to line buffering in main.c, didn't get called in the server child process. But in the future it is quite plausible that we'll want to make - this case work analogously to cvs_flusherr. */ + this case work analogously to cvs_flusherr. + + FIXME - DRP - I tried to implement this and triggered the following + error: "Protocol error: uncounted data discarded". I don't need + this feature right now, so I'm not going to bother with it yet. + */ + buf_send_special_count (protocol, -1); } else #endif diff --git a/contrib/cvs/src/stamp-h2.in b/contrib/cvs/src/stamp-h2.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/contrib/cvs/src/stamp-h2.in @@ -0,0 +1 @@ +timestamp diff --git a/contrib/cvs/src/status.c b/contrib/cvs/src/status.c index 4e5ddcb..7b64d30 100644 --- a/contrib/cvs/src/status.c +++ b/contrib/cvs/src/status.c @@ -67,7 +67,7 @@ cvsstatus (argc, argv) wrap_setup (); #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { start_server (); @@ -135,11 +135,9 @@ status_fileproc (callerdat, finfo) case T_CHECKOUT: sstat = "Needs Checkout"; break; -#ifdef SERVER_SUPPORT case T_PATCH: sstat = "Needs Patch"; break; -#endif case T_CONFLICT: /* I _think_ that "unresolved" is correct; that if it has been resolved then the status will change. But I'm not diff --git a/contrib/cvs/src/subr.c b/contrib/cvs/src/subr.c index c9f3747..8211a77 100644 --- a/contrib/cvs/src/subr.c +++ b/contrib/cvs/src/subr.c @@ -11,6 +11,15 @@ #include "cvs.h" #include "getline.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 */ + extern char *getlogin (); /* @@ -111,6 +120,19 @@ expand_string (strptr, n, newsize) } } +/* *STR is a pointer to a malloc'd string. *LENP is its allocated + length. Add SRC to the end of it, reallocating if necessary. */ +void +allocate_and_strcat (str, lenp, src) + char **str; + size_t *lenp; + const char *src; +{ + + expand_string (str, lenp, strlen (*str) + strlen (src) + 1); + strcat (*str, src); +} + /* * Duplicate a string, calling xmalloc to allocate some dynamic space */ @@ -776,3 +798,96 @@ backup_file (filename, suffix) return backup_name; } +/* + * Copy a string into a buffer escaping any shell metacharacters. The + * buffer should be at least twice as long as the string. + * + * Returns a pointer to the terminating NUL byte in buffer. + */ + +char * +shell_escape(buf, str) + char *buf; + const char *str; +{ + static const char meta[] = "$`\\\""; + const char *p; + + for (;;) + { + p = strpbrk(str, meta); + if (!p) p = str + strlen(str); + if (p > str) + { + memcpy(buf, str, p - str); + buf += p - str; + } + if (!*p) break; + *buf++ = '\\'; + *buf++ = *p++; + str = p; + } + *buf = '\0'; + return buf; +} + +/* + * We can only travel forwards in time, not backwards. :) + */ +void +sleep_past (desttime) + time_t desttime; +{ + time_t t; + long s; + long us; + + while (time (&t) <= desttime) + { +#ifdef HAVE_GETTIMEOFDAY + struct timeval tv; + gettimeofday (&tv, NULL); + if (tv.tv_sec > desttime) + break; + s = desttime - tv.tv_sec; + if (tv.tv_usec > 0) + us = 1000000 - tv.tv_usec; + else + { + s++; + us = 0; + } +#else + /* default to 20 ms increments */ + s = desttime - t; + us = 20000; +#endif + +#if defined(HAVE_NANOSLEEP) + { + struct timespec ts; + ts.tv_sec = s; + ts.tv_nsec = us * 1000; + (void)nanosleep (&ts, NULL); + } +#elif defined(HAVE_USLEEP) + if (s > 0) + (void)sleep (s); + else + (void)usleep (us); +#elif defined(HAVE_SELECT) + { + /* use select instead of sleep since it is a fairly portable way of + * sleeping for ms. + */ + struct timeval tv; + tv.tv_sec = s; + tv.tv_usec = us; + (void)select (0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL, &tv); + } +#else + if (us > 0) s++; + (void)sleep(s); +#endif + } +} diff --git a/contrib/cvs/src/tag.c b/contrib/cvs/src/tag.c index a9d8534..a2883c8 100644 --- a/contrib/cvs/src/tag.c +++ b/contrib/cvs/src/tag.c @@ -5,15 +5,19 @@ * 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. * - * Tag + * Tag and Rtag * * Add or delete a symbolic name to an RCS file, or a collection of RCS files. - * Uses the checked out revision in the current directory. + * Tag uses the checked out revision in the current directory, rtag uses + * the modules database, if necessary. */ #include "cvs.h" #include "savecwd.h" +static int rtag_proc PROTO((int argc, char **argv, char *xwhere, + char *mwhere, char *mfile, int shorten, + 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, @@ -26,20 +30,22 @@ 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 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)); -static int tag_filesdoneproc PROTO ((void *callerdat, int err, - char *repos, char *update_dir, - List *entries)); -static char *numtag; +static char *numtag; /* specific revision to tag */ +static int numtag_validated = 0; static char *date = NULL; -static char *symtag; +static char *symtag; /* tag to add or delete */ static int delete_flag; /* adding a tag by default */ static int branch_mode; /* make an automagic "branch" tag */ static int local; /* recursive by default */ -static int force_tag_match = 1; /* force tag to match by default */ +static int force_tag_match = 1; /* force tag to match by default */ static int force_tag_move; /* don't force tag to move by default */ static int check_uptodate; /* no uptodate-check by default */ +static int attic_too; /* remove tag from Attic files */ +static int is_rtag; struct tag_info { @@ -57,18 +63,37 @@ struct master_lists static List *mtlist; static List *tlist; -static const char *const tag_usage[] = +static const char rtag_opts[] = "+abdFflnQqRr:D:"; +static const char *const rtag_usage[] = { - "Usage: %s %s [-lRF] [-b] [-d] [-c] [-r rev|-D date] tag [files...]\n", + "Usage: %s %s [-abdFflnR] [-r rev|-D date] tag modules...\n", + "\t-a\tClear tag from removed files that would not otherwise be tagged.\n", + "\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n", + "\t-d\tDelete the given tag.\n", + "\t-F\tMove tag if it already exists.\n", + "\t-f\tForce a head revision match if tag/date not found.\n", "\t-l\tLocal directory only, not recursive.\n", + "\t-n\tNo execution of 'tag program'.\n", "\t-R\tProcess directories recursively.\n", - "\t-d\tDelete the given tag.\n", "\t-r rev\tExisting revision/tag.\n", "\t-D\tExisting date.\n", - "\t-f\tForce a head revision if specified tag not found.\n", + "(Specify the --help global option for a list of other help options)\n", + NULL +}; + +static const char tag_opts[] = "+bcdFflQqRr:D:"; +static const char *const tag_usage[] = +{ + "Usage: %s %s [-bcdFflR] [-r rev|-D date] tag [files...]\n", "\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n", - "\t-F\tMove tag if it already exists.\n", "\t-c\tCheck that working files are unmodified.\n", + "\t-d\tDelete the given tag.\n", + "\t-F\tMove tag if it already exists.\n", + "\t-f\tForce a head revision match if tag/date not found.\n", + "\t-l\tLocal directory only, not recursive.\n", + "\t-R\tProcess directories recursively.\n", + "\t-r rev\tExisting revision/tag.\n", + "\t-D\tExisting date.\n", "(Specify the --help global option for a list of other help options)\n", NULL }; @@ -80,15 +105,42 @@ cvstag (argc, argv) { int c; int err = 0; + int run_module_prog = 1; + is_rtag = (strcmp (command_name, "rtag") == 0); + if (argc == -1) - usage (tag_usage); + usage (is_rtag ? rtag_usage : tag_usage); optind = 0; - while ((c = getopt (argc, argv, "+FQqlRcdr:D:bf")) != -1) + while ((c = getopt (argc, argv, is_rtag ? rtag_opts : tag_opts)) != -1) { switch (c) { + case 'a': + attic_too = 1; + break; + case 'b': + branch_mode = 1; + break; + case 'c': + check_uptodate = 1; + break; + case 'd': + delete_flag = 1; + break; + case 'F': + force_tag_move = 1; + break; + case 'f': + force_tag_match = 0; + break; + case 'l': + local = 1; + break; + case 'n': + run_module_prog = 0; + break; case 'Q': case 'q': #ifdef SERVER_SUPPORT @@ -100,18 +152,9 @@ cvstag (argc, argv) "-q or -Q must be specified before \"%s\"", command_name); break; - case 'l': - local = 1; - break; case 'R': local = 0; break; - case 'd': - delete_flag = 1; - break; - case 'c': - check_uptodate = 1; - break; case 'r': numtag = optarg; break; @@ -120,26 +163,17 @@ cvstag (argc, argv) free (date); date = Make_Date (optarg); break; - case 'f': - force_tag_match = 0; - break; - case 'b': - branch_mode = 1; - break; - case 'F': - force_tag_move = 1; - break; case '?': default: - usage (tag_usage); + usage (is_rtag ? rtag_usage : tag_usage); break; } } argc -= optind; argv += optind; - if (argc == 0) - usage (tag_usage); + if (argc < (is_rtag ? 2 : 1)) + usage (is_rtag ? rtag_usage : tag_usage); symtag = argv[0]; argc--; argv++; @@ -151,25 +185,29 @@ cvstag (argc, argv) RCS_check_tag (symtag); #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { /* We're the client side. Fire up the remote server. */ start_server (); ign_setup (); - if (!force_tag_match) - send_arg ("-f"); - if (local) - send_arg("-l"); - if (delete_flag) - send_arg("-d"); - if (check_uptodate) - send_arg("-c"); + if (attic_too) + send_arg("-a"); if (branch_mode) send_arg("-b"); + if (check_uptodate) + send_arg("-c"); + if (delete_flag) + send_arg("-d"); if (force_tag_move) send_arg("-F"); + if (!force_tag_match) + send_arg ("-f"); + if (local) + send_arg("-l"); + if (!run_module_prog) + send_arg("-n"); if (numtag) option_with_arg ("-r", numtag); @@ -178,20 +216,155 @@ cvstag (argc, argv) send_arg (symtag); - send_files (argc, argv, local, 0, + if (is_rtag) + { + int i; + for (i = 0; i < argc; ++i) + send_arg (argv[i]); + send_to_server ("rtag\012", 0); + } + else + { + + send_files (argc, argv, local, 0, /* I think the -c case is like "cvs status", in which we really better be correct rather than being fast; it is just too confusing otherwise. */ - check_uptodate ? 0 : SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server ("tag\012", 0); + check_uptodate ? 0 : SEND_NO_CONTENTS); + send_file_names (argc, argv, SEND_EXPAND_WILD); + send_to_server ("tag\012", 0); + } + return get_responses_and_close (); } #endif - if (numtag != NULL) - tag_check_valid (numtag, argc, argv, local, 0, ""); + if (is_rtag) + { + DBM *db; + int i; + db = open_module (); + for (i = 0; i < argc; i++) + { + /* XXX last arg should be repository, but doesn't make sense here */ + history_write ('T', (delete_flag ? "D" : (numtag ? numtag : + (date ? date : "A"))), symtag, argv[i], ""); + err += do_module (db, argv[i], TAG, + delete_flag ? "Untagging" : "Tagging", + rtag_proc, (char *) NULL, 0, 0, run_module_prog, + 0, symtag); + } + close_module (db); + } + else + { + err = rtag_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, 0, NULL, + NULL); + } + + return (err); +} + +/* + * callback proc for doing the real work of tagging + */ +/* ARGSUSED */ +static int +rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified, + mname, msg) + int argc; + char **argv; + char *xwhere; + char *mwhere; + char *mfile; + int shorten; + int local_specified; + char *mname; + char *msg; +{ + /* Begin section which is identical to patch_proc--should this + be abstracted out somehow? */ + char *myargv[2]; + int err = 0; + int which; + char *repository; + char *where; + + if (is_rtag) + { + 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) + + 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 != NULL) + { + char *cp; + char *path; + + /* 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); + mfile = cp + 1; + } + + /* take care of the rest */ + path = xmalloc (strlen (repository) + strlen (mfile) + 5); + (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); + } + else + { + myargv[0] = argv[0]; + myargv[1] = mfile; + argc = 2; + argv = myargv; + } + free (path); + } + + /* cd to the starting repository */ + if ( CVS_CHDIR (repository) < 0) + { + error (0, errno, "cannot chdir to %s", repository); + 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 + { + where = NULL; + which = W_LOCAL; + repository = ""; + } + + if (numtag != NULL && !numtag_validated) + { + tag_check_valid (numtag, argc - 1, argv + 1, local, 0, repository); + numtag_validated = 1; + } /* check to make sure they are authorized to tag all the specified files in the repository */ @@ -199,19 +372,32 @@ cvstag (argc, argv) mtlist = getlist(); err = start_recursion (check_fileproc, check_filesdoneproc, (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, W_LOCAL, 0, 1, - (char *) NULL, 1); + argc - 1, argv + 1, local, which, 0, 1, + where, 1); if (err) { error (1, 0, "correct the above errors first!"); } + /* It would be nice to provide consistency with respect to + commits; however CVS lacks the infrastructure to do that (see + Concurrency in cvs.texinfo and comment in do_recursion). We + do need to ensure that the RCS file info that gets read and + cached in do_recursion isn't stale by the time we get around + to using it to rewrite the RCS file in the callback, and this + is the easiest way to accomplish that. */ + lock_tree_for_write (argc - 1, argv + 1, local, which, 0); + /* start the recursion processor */ - err = start_recursion (tag_fileproc, tag_filesdoneproc, tag_dirproc, - (DIRLEAVEPROC) NULL, NULL, argc, argv, local, - W_LOCAL, 0, 0, (char *) NULL, 1); - dellist(&mtlist); + err = start_recursion (is_rtag ? rtag_fileproc : tag_fileproc, + (FILESDONEPROC) NULL, tag_dirproc, + (DIRLEAVEPROC) NULL, NULL, argc - 1, argv + 1, + local, which, 0, 0, where, 1); + Lock_Cleanup (); + dellist (&mtlist); + if (where != NULL) + free (where); return (err); } @@ -231,7 +417,8 @@ check_fileproc (callerdat, finfo) { Ctype status = Classify_File (finfo, (char *) NULL, (char *) NULL, (char *) NULL, 1, 0, &vers, 0); - if ((status != T_UPTODATE) && (status != T_CHECKOUT)) + if ((status != T_UPTODATE) && (status != T_CHECKOUT) && + (status != T_PATCH)) { error (0, 0, "%s is locally modified", finfo->fullname); freevers_ts (&vers); @@ -282,7 +469,7 @@ check_fileproc (callerdat, finfo) version we are going to tag. There probably are some subtle races (e.g. numtag is "foo" which gets moved between here and tag_fileproc). */ - if (numtag == NULL && date == NULL) + if (!is_rtag && numtag == NULL && date == NULL) p->data = xstrdup (vers->vn_user); else p->data = RCS_getversion (vers->srcfile, numtag, date, @@ -327,7 +514,7 @@ check_fileproc (callerdat, finfo) p->data = NULL; } } - freevers_ts(&vers); + freevers_ts (&vers); (void) addnode (tlist, p); return (0); } @@ -437,6 +624,192 @@ pretag_list_proc(p, closure) /* + * Called to rtag a particular file, as appropriate with the options that were + * set above. + */ +/* ARGSUSED */ +static int +rtag_fileproc (callerdat, finfo) + void *callerdat; + struct file_info *finfo; +{ + RCSNode *rcsfile; + char *version, *rev; + int retcode = 0; + + /* find the parsed RCS data */ + if ((rcsfile = finfo->rcs) == NULL) + return (1); + + /* + * For tagging an RCS file which is a symbolic link, you'd best be + * running with RCS 5.6, since it knows how to handle symbolic links + * correctly without breaking your link! + */ + + if (delete_flag) + return (rtag_delete (rcsfile)); + + /* + * If we get here, we are adding a tag. But, if -a was specified, we + * need to check to see if a -r or -D option was specified. If neither + * was specified and the file is in the Attic, remove the tag. + */ + if (attic_too && (!numtag && !date)) + { + if ((rcsfile->flags & VALID) && (rcsfile->flags & INATTIC)) + return (rtag_delete (rcsfile)); + } + + version = RCS_getversion (rcsfile, numtag, date, force_tag_match, + (int *) NULL); + if (version == NULL) + { + /* If -a specified, clean up any old tags */ + if (attic_too) + (void) rtag_delete (rcsfile); + + if (!quiet && !force_tag_match) + { + error (0, 0, "cannot find tag `%s' in `%s'", + numtag ? numtag : "head", rcsfile->path); + return (1); + } + return (0); + } + if (numtag + && isdigit ((unsigned char) *numtag) + && strcmp (numtag, version) != 0) + { + + /* + * We didn't find a match for the numeric tag that was specified, but + * that's OK. just pass the numeric tag on to rcs, to be tagged as + * specified. Could get here if one tried to tag "1.1.1" and there + * was a 1.1.1 branch with some head revision. In this case, we want + * the tag to reference "1.1.1" and not the revision at the head of + * the branch. Use a symbolic tag for that. + */ + rev = branch_mode ? RCS_magicrev (rcsfile, version) : numtag; + retcode = RCS_settag(rcsfile, symtag, numtag); + if (retcode == 0) + RCS_rewrite (rcsfile, NULL, NULL); + } + else + { + char *oversion; + + /* + * As an enhancement for the case where a tag is being re-applied to + * a large body of a module, make one extra call to RCS_getversion to + * see if the tag is already set in the RCS file. If so, check to + * see if it needs to be moved. If not, do nothing. This will + * likely save a lot of time when simply moving the tag to the + * "current" head revisions of a module -- which I have found to be a + * typical tagging operation. + */ + rev = branch_mode ? RCS_magicrev (rcsfile, version) : version; + oversion = RCS_getversion (rcsfile, symtag, (char *) NULL, 1, + (int *) NULL); + if (oversion != NULL) + { + int isbranch = RCS_nodeisbranch (finfo->rcs, symtag); + + /* + * if versions the same and neither old or new are branches don't + * have to do anything + */ + if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch) + { + free (oversion); + free (version); + return (0); + } + + if (!force_tag_move) + { + /* we're NOT going to move the tag */ + (void) printf ("W %s", finfo->fullname); + + (void) printf (" : %s already exists on %s %s", + symtag, isbranch ? "branch" : "version", + oversion); + (void) printf (" : NOT MOVING tag to %s %s\n", + branch_mode ? "branch" : "version", rev); + free (oversion); + free (version); + return (0); + } + free (oversion); + } + retcode = RCS_settag(rcsfile, symtag, rev); + if (retcode == 0) + RCS_rewrite (rcsfile, NULL, NULL); + } + + if (retcode != 0) + { + error (1, retcode == -1 ? errno : 0, + "failed to set tag `%s' to revision `%s' in `%s'", + symtag, rev, rcsfile->path); + if (branch_mode) + free (rev); + free (version); + return (1); + } + if (branch_mode) + free (rev); + free (version); + return (0); +} + +/* + * If -d is specified, "force_tag_match" is set, so that this call to + * RCS_getversion() will return a NULL version string if the symbolic + * tag does not exist in the RCS file. + * + * If the -r flag was used, numtag is set, and we only delete the + * symtag from files that have numtag. + * + * This is done here because it's MUCH faster than just blindly calling + * "rcs" to remove the tag... trust me. + */ +static int +rtag_delete (rcsfile) + RCSNode *rcsfile; +{ + char *version; + int retcode; + + if (numtag) + { + version = RCS_getversion (rcsfile, numtag, (char *) NULL, 1, + (int *) NULL); + if (version == NULL) + return (0); + free (version); + } + + version = RCS_getversion (rcsfile, symtag, (char *) NULL, 1, + (int *) NULL); + if (version == NULL) + return (0); + free (version); + + if ((retcode = RCS_deltag(rcsfile, symtag)) != 0) + { + if (!quiet) + error (0, retcode == -1 ? errno : 0, + "failed to remove tag `%s' from `%s'", symtag, + rcsfile->path); + return (1); + } + RCS_rewrite (rcsfile, NULL, NULL); + return (0); +} + + +/* * Called to tag a particular file (the currently checked out version is * tagged with the specified tag - or the specified tag is deleted). */ @@ -452,17 +825,6 @@ tag_fileproc (callerdat, finfo) Vers_TS *vers; int retcode = 0; - /* Lock the directory if it is not already locked. We can't rely - on tag_dirproc because it won't handle the case where the user - specifies a list of files on the command line. */ - /* We do not need to acquire a full write lock for the tag operation: - the revisions are obtained from the working directory, so we do not - require consistency across the entire repository. However, we do - need to prevent simultaneous tag operations from interfering with - each other. Therefore, we write lock each directory as we enter - it, and unlock it as we leave it. */ - lock_dir_for_write (finfo->repository); - vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0); if ((numtag != NULL) || (date != NULL)) @@ -644,21 +1006,6 @@ tag_fileproc (callerdat, finfo) return (0); } -/* Clear any lock we may hold on the current directory. */ - -static int -tag_filesdoneproc (callerdat, err, repos, update_dir, entries) - void *callerdat; - int err; - char *repos; - char *update_dir; - List *entries; -{ - Lock_Cleanup (); - - return (err); -} - /* * Print a warm fuzzy message */ @@ -671,6 +1018,15 @@ tag_dirproc (callerdat, dir, repos, update_dir, entries) char *update_dir; List *entries; { + + if (ignore_directory (update_dir)) + { + /* print the warm fuzzy message */ + if (!quiet) + error (0, 0, "Ignoring %s", update_dir); + return R_SKIP_ALL; + } + if (!quiet) error (0, 0, "%s %s", delete_flag ? "Untagging" : "Tagging", update_dir); return (R_PROCESS); @@ -758,6 +1114,7 @@ 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; struct saved_cwd cwd; @@ -789,24 +1146,28 @@ Numeric tag %s contains characters other than digits and '.'", name); mytag.dptr = name; mytag.dsize = strlen (name); - valtags_filename = xmalloc (strlen (CVSroot_directory) + valtags_filename = xmalloc (strlen (current_parsed_root->directory) + sizeof CVSROOTADM - + sizeof CVSROOTADM_VALTAGS + 20); - strcpy (valtags_filename, CVSroot_directory); - strcat (valtags_filename, "/"); - strcat (valtags_filename, CVSROOTADM); - strcat (valtags_filename, "/"); - strcat (valtags_filename, CVSROOTADM_VALTAGS); + + sizeof CVSROOTADM_VALTAGS + 3); + sprintf (valtags_filename, "%s/%s/%s", current_parsed_root->directory, + CVSROOTADM, CVSROOTADM_VALTAGS); db = dbm_open (valtags_filename, O_RDWR, 0666); if (db == NULL) { if (!existence_error (errno)) - error (1, errno, "cannot read %s", valtags_filename); - + { + error (0, errno, "warning: cannot open %s read/write", + valtags_filename); + db = dbm_open (valtags_filename, O_RDONLY, 0666); + if (db != NULL) + nowrite = 1; + else if (!existence_error (errno)) + error (1, errno, "cannot read %s", valtags_filename); + } /* If the file merely fails to exist, we just keep going and create it later if need be. */ } - else + if (db != NULL) { datum val; @@ -868,7 +1229,7 @@ Numeric tag %s contains characters other than digits and '.'", name); /* The tags is valid but not mentioned in val-tags. Add it. */ datum value; - if (noexec) + if (noexec || nowrite) { if (db != NULL) dbm_close (db); @@ -885,7 +1246,7 @@ Numeric tag %s contains characters other than digits and '.'", name); if (db == NULL) { - error (0, errno, "cannot create %s", valtags_filename); + error (0, errno, "warning: cannot create %s", valtags_filename); free (valtags_filename); return; } diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c index 81d4fea..f4b919f 100644 --- a/contrib/cvs/src/update.c +++ b/contrib/cvs/src/update.c @@ -58,7 +58,7 @@ static int patch_file PROTO ((struct file_info *finfo, static void patch_file_write PROTO ((void *, const char *, size_t)); #endif static int merge_file PROTO ((struct file_info *finfo, Vers_TS *vers)); -static int scratch_file PROTO((struct file_info *finfo)); +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)); @@ -99,6 +99,7 @@ static int force_tag_match = 1; static int update_build_dirs = 0; static int update_prune_dirs = 0; static int pipeout = 0; +static int dotemplate = 0; #ifdef SERVER_SUPPORT static int patches = 0; static int rcs_diff_patches = 0; @@ -107,7 +108,7 @@ static List *ignlist = (List *) NULL; static time_t last_register_time; static const char *const update_usage[] = { - "Usage: %s %s [-APdflRp] [-k kopt] [-r rev|-D date] [-j rev]\n", + "Usage: %s %s [-APCdflRp] [-k kopt] [-r rev] [-D date] [-j rev]\n", " [-I ign] [-W spec] [files...]\n", "\t-A\tReset any sticky tags/date/kopts.\n", "\t-P\tPrune empty directories.\n", @@ -117,7 +118,7 @@ static const char *const update_usage[] = "\t-l\tLocal directory only, no recursion.\n", "\t-R\tProcess directories recursively.\n", "\t-p\tSend updates to standard output (avoids stickiness).\n", - "\t-k kopt\tUse RCS kopt -k option on checkout.\n", + "\t-k kopt\tUse RCS kopt -k option on checkout. (is sticky)\n", "\t-r rev\tUpdate using specified revision/tag (is sticky).\n", "\t-D date\tSet date to update from (is sticky).\n", "\t-j rev\tMerge in changes made between current revision and rev.\n", @@ -233,7 +234,7 @@ update (argc, argv) argv += optind; #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { int pass; @@ -409,7 +410,7 @@ 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); + pipeout, which, join_rev1, join_rev2, (char *) NULL, 1); /* free the space Make_Date allocated if necessary */ if (date != NULL) @@ -423,7 +424,8 @@ 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) + xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir, + xdotemplate) int argc; char **argv; char *xoptions; @@ -439,6 +441,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag, char *xjoin_rev1; char *xjoin_rev2; char *preload_update_dir; + int xdotemplate; { int err = 0; char *cp; @@ -452,6 +455,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag, aflag = xaflag; update_prune_dirs = xprune; pipeout = xpipeout; + dotemplate = xdotemplate; /* setup the join support */ join_rev1 = xjoin_rev1; @@ -503,11 +507,15 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag, argc, argv, local, which, aflag, 1, preload_update_dir, 1); +#ifdef SERVER_SUPPORT + if (server_active) + return err; +#endif + /* see if we need to sleep before returning to avoid time-stamp races */ if (last_register_time) { - while (time ((time_t *) NULL) == last_register_time) - sleep (1); + sleep_past (last_register_time); } return (err); @@ -575,9 +583,6 @@ update_fileproc (callerdat, finfo) int retval; Ctype status; Vers_TS *vers; - int resurrecting; - - resurrecting = 0; status = Classify_File (finfo, tag, date, options, force_tag_match, aflag, &vers, pipeout); @@ -623,9 +628,7 @@ update_fileproc (callerdat, finfo) case T_MODIFIED: /* locally modified */ case T_REMOVED: /* removed but not committed */ case T_CHECKOUT: /* needs checkout */ -#ifdef SERVER_SUPPORT case T_PATCH: /* needs patch */ -#endif retval = checkout_file (finfo, vers, 0, 0, 0); break; @@ -650,8 +653,12 @@ update_fileproc (callerdat, finfo) write_letter (finfo, 'C'); break; case T_NEEDS_MERGE: /* needs merging */ - retval = merge_file (finfo, vers); - break; + if (! toss_local_changes) + { + retval = merge_file (finfo, vers); + break; + } + /* else FALL THROUGH */ case T_MODIFIED: /* locally modified */ retval = 0; if (toss_local_changes) @@ -731,8 +738,8 @@ update_fileproc (callerdat, finfo) } } break; -#ifdef SERVER_SUPPORT case T_PATCH: /* needs patch */ +#ifdef SERVER_SUPPORT if (patches) { int docheckout; @@ -754,11 +761,11 @@ update_fileproc (callerdat, finfo) break; } } +#endif /* If we're not running as a server, just check the file out. It's simpler and faster than producing and applying patches. */ /* Fall through. */ -#endif case T_CHECKOUT: /* needs checkout */ retval = checkout_file (finfo, vers, 0, 0, 1); break; @@ -771,18 +778,7 @@ update_fileproc (callerdat, finfo) retval = 0; break; case T_REMOVE_ENTRY: /* needs to be un-registered */ - retval = scratch_file (finfo); -#ifdef SERVER_SUPPORT - if (server_active && retval == 0) - { - if (vers->ts_user == NULL) - server_scratch_entry_only (); - server_updated (finfo, vers, - SERVER_UPDATED, (mode_t) -1, - (unsigned char *) NULL, - (struct buffer *) NULL); - } -#endif + retval = scratch_file (finfo, vers); break; default: /* can't ever happen :-) */ error (0, 0, @@ -797,7 +793,7 @@ update_fileproc (callerdat, finfo) join_file (finfo, vers); /* if this directory has an ignore list, add this file to it */ - if (ignlist) + if (ignlist && (status != T_UNKNOWN || vers->ts_user == NULL)) { Node *p; @@ -877,7 +873,7 @@ update_filesdone_proc (callerdat, err, repository, update_dir, entries) { /* If there is no CVS/Root file, add one */ if (!isfile (CVSADM_ROOT)) - Create_Root ((char *) NULL, CVSroot_original); + Create_Root ((char *) NULL, current_parsed_root->original); } return (err); @@ -970,7 +966,7 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries) via WriteTag. */ 0, 0, - 1); + dotemplate); rewrite_tag = 1; nonbranch = 0; Subdir_Register (entries, (char *) NULL, dir); @@ -1173,7 +1169,7 @@ isemptydir (dir, might_not_exist) return (0); } errno = 0; - while ((dp = readdir (dirp)) != NULL) + while ((dp = CVS_READDIR (dirp)) != NULL) { if (strcmp (dp->d_name, ".") != 0 && strcmp (dp->d_name, "..") != 0) @@ -1182,7 +1178,7 @@ isemptydir (dir, might_not_exist) { /* An entry other than the CVS directory. The directory is certainly not empty. */ - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); return (0); } else @@ -1213,7 +1209,7 @@ isemptydir (dir, might_not_exist) { /* There are files that have been removed, but not committed! Do not consider the directory empty. */ - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); return (0); } } @@ -1223,10 +1219,10 @@ isemptydir (dir, might_not_exist) if (errno != 0) { error (0, errno, "cannot read directory %s", dir); - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); return (0); } - (void) closedir (dirp); + (void) CVS_CLOSEDIR (dirp); return (1); } @@ -1234,13 +1230,46 @@ isemptydir (dir, might_not_exist) * scratch the Entries file entry associated with a file */ static int -scratch_file (finfo) +scratch_file (finfo, vers) struct file_info *finfo; + Vers_TS *vers; { history_write ('W', finfo->update_dir, "", finfo->file, finfo->repository); Scratch_Entry (finfo->entries, finfo->file); +#ifdef SERVER_SUPPORT + if (server_active) + { + if (vers->ts_user == NULL) + server_scratch_entry_only (); + server_updated (finfo, vers, + SERVER_UPDATED, (mode_t) -1, + (unsigned char *) NULL, + (struct buffer *) NULL); + } +#endif if (unlink_file (finfo->file) < 0 && ! existence_error (errno)) error (0, errno, "unable to remove %s", finfo->fullname); + else +#ifdef SERVER_SUPPORT + /* skip this step when the server is running since + * server_updated should have handled it */ + if (!server_active) +#endif + { + /* keep the vers structure up to date in case we do a join + * - if there isn't a file, it can't very well have a version number, can it? + */ + if (vers->vn_user != NULL) + { + free (vers->vn_user); + vers->vn_user = NULL; + } + if (vers->ts_user != NULL) + { + free (vers->ts_user); + vers->ts_user = NULL; + } + } return (0); } @@ -1740,7 +1769,7 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum) diff_options = "-n"; } - retcode = diff_exec (file1, file2, diff_options, finfo->file); + retcode = diff_exec (file1, file2, NULL, NULL, diff_options, finfo->file); /* A retcode of 0 means no differences. 1 means some differences. */ if (retcode != 0 @@ -2106,6 +2135,17 @@ join_file (finfo, vers) char *jdate1; char *jdate2; + if (trace) + fprintf (stderr, "%s-> join_file(%s, %s%s%s%s, %s, %s)\n", + CLIENT_SERVER_STR, + finfo->file, + vers->tag ? vers->tag : "", + vers->tag ? " (" : "", + vers->vn_rcs ? vers->vn_rcs : "", + vers->tag ? ")" : "", + join_rev1 ? join_rev1 : "", + join_rev2 ? join_rev2 : ""); + jrev1 = join_rev1; jrev2 = join_rev2; jdate1 = date_rev1; @@ -2274,7 +2314,14 @@ join_file (finfo, vers) for removal. FIXME: If we are doing a checkout, this has the effect of first checking out the file, and then removing it. It would be better to just register the - removal. */ + removal. + + The same goes for a removal then an add. e.g. + cvs up -rbr -jbr2 could remove and readd the same file + */ + /* save the rev since server_updated might invalidate it */ + mrev = xmalloc (strlen (vers->vn_user) + 2); + sprintf (mrev, "-%s", vers->vn_user); #ifdef SERVER_SUPPORT if (server_active) { @@ -2283,8 +2330,6 @@ join_file (finfo, vers) (unsigned char *) NULL, (struct buffer *) NULL); } #endif - mrev = xmalloc (strlen (vers->vn_user) + 2); - sprintf (mrev, "-%s", vers->vn_user); Register (finfo->entries, finfo->file, mrev, vers->ts_rcs, vers->options, vers->tag, vers->date, vers->ts_conflict); free (mrev); @@ -2327,6 +2372,7 @@ join_file (finfo, vers) addition. */ if (vers->vn_user == NULL) { + char *saved_options = options; Vers_TS *xvers; xvers = Version_TS (finfo, vers->options, jrev2, jdate2, 1, 0); @@ -2341,6 +2387,7 @@ join_file (finfo, vers) /* FIXME: If checkout_file fails, we should arrange to return a non-zero exit status. */ status = checkout_file (finfo, xvers, 1, 0, 1); + options = saved_options; freevers_ts (&xvers); diff --git a/contrib/cvs/src/update.h b/contrib/cvs/src/update.h index ba71310..9a1fc00 100644 --- a/contrib/cvs/src/update.h +++ b/contrib/cvs/src/update.h @@ -13,6 +13,7 @@ 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)); + char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir, + int xdotemplate)); int joining PROTO((void)); extern int isemptydir PROTO ((char *dir, int might_not_exist)); diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c index 8d55284..5524bab 100644 --- a/contrib/cvs/src/vers_ts.c +++ b/contrib/cvs/src/vers_ts.c @@ -322,6 +322,8 @@ time_stamp_server (file, vers_ts, entdata) cp = ctime (&sb.st_mtime); cp[24] = 0; + /* Fix non-standard format. */ + if (cp[8] == '0') cp[8] = ' '; (void) strcpy (vers_ts->ts_user, cp); } } @@ -365,6 +367,8 @@ time_stamp (file) cp = ctime(&sb.st_mtime); cp[24] = 0; + /* Fix non-standard format. */ + if (cp[8] == '0') cp[8] = ' '; (void) strcpy (ts, cp); } diff --git a/contrib/cvs/src/version.c b/contrib/cvs/src/version.c index c8273fb..5070615 100644 --- a/contrib/cvs/src/version.c +++ b/contrib/cvs/src/version.c @@ -12,7 +12,7 @@ #include "cvs.h" -char *version_string = "Concurrent Versions System (CVS) 1.11"; +char *version_string = "Concurrent Versions System (CVS) 1.11.1p1"; #ifdef CLIENT_SUPPORT #ifdef SERVER_SUPPORT @@ -28,12 +28,23 @@ char *config_string = "\n"; #endif #endif + + static const char *const version_usage[] = { "Usage: %s %s\n", NULL }; + + +/* + * Output a version string for the client and server. + * + * This function will output the simple version number (for the '--version' + * option) or the version numbers of the client and server (using the 'version' + * command). + */ int version (argc, argv) int argc; @@ -45,7 +56,7 @@ version (argc, argv) usage (version_usage); #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root && current_parsed_root->isremote) (void) fputs ("Client: ", stdout); #endif @@ -56,7 +67,7 @@ version (argc, argv) (void) fputs (config_string, stdout); #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root && current_parsed_root->isremote) { (void) fputs ("Server: ", stdout); start_server (); diff --git a/contrib/cvs/src/version.c.in b/contrib/cvs/src/version.c.in new file mode 100644 index 0000000..aa2f97f --- /dev/null +++ b/contrib/cvs/src/version.c.in @@ -0,0 +1,86 @@ +/* + * Copyright (c) 1994 david d `zoo' zuhn + * Copyright (c) 1994 Free Software Foundation, Inc. + * Copyright (c) 1992, Brian Berliner and Jeff Polk + * Copyright (c) 1989-1992, Brian Berliner + * + * You may distribute under the terms of the GNU General Public License as + * specified in the README file that comes with this CVS source distribution. + * + * version.c - the CVS version number + */ + +#include "cvs.h" + +char *version_string = "Concurrent Versions System (CVS) @VERSION@"; + +#ifdef CLIENT_SUPPORT +#ifdef SERVER_SUPPORT +char *config_string = " (client/server)\n"; +#else +char *config_string = " (client)\n"; +#endif +#else +#ifdef SERVER_SUPPORT +char *config_string = " (server)\n"; +#else +char *config_string = "\n"; +#endif +#endif + + + +static const char *const version_usage[] = +{ + "Usage: %s %s\n", + NULL +}; + + + +/* + * Output a version string for the client and server. + * + * This function will output the simple version number (for the '--version' + * option) or the version numbers of the client and server (using the 'version' + * command). + */ +int +version (argc, argv) + int argc; + char **argv; +{ + int err = 0; + + if (argc == -1) + usage (version_usage); + +#ifdef CLIENT_SUPPORT + if (current_parsed_root && current_parsed_root->isremote) + (void) fputs ("Client: ", stdout); +#endif + + /* Having the year here is a good idea, so people have + some idea of how long ago their version of CVS was + released. */ + (void) fputs (version_string, stdout); + (void) fputs (config_string, stdout); + +#ifdef CLIENT_SUPPORT + if (current_parsed_root && current_parsed_root->isremote) + { + (void) fputs ("Server: ", stdout); + start_server (); + if (supported_request ("version")) + send_to_server ("version\012", 0); + else + { + send_to_server ("noop\012", 0); + fputs ("(unknown)\n", stdout); + } + err = get_responses_and_close (); + } +#endif + return err; +} + diff --git a/contrib/cvs/src/watch.c b/contrib/cvs/src/watch.c index 1a0ecfe..d86968b 100644 --- a/contrib/cvs/src/watch.c +++ b/contrib/cvs/src/watch.c @@ -308,7 +308,7 @@ watch_addremove (argc, argv) } #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { start_server (); ign_setup (); @@ -348,7 +348,7 @@ watch_addremove (argc, argv) the_args.setting_default = (argc <= 0); - lock_tree_for_write (argc, argv, local, 0); + lock_tree_for_write (argc, argv, local, W_LOCAL, 0); err = start_recursion (addremove_fileproc, addremove_filesdoneproc, (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, @@ -509,7 +509,7 @@ watchers (argc, argv) argv += optind; #ifdef CLIENT_SUPPORT - if (client_active) + if (current_parsed_root->isremote) { start_server (); ign_setup (); diff --git a/contrib/cvs/src/wrapper.c b/contrib/cvs/src/wrapper.c index 2d53c7a..039590a 100644 --- a/contrib/cvs/src/wrapper.c +++ b/contrib/cvs/src/wrapper.c @@ -96,17 +96,17 @@ void wrap_setup() wrap_setup_already_done = 1; #ifdef CLIENT_SUPPORT - if (!client_active) + if (!current_parsed_root->isremote) #endif { char *file; - file = xmalloc (strlen (CVSroot_directory) + file = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) + sizeof (CVSROOTADM_WRAPPER) - + 10); + + 3); /* Then add entries found in repository, if it exists. */ - (void) sprintf (file, "%s/%s/%s", CVSroot_directory, CVSROOTADM, + (void) sprintf (file, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, CVSROOTADM_WRAPPER); if (isfile (file)) { -- cgit v1.1