diff options
author | 1999-09-10 05:06:01 +0000 | |
---|---|---|
committer | 1999-09-10 05:06:01 +0000 | |
commit | 892c0aade1f7c0f3a217301a37d1119c4a91f3cd (patch) | |
tree | 809aebd5e2b11f30b38743a60d59aab9341f407e /gnu/usr.bin/cvs/src | |
parent | Describe the fact that a separate clock is wanted for statistics and (diff) | |
download | wireguard-openbsd-892c0aade1f7c0f3a217301a37d1119c4a91f3cd.tar.xz wireguard-openbsd-892c0aade1f7c0f3a217301a37d1119c4a91f3cd.zip |
Latest version from Cyclic
Diffstat (limited to 'gnu/usr.bin/cvs/src')
-rw-r--r-- | gnu/usr.bin/cvs/src/ChangeLog | 449 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/add.c | 73 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/admin.c | 64 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/client.c | 108 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/diff.c | 2 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/edit.c | 17 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/fileattr.h | 20 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/log.c | 3 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/modules.c | 70 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/root.c | 2 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/run.c | 18 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/sanity.sh | 1471 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/status.c | 71 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/subr.c | 36 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/tag.c | 7 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/version.c | 2 |
16 files changed, 2153 insertions, 260 deletions
diff --git a/gnu/usr.bin/cvs/src/ChangeLog b/gnu/usr.bin/cvs/src/ChangeLog index 7acccf5cbfe..0d1889185a3 100644 --- a/gnu/usr.bin/cvs/src/ChangeLog +++ b/gnu/usr.bin/cvs/src/ChangeLog @@ -1,3 +1,452 @@ +1999-07-28 Eric Sink <eric@sourcegear.com> + + * sanity.sh: before running basicc-11, we need to see if + the cwd has been deleted (by basicc-8). If so, we + recreate it to allow basicc-11 to proceed. This may be + something that only happens under the Linux 2.2 kernel. + +1999-07-18 Karl Fogel <kfogel@floss.red-bean.com> + + * edit.c (notify_do): chop newline, if any, from the value + obtained from CVSROOT/users. Otherwise it just gets passed along + in the argument to the notification program (usually mail), which + will misinterpret it as signifying the end of the command. + +1999-07-19 Larry Jones <larry.jones@sdrc.com> + + * rcs.c (RCS_delete_revs): In the WIN32 kludge, be sure that the result + of RCS_getexpand is not NULL before trying to use what it points to. + (Patch submitted by Timothy L. Taylor <ttaylor@mitre.org>.) + +1999-07-16 Tom Tromey <tromey@cygnus.com> + + * admin.c (admin): Allow `-k' options to be used unrestricted. + +1999-06-23 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh (symlinks2): New test, for symlinks in working + directory without PreservePermissions. This test (modulo a few + details not relevant to testing whether we are following symlinks) + worked remote as of now, or either remote or local for CVS 1.9. + * subr.c (get_file): Revert 1998-02-15 change to special-case + symlinks. This makes the above test work local too. + * rcs.c (RCS_checkin): Move the logic to handle special-case + symlinks (and other files other than regular files) here, and make + it only happen if PreservePermissions is on. + +1999-06-18 Larry Jones <larry.jones@sdrc.com> + + * sanity.sh (devcom3-9a): Be less specific about the expected + error message (BSD/OS 4.0 has a bug that can cause exec* to fail + with EACCES instead of ENOENT). + +1999-06-08 Larry Jones <larry.jones@sdrc.com> + + * sanity.sh (diff-4, dirs2-10, tagf-13, importc-7, conflicts2-142b8): + Use ${PROG} instead of "cvs". + +1999-06-05 Jim Kingdon <http://www.cyclic.com> + + * recurse.c (do_recursion, do_dir_proc): Make the SERVER_ACTIVE + #ifdef be only around the check for server_active. Modulo a few + cosmetic tweaks, same as a patch submitted by Johannes Stezenbach + of propack-data.de. + +1999-06-01 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh: Add comment about rcs2-7 failures on certain days. + + Make "cvs status -v" on a removed file work: + * status.c (cvsstatus): Reindent the client code. + (status_fileproc): Don't need a CVS/Entries listing to show the + tags. + * sanity.sh (rmadd2): New test rmadd2-16 tests the existing + behavior with "cvs log"; new test rmadd2-17 tests the new behavior + with "cvs status". + + * sanity.sh (basicc): To match no output in dotest, put the empty + regexp first. Remove tests which check that first-dir exists, + since that isn't true in the case where the OS let us delete it. + (dotest_internal): Fix so that things work with two regexps, with + an empty one first. + +1999-05-28 Larry Jones <larry.jones@sdrc.com> + + * sanity.sh (server-4): Replace bogus directory with real one since + the server now checks it. + +1999-05-27 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh (spacefiles): Clean up -c, top, and -b at end. + (spacefiles, files): Fix bad references to CVSROOT_DIRNAME. + + Fix two problems pointed out by Olaf Kirch of swb.de/caldera.de: + * server.c (outside_root): New function, contains expanded version + of code from serve_directory. + (serve_directory): Call outside_root. + (outside_dir): New function + (serve_modified, serve_is_modified, serve_notify, + serve_questionable, serve_unchanged): Call outside_dir. + * sanity.sh (server2): New tests, for these fixes. + +1999-05-26 Jim Kingdon <http://www.cyclic.com> + + * cvs.h, subr.c (xmalloc): Return void* not char*, like xrealloc + has done for some time. + * modules.c (do_module): If we find the module as a directory/file + (rather than in the modules file), skip a bunch of processing + which was unnecessary and also broken in most of the cases + now tested for by the spacefiles sanity.sh test. + * sanity.sh (spacefiles): New test, for specifying filenames + (containing spaces, or starting with '-', or starting with '/') to + "cvs co". + +1999-05-25 Jim Kingdon <http://www.cyclic.com> + + * client.c (update_entries): Make the old DONT_USE_PATCH code the + only code. This means that if people are still on CVS 1.9 + servers, then CVS will fall back to transferring entire files. + This is better than looking for an external "patch" program which + causes no end of troubles (especially on Windows, but someone just + posted to info-cvs about a problem with the Solaris patch). (This + change was run by devel-cvs and feedback was positive). + + * subr.c (xmalloc, xrealloc): The new error.c does not support + %lu; use sprintf instead. + +1999-05-25 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + + * sanity.sh (server): Escaped a few more newlines in + another awk script. Solaris awk still don't like 'em. + +1999-05-25 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + and Jim Kingdon + + * log.c: Remove comment which said "you can delete [this line]" + and which stuck around for over 3 years. + * sanity.sh (errmsg2 & tagdate): Added tests to prove the + current functionality with respect to combining -r and -D. + +1999-05-20 Larry Jones <larry.jones@sdrc.com> + + * server.c (pserver_authenticate_connection): Previous changes + broke verify_and_exit (reported by Robert Fitzsimons, thanks). + * sanity.sh (pserver): New tests pserver-7 and pserver-8 for this. + +1999-05-18 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + + * sanity.sh (keyword2): Escaped a newline in an awk script. + Apparently Solaris awk don't like 'em. + +1999-05-18 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh (basicc): Allow the behavior whereby unlink(".") + succeeds. Reported by Jeremy Buhler and Pavel Roskin. + +1999-05-17 Steve Cameron of Compaq + + * sanity.sh: Modified to no longer use "test -e" for existence + test as it has turned out to be not portable enough. Instead use + "test -f", "test -d", etc. + [SCO Unixware 7 apparently doesn't always support it -kingdon] + +1999-05-17 Jim Kingdon <http://www.cyclic.com> + + * version.c: Push version number to 1.10.6.1. + + * version.c: Version 1.10.6. + +1999-05-16 Jim Kingdon <http://www.cyclic.com> + + * update.c (patch_file): When we are passing vn_rcs to + RCS_checkout, pass vn_tag as well. + * sanity.sh (keyword): In test keyword-22, test for the fixed + behavior rather than the buggy behavior. Adjust keyword-23. Add + test keyword-24, to see whether keyword-23 really worked. + +1999-05-12 Larry Jones <larry.jones@sdrc.com> + + * sanity.sh (pserver-4, pserver-5): Bogus error messages from + non-root initgroups on some 4.4BSD derived systems now show up + in different places in the output. + +1999-05-12 Jim Kingdon <http://www.cyclic.com> + + * import.c (import): Don't allow the user to supply a repository + directory which takes us out of the cvsroot. + * sanity.sh (importc): New tests importc-10 to importc-12, for this. + +1999-05-11 Larry Jones <larry.jones@sdrc.com> + + * server.c (serve_notify): Allocate enough memory to hold the + "misformed Notify request" message in pending_error_text. + +1999-05-11 Jim Kingdon <http://www.cyclic.com> + + * server.c (switch_to_user): Ignore EPERM from initgroups. Fixes + pserver-4 in testsuite. + (pserver_authenticate_connection): Only print "I LOVE YOU" after + switch_to_user has come back successfully. + + * server.c (pserver_authenticate_connection): Call error_exit + rather than reinventing the wheel ourselves. + (switch_to_user): Check for errors from setuid, setgid, and + initgroups. Fix the #ifdef's (the previous code would skip the + setuid call if SETXID_SUPPORT). + +1999-05-10 Jim Kingdon <http://www.cyclic.com> + + * server.c (serve_notify), edit.c (notify_do): Check for + and reject characters which will get confused with delimiters. + * sanity.sh (server): New tests server-7 through server-15 test + for this and for other notify behaviors. + + * rcs.c (RCS_tag2rev): Also look for a physical branch with + RCS_getversion. + * sanity.sh (tagf): Adjust tagf-12 and following tests to test for + the fixed behavior rather than the broken behavior. + +1999-05-07 Jim Kingdon <http://www.cyclic.com> + + * server.c (server_notify): Also set last_node to NULL. + * sanity.sh (server): New tests server-6 and server-7, for this. + +1999-05-05 Jim Kingdon <http://www.cyclic.com> + + * rcs.c (rcs_internal_lockfile): Remove unused variable lockfile. + + * add.c (add): Look for directories with the same name in a + different case where appropriate (analogous to fopen_case). + In client code, add comment about how this doesn't do quite + everything. + +1999-05-03 Jim Meyering <meyering@ascend.com> + + Remove rcs-style ,file, lock files upon signal. + * rcs.c (rcs_lockfile): New file-scoped global. + (rcs_cleanup): New function (similar to patch_cleanup). + (rcs_internal_lockfile): Register rcs_cleanup the first time this + function is called. Rename uses of local `lockfile' to refer to new + global, `rcs_lockfile'. Don't free the lock file name string, now + that it's global. + (rcs_internal_unlockfile): Rename `lockfile', as above, and carefully + free and NULL-out the global, rcs_lockfile. + +1999-04-30 Jim Kingdon <http://www.cyclic.com> + + * rcs.c (annotate_fileproc): Don't cast NULL in passing it to + RCS_deltas. Because there is a prototype in scope the cast is + unnecessary (per HACKING's ANSI C or SunOS4 rule), and in fact it + was causing failures on UNICOS because it cast to size_t instead + of size_t*. (Thanks to Dean Kopesky for reporting this). + +1999-04-29 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh: If invoked without any arguments, print a usage + message (thanks to Pavel Roskin for a report/patch). + + * run.c (piped_child): Make the error messages more verbose. + (close_on_exec): Reindent. + * sanity.sh (devcom3): Several errors are possible in devcom3-9a. + Adjust for change to piped_child error message. + +1999-04-28 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh (devcom3): Add some tests of the CVS/Notify file and + disconnected "cvs edit". + + * main.c (opt_usage): Remove -b. + +1999-04-20 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + + * rcs.c (RCS_delete_revs): RCS_delete_revs uses an + RCS_checkout call to get a new copy of a revision to be + used internally after old revisions were deleted and it was + performing keyword substitutions. This munged all the + the revisions of the file on the branch containing the + deleted revisions and its sub-branches, as the original they + were being patched from was incorrect. Corrected this by + passing in "-ko" as an option to RCS_checkout. + * sanity.sh (keywordlog): modified this test to verify the + correct behavior of 'cvs admin -o'. + [Fixed use of \$ in keywordlog test; added code in RCS_delete_revs + to abort on binary file on Windows -kingdon] + +1999-04-21 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + and Jim Kingdon + + * tag.c (tag_check_valid): A bug was causing CVS to spin + indefinately when -j:<date> was specified. CVS now returns + an error. + * sanity.sh: Added a test (tagdate-12) to test this. + +1999-04-19 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh (backuprecover): Clean up the repository at the end. + +1999-04-18 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + + * sanity.sh added a test (backuprecover) to test cvs behavior + with a repository that is out of date relative to the + developer's workspaces. + [Fix --keep code; move test to "Repository Storage" section since + it doesn't really exercise the diff/diff3 library. -kingdon] + +1999-04-13 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + + * sanity.sh (diff): Tests to verify correct operation of + the --ifdef parameter to cvs diff. + [indentation fixed -kingdon]. + +1999-04-13 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + for Noah Friedman <friedman@splode.com> + + * diff.c (diff): Put "--ifdef=" in opts string, not "-D"; the + latter is confused by pserver for a date spec. + +1999-04-14 Jim Kingdon <http://www.cyclic.com> + + * fileattr.h: Adjust comments to reflect the official version of + the fileattr format now being in cvs.texinfo. + +1999-04-05 Jim Kingdon + + * sanity.sh (watch5): Remove nonstandard --keep code. Don't pass + -f to rm when cleaning up (that tends to mask bugs). Add watch5 + to list of tests at start. Add comment explaining why we consider + the behavior we test for the right one. Rename a few tests which + had been erroneously named watch6* instead of watch5*. + * client.c (update_entries): Add comment with brief discussion of + whether there is a better way. + +1999-04-05 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + + * client.c (update_entries): Only call mark_up_to_date + (which deletes the CVS/Base/<filename> file for watched + and edited files) on commit. + * sanity.sh: Make sure the CVS/Base/<filename> file for + a watched and edited file is not removed on a status or + update of a touched/unmodfied file. + +1999-03-30 Larry Jones <larry.jones@sdrc.com> + + * client.c (get_responses_and_close), commit.c (commit), + update.c (do_update): If the sleep(1) call returns prematurely + (due to the way wakeup is scheduled or receiving a signal), do + it again. + +1999-03-26 Jim Kingdon <http://www.cyclic.com> + + * server.c (server): Add comment about Gzip-stream vs. RQ_ROOTLESS. + + * sanity.sh (modules3-11b): Adjust exact text of error message to + reflect 1999-03-24 change to dirswitch. + +1999-03-25 Jim Kingdon <http://www.cyclic.com> + + * admin.c (admin): Make argument to -e optional, to match the + documentation. + * sanity.sh (admin-19a-2): Test for this. + + * server.c (serve_root): Update comment about checking for missing + Root request. + +1999-03-24 Jim Kingdon <http://www.cyclic.com> + + * server.c (dirswitch): Also check dir here, similar to + what server_pathname_check does for other cases. + * sanity.sh (files): Adjust files-14 to test for this. + +1999-03-24 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + and Jim Kingdon + + * sanity.sh: added a test (files-13) to test .. indirection + in a path and another (files-14) to make sure we still fail + out when the '..' indirection takes us into the $CVSROOT + directory or beyond. + +1999-03-24 Larry Jones <larry.jones@sdrc.com> + + * rcs.c: Change enum constants ADD and DELETE to something less + likely to run into conflicts. + +1999-03-21 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh (tagf): New test, tests for moving a branch tag to a + non-branch tag and trying to recover. + +1999-03-12 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh (branches): Tweak test branches-5 to test the case in + which one modifies a file and then branches it. + +1999-03-09 John Bley of duke.edu + + * mkmodules.c (filelist): Missed a NULL in this struct (should + have 3 members, only had 2). + +1999-03-07 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh (Index): Rename new test from rm_CVS/Root to rmroot + (we don't have a formal rule about funky punctuation in test names + but both underscore and a slash is too funky for me :-)). + Reindent a few tests which were off. + + * root.c: Remove the sentence which had the improper English; + there isn't really a need for that sentence and it isn't + particularly accurate any more. + +1999-02-27 Derek Price + <http://www-personal.engin.umich.edu/~oberon/resume.html> + + * sanity.sh: Added rm_CVS/Root test to test that CVS uses + $CVSROOT rather than dumping core when running remotely and + the admin file CVS/Root is deleted from the workspace. + + Also, altered a few 'cvs commit' 's in regular expressions to + fit the .${PROG} commit. portability syntax. + + * recurse.c: Stopped CVS from dumping core in the case tested + above. + + * root.c: Fixed somebody's improper english. + +1999-02-25 Larry Jones <larry.jones@sdrc.com> + + * sanity.sh (keyword2-12): Use ${QUESTION} instead of ? in the + expected result. + +1999-02-24 Jim Kingdon <http://www.cyclic.com> + + * sanity.sh (keyword2): Restore the original \\\$ instead of $. + The latter ends up working due to various kludgy semantics in the + shell and regular expressions, but the former is cleaner. + + * sanity.sh (keyword2): Protect keywords against accidental + expansion in sanity.sh itself (most occurrences had this, but not + all). + +1999-02-23 Derek Price <http://www.cyclic.com> + and Jim Kingdon. + + * sanity.sh (keyword2): New test, tests for merging with -kk. + +1999-02-22 Jim Kingdon <http://www.cyclic.com> + + * version.c: Ease version number to 1.10.5.1. + + * version.c: Version 1.10.5. + 1999-02-18 Jim Kingdon <http://www.cyclic.com> * sanity.sh (files): New test, for a relatively obscure spurious diff --git a/gnu/usr.bin/cvs/src/add.c b/gnu/usr.bin/cvs/src/add.c index fa569507ab6..db1f5278f71 100644 --- a/gnu/usr.bin/cvs/src/add.c +++ b/gnu/usr.bin/cvs/src/add.c @@ -172,9 +172,20 @@ add (argc, argv) } for (i = 0; i < argc; ++i) + { /* FIXME: Does this erroneously call Create_Admin in error conditions which are only detected once the server gets its hands on things? */ + /* FIXME-also: if filenames are case-insensitive on the + client, and the directory in the repository already + exists and is named "foo", and the command is "cvs add + FOO", this call to Create_Admin puts the wrong thing in + CVS/Repository and so a subsequent "cvs update" will + give an error. The fix will be to have the server report + back what it actually did (e.g. use tagged text for the + "Directory %s added" message), and then Create_Admin, + which should also fix the error handling concerns. */ + if (isdir (argv[i])) { char *tag; @@ -240,6 +251,7 @@ add (argc, argv) free (repository); free (filedir); } + } send_files (argc, argv, 0, 0, SEND_BUILD_DIRS | SEND_NO_CONTENTS); send_file_names (argc, argv, SEND_EXPAND_WILD); send_to_server ("add\012", 0); @@ -258,6 +270,9 @@ add (argc, argv) #endif struct file_info finfo; char *p; +#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE) + char *found_name; +#endif memset (&finfo, 0, sizeof finfo); @@ -294,6 +309,60 @@ add (argc, argv) finfo.repository = repository; finfo.entries = entries; +#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE) + if (ign_case) + { + /* Need to check whether there is a directory with the + same name but different case. We'll check for files + with the same name later (when Version_TS calls + RCS_parse which calls fopen_case). If CVS some day + records directories in the RCS files, then we should be + able to skip the separate check here, which would be + cleaner. */ + DIR *dirp; + struct dirent *dp; + + dirp = CVS_OPENDIR (finfo.repository); + if (dirp == NULL) + error (1, errno, "cannot read directory %s", finfo.repository); + found_name = NULL; + errno = 0; + while ((dp = readdir (dirp)) != NULL) + { + if (cvs_casecmp (dp->d_name, finfo.file) == 0) + { + if (found_name != NULL) + error (1, 0, "%s is ambiguous; could mean %s or %s", + finfo.file, dp->d_name, found_name); + found_name = xstrdup (dp->d_name); + } + } + if (errno != 0) + error (1, errno, "cannot read directory %s", finfo.repository); + closedir (dirp); + + if (found_name != NULL) + { + /* OK, we are about to patch up the name, so patch up + the temporary directory too to match. The isdir + should "always" be true (since files have ,v), but + I guess we might as well make some attempt to not + get confused by stray files in the repository. */ + if (isdir (finfo.file)) + { + if (CVS_MKDIR (found_name, 0777) < 0 + && errno != EEXIST) + error (0, errno, "cannot create %s", finfo.file); + } + + /* OK, we found a directory with the same name, maybe in + a different case. Treat it as if the name were the + same. */ + finfo.file = found_name; + } + } +#endif + /* We pass force_tag_match as 1. If the directory has a sticky branch tag, and there is already an RCS file which does not have that tag, then the head revision is @@ -538,6 +607,10 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname); free_cwd (&cwd); free (finfo.fullname); +#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE) + if (ign_case && found_name != NULL) + free (found_name); +#endif } if (added_files) error (0, 0, "use '%s commit' to add %s permanently", diff --git a/gnu/usr.bin/cvs/src/admin.c b/gnu/usr.bin/cvs/src/admin.c index 3e5f61d1146..c5af96e2d5c 100644 --- a/gnu/usr.bin/cvs/src/admin.c +++ b/gnu/usr.bin/cvs/src/admin.c @@ -120,35 +120,11 @@ admin (argc, argv) struct admin_data admin_data; int c; int i; + int only_k_option; if (argc <= 1) usage (admin_usage); -#ifdef CVS_ADMIN_GROUP - grp = getgrnam(CVS_ADMIN_GROUP); - /* skip usage right check if group CVS_ADMIN_GROUP does not exist */ - if (grp != NULL) - { - char *me = getcaller(); - char **grnam = grp->gr_mem; - int denied = 1; - - while (*grnam) - { - if (strcmp(*grnam, me) == 0) - { - denied = 0; - break; - } - grnam++; - } - - if (denied) - error (1, 0, "usage is restricted to members of the group %s", - CVS_ADMIN_GROUP); - } -#endif - wrap_setup (); memset (&admin_data, 0, sizeof admin_data); @@ -157,9 +133,13 @@ admin (argc, argv) example, admin_data->branch should be not `-bfoo' but simply `foo'. */ optind = 0; + only_k_option = 1; while ((c = getopt (argc, argv, - "+ib::c:a:A:e:l::u::LUn:N:m:o:s:t::IqxV:k:")) != -1) + "+ib::c:a:A:e::l::u::LUn:N:m:o:s:t::IqxV:k:")) != -1) { + if (c != 'k') + only_k_option = 0; + switch (c) { case 'i': @@ -211,6 +191,11 @@ admin (argc, argv) break; case 'e': + if (optarg == NULL) + { + error (1, 0, + "removing entire access list not yet implemented"); + } arg_add (&admin_data, 'e', optarg); break; @@ -353,6 +338,33 @@ admin (argc, argv) argc -= optind; 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) + { + 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; + + while (*grnam) + { + if (strcmp(*grnam, me) == 0) + { + denied = 0; + break; + } + grnam++; + } + + if (denied) + error (1, 0, "usage is restricted to members of the group %s", + CVS_ADMIN_GROUP); + } +#endif + for (i = 0; i < admin_data.ac; ++i) { assert (admin_data.av[i][0] == '-'); diff --git a/gnu/usr.bin/cvs/src/client.c b/gnu/usr.bin/cvs/src/client.c index 02c31e223ae..748132a9310 100644 --- a/gnu/usr.bin/cvs/src/client.c +++ b/gnu/usr.bin/cvs/src/client.c @@ -1690,8 +1690,8 @@ update_entries (data_arg, ent_list, short_pathname, filename) free (size_string); /* Note that checking this separately from writing the file is - a race condition: if the existing or lack thereof of the - file changes between now and the actually calls which + a race condition: if the existence or lack thereof of the + file changes between now and the actual calls which operate on it, we lose. However (a) there are so many cases, I'm reluctant to try to fix them all, (b) in some cases the system might not even have a system call which @@ -1882,87 +1882,14 @@ update_entries (data_arg, ent_list, short_pathname, filename) } else if (data->contents == UPDATE_ENTRIES_PATCH) { -#ifdef DONT_USE_PATCH - /* Hmm. We support only Rcs-diff, and the server supports - only Patched (or else it would have sent Rcs-diff instead). + /* You might think we could just leave Patched out of + Valid-responses and not get this response. However, if + memory serves, the CVS 1.9 server bases this on -u + (update-patches), and there is no way for us to send -u + or not based on whether the server supports "Rcs-diff". + Fall back to transmitting entire files. */ patch_failed = 1; -#else /* Use patch. */ - int retcode; - char *backup; - struct stat s; - - backup = xmalloc (strlen (filename) + 5); - strcpy (backup, filename); - strcat (backup, "~"); - if (unlink_file (backup) < 0 - && !existence_error (errno)) - { - error (0, errno, "cannot remove %s", backup); - } - if (!isfile (filename)) - error (1, 0, "patch original file %s does not exist", - short_pathname); - if ( CVS_STAT (temp_filename, &s) < 0) - error (1, errno, "can't stat patch file %s", temp_filename); - if (s.st_size == 0) - retcode = 0; - else - { - /* This behavior (in which -b takes an argument) is - supported by GNU patch 2.1. Apparently POSIX.2 - specifies a -b option without an argument. GNU - patch 2.1.5 implements this and therefore won't - work here. GNU patch versions after 2.1.5 are said - to have a kludge which checks if the last 4 args - are `-b SUFFIX ORIGFILE PATCHFILE' and if so emit a - warning (I think -s suppresses it), and then behave - as CVS expects. - - Of course this is yet one more reason why in the long - run we want Rcs-diff to replace Patched. */ - - run_setup (PATCH_PROGRAM); - run_arg ("-f"); - run_arg ("-s"); - run_arg ("-b"); - run_arg ("~"); - run_arg (filename); - run_arg (temp_filename); - retcode = run_exec (DEVNULL, RUN_TTY, RUN_TTY, RUN_NORMAL); - } - if (unlink_file (temp_filename) < 0) - error (0, errno, "cannot remove %s", temp_filename); - if (retcode == 0) - { - if (unlink_file (backup) < 0) - error (0, errno, "cannot remove %s", backup); - } - else - { - int old_errno = errno; - char *path_tmp; - - if (isfile (backup)) - rename_file (backup, filename); - - /* Get rid of the patch reject file. */ - path_tmp = xmalloc (strlen (filename) + 10); - strcpy (path_tmp, filename); - strcat (path_tmp, ".rej"); - if (unlink_file (path_tmp) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", path_tmp); - free (path_tmp); - - error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0, - "could not patch %s%s", filename, - retcode == -1 ? "" : "; will refetch"); - - patch_failed = 1; - } - free (backup); -#endif /* Use patch. */ } else { @@ -2177,7 +2104,17 @@ update_entries (data_arg, ent_list, short_pathname, filename) else if (local_timestamp == NULL) { local_timestamp = file_timestamp; - mark_up_to_date (filename); + + /* Checking for command_name of "commit" doesn't seem like + the cleanest way to handle this, but it seem to roughly + parallel what the :local: code which calls + mark_up_to_date ends up amounting to. Some day, should + think more about what the Checked-in response means + vis-a-vis both Entries and Base and clarify + cvsclient.texi accordingly. */ + + if (!strcmp (command_name, "commit")) + mark_up_to_date (filename); } Register (ent_list, filename, vn, local_timestamp, @@ -3664,9 +3601,12 @@ get_responses_and_close () { time_t now; - (void) time (&now); - if (now == last_register_time) + for (;;) + { + (void) time (&now); + if (now != last_register_time) break; sleep (1); /* to avoid time-stamp races */ + } } return errs; diff --git a/gnu/usr.bin/cvs/src/diff.c b/gnu/usr.bin/cvs/src/diff.c index aa35885af30..e98938d9b55 100644 --- a/gnu/usr.bin/cvs/src/diff.c +++ b/gnu/usr.bin/cvs/src/diff.c @@ -277,7 +277,7 @@ diff (argc, argv) break; case 131: /* --ifdef. */ - strcat_and_allocate (&opts, &opts_allocated, " -D"); + strcat_and_allocate (&opts, &opts_allocated, " --ifdef="); strcat_and_allocate (&opts, &opts_allocated, optarg); break; case 129: case 130: case 132: case 133: case 134: diff --git a/gnu/usr.bin/cvs/src/edit.c b/gnu/usr.bin/cvs/src/edit.c index 9d9a588cd2a..59d363cce04 100644 --- a/gnu/usr.bin/cvs/src/edit.c +++ b/gnu/usr.bin/cvs/src/edit.c @@ -722,6 +722,9 @@ notify_proc (repository, filter) return (pclose (pipefp)); } +/* FIXME: this function should have a way to report whether there was + an error so that server.c can know whether to report Notified back + to the client. */ void notify_do (type, filename, who, val, watches, repository) int type; @@ -743,6 +746,11 @@ notify_do (type, filename, who, val, watches, repository) switch (type) { case 'E': + if (strpbrk (val, ",>;=\n") != NULL) + { + error (0, 0, "invalid character in editor value"); + return; + } editor_set (filename, who, val); break; case 'U': @@ -864,7 +872,14 @@ notify_do (type, filename, who, val, watches, repository) { char *cp; args.notifyee = xstrdup (line + len + 1); - cp = strchr (args.notifyee, ':'); + + /* There may or may not be more + colon-separated fields added to this in the + future; in any case, we ignore them right + now, and if there are none we make sure to + chop off the final newline, if any. */ + cp = strpbrk (args.notifyee, ":\n"); + if (cp != NULL) *cp = '\0'; break; diff --git a/gnu/usr.bin/cvs/src/fileattr.h b/gnu/usr.bin/cvs/src/fileattr.h index 7e02b3a3cdb..046b97547ed 100644 --- a/gnu/usr.bin/cvs/src/fileattr.h +++ b/gnu/usr.bin/cvs/src/fileattr.h @@ -12,28 +12,24 @@ #ifndef FILEATTR_H -/* File containing per-file attributes. Format is a series of entries: +/* File containing per-file attributes. The format of this file is in + cvs.texinfo but here is a quick summary. The file contains a + series of entries: ENT-TYPE FILENAME <tab> ATTRNAME = ATTRVAL {; ATTRNAME = ATTRVAL} <linefeed> - ENT-TYPE is 'F' for a file, in which case the entry specifies the - attributes for that file. + ENT-TYPE is 'F' for a file. - ENT-TYPE is 'D', and FILENAME empty, to specify default attributes - to be used for newly added files. + ENT-TYPE is 'D', and FILENAME empty, for default attributes. - Other ENT-TYPE are reserved for future expansion. CVS 1.9 and older - will delete them any time it writes file attributes. Current versions - of CVS will preserve them. + Other ENT-TYPE are reserved for future expansion. Note that the order of the line is not significant; CVS is free to rearrange them at its convenience. - There is currently no way of quoting tabs or linefeeds in the - filename, '=' in ATTRNAME, ';' in ATTRVAL, etc. I'm not sure - whether I think we need one. Note: the current implementation also - doesn't handle '\0' in any of the fields. + FIXME: this implementation doesn't handle '\0' in any of the + fields. We are encouraged to fix this (by cvs.texinfo). By convention, ATTRNAME starting with '_' is for an attribute given special meaning by CVS; other ATTRNAMEs are for user-defined attributes diff --git a/gnu/usr.bin/cvs/src/log.c b/gnu/usr.bin/cvs/src/log.c index 7c57c77ced6..398d6500de6 100644 --- a/gnu/usr.bin/cvs/src/log.c +++ b/gnu/usr.bin/cvs/src/log.c @@ -7,9 +7,6 @@ * * Print Log Information * - * This line exists solely to test some pcl-cvs/ChangeLog stuff. You - * can delete it, if indeed it's still here when you read it. -Karl - * * Prints the RCS "log" (rlog) information for the specified files. With no * argument, prints the log information for all the files in the directory * (recursive by default). diff --git a/gnu/usr.bin/cvs/src/modules.c b/gnu/usr.bin/cvs/src/modules.c index e322086591e..9907cc85e4f 100644 --- a/gnu/usr.bin/cvs/src/modules.c +++ b/gnu/usr.bin/cvs/src/modules.c @@ -20,6 +20,7 @@ * command line. */ +#include <assert.h> #include "cvs.h" #include "savecwd.h" @@ -120,7 +121,8 @@ do_module (db, mname, m_type, msg, callback_proc, where, int xmodargc; char **modargv; char **xmodargv; - char *value; + /* Found entry from modules file, including options and such. */ + char *value = NULL; char *zvalue = NULL; char *mwhere = NULL; char *mfile = NULL; @@ -231,7 +233,9 @@ do_module (db, mname, m_type, msg, callback_proc, where, if (isdir (file)) { - value = mname; + modargv = xmalloc (sizeof (*modargv)); + modargv[0] = xstrdup (mname); + modargc = 1; is_found = 1; } else @@ -242,14 +246,12 @@ do_module (db, mname, m_type, msg, callback_proc, where, /* if mname was a file, we have to split it into "dir file" */ if ((cp = strrchr (mname, '/')) != NULL && cp != mname) { - char *slashp; - - /* put the ' ' in a copy so we don't mess up the - original */ - xvalue = xmalloc (strlen (mname) + 2); - value = strcpy (xvalue, mname); - slashp = strrchr (value, '/'); - *slashp = ' '; + modargv = xmalloc (2 * sizeof (*modargv)); + modargv[0] = xmalloc (strlen (mname) + 2); + strncpy (modargv[0], mname, cp - mname); + modargv[0][cp - mname] = '\0'; + modargv[1] = xstrdup (cp + 1); + modargc = 2; } else { @@ -261,31 +263,54 @@ do_module (db, mname, m_type, msg, callback_proc, where, if (cp == mname) { /* drop the leading / if specified */ - xvalue = xmalloc (strlen (mname) + 10); - value = strcpy (xvalue, ". "); - (void) strcat (xvalue, mname + 1); + modargv = xmalloc (2 * sizeof (*modargv)); + modargv[0] = xstrdup ("."); + modargv[1] = xstrdup (mname + 1); + modargc = 2; } else { /* otherwise just copy it */ - xvalue = xmalloc (strlen (mname) + 10); - value = strcpy (xvalue, ". "); - (void) strcat (xvalue, mname); + modargv = xmalloc (2 * sizeof (*modargv)); + modargv[0] = xstrdup ("."); + modargv[1] = xstrdup (mname); + modargc = 2; } } is_found = 1; } - else - { - /* This initialization suppresses a warning from gcc -Wall. */ - value = NULL; - } } free (attic_file); free (file); if (is_found) - goto found; + { + assert (value == NULL); + + /* OK, we have now set up modargv with the actual + file/directory we want to work on. We duplicate a + small amount of code here because the vast majority of + the code after the "found" label does not pertain to + the case where we found a file/directory rather than + finding an entry in the modules file. */ + if (save_cwd (&cwd)) + error_exit (); + cwd_saved = 1; + + err += callback_proc (&modargc, modargv, where, mwhere, mfile, + shorten, + local_specified, mname, msg); + + free_names (&modargc, modargv); + + /* cd back to where we started. */ + if (restore_cwd (&cwd, NULL)) + error_exit (); + free_cwd (&cwd); + cwd_saved = 0; + + goto do_module_return; + } } /* look up everything to the first / as a module */ @@ -352,6 +377,7 @@ do_module (db, mname, m_type, msg, callback_proc, where, /* copy value to our own string since if we go recursive we'll be really screwed if we do another dbm lookup */ + assert (value != NULL); zvalue = xstrdup (value); value = zvalue; diff --git a/gnu/usr.bin/cvs/src/root.c b/gnu/usr.bin/cvs/src/root.c index c650646ecff..d88c6f4b55a 100644 --- a/gnu/usr.bin/cvs/src/root.c +++ b/gnu/usr.bin/cvs/src/root.c @@ -7,8 +7,6 @@ * Name of Root * * Determine the path to the CVSROOT and set "Root" accordingly. - * If this looks like of modified clone of Name_Repository() in - * repos.c, it is... */ #include "cvs.h" diff --git a/gnu/usr.bin/cvs/src/run.c b/gnu/usr.bin/cvs/src/run.c index 6d2c3b1cec6..41f445756d6 100644 --- a/gnu/usr.bin/cvs/src/run.c +++ b/gnu/usr.bin/cvs/src/run.c @@ -406,21 +406,21 @@ piped_child (command, tofdp, fromfdp) if (pid == 0) { if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0) - error (1, errno, "cannot dup2"); + error (1, errno, "cannot dup2 pipe"); if (close (to_child_pipe[1]) < 0) - error (1, errno, "cannot close"); + error (1, errno, "cannot close pipe"); if (close (from_child_pipe[0]) < 0) - error (1, errno, "cannot close"); + error (1, errno, "cannot close pipe"); if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0) - error (1, errno, "cannot dup2"); + error (1, errno, "cannot dup2 pipe"); execvp (command[0], command); - error (1, errno, "cannot exec"); + error (1, errno, "cannot exec %s", command[0]); } if (close (to_child_pipe[0]) < 0) - error (1, errno, "cannot close"); + error (1, errno, "cannot close pipe"); if (close (from_child_pipe[1]) < 0) - error (1, errno, "cannot close"); + error (1, errno, "cannot close pipe"); *tofdp = to_child_pipe[1]; *fromfdp = from_child_pipe[0]; @@ -433,7 +433,7 @@ close_on_exec (fd) int fd; { #if defined (FD_CLOEXEC) && defined (F_SETFD) - if (fcntl (fd, F_SETFD, 1)) - error (1, errno, "can't set close-on-exec flag on %d", fd); + if (fcntl (fd, F_SETFD, 1)) + error (1, errno, "can't set close-on-exec flag on %d", fd); #endif } diff --git a/gnu/usr.bin/cvs/src/sanity.sh b/gnu/usr.bin/cvs/src/sanity.sh index 690398441ea..6130289c42d 100644 --- a/gnu/usr.bin/cvs/src/sanity.sh +++ b/gnu/usr.bin/cvs/src/sanity.sh @@ -97,12 +97,16 @@ fi # 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 + ;; /*) - testcvs=$1 - ;; + testcvs=$1 + ;; *) - testcvs=`pwd`/$1 - ;; + testcvs=`pwd`/$1 + ;; esac shift @@ -281,13 +285,18 @@ dotest_internal () # so special-case it. if test -z "$3"; then if test -s ${TESTDIR}/dotest.tmp; then - 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" + 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 @@ -557,10 +566,11 @@ RCSINIT=; export RCSINIT if test x"$*" = x; then # Basic/miscellaneous functionality - tests="basica basicb basicc basic1 deep basic2 files commit-readonly" + tests="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" + tests="${tests} branches branches2 tagc tagf" tests="${tests} rcslib multibranch import importb importc" tests="${tests} import-after-initial" tests="${tests} join join2 join3 join-readonly-conflict" @@ -572,7 +582,7 @@ if test x"$*" = x; then # Log messages, error messages. tests="${tests} mflag editor errmsg1 errmsg2" # Watches, binary files, history browsing, &c. - tests="${tests} devcom devcom2 devcom3 watch4" + tests="${tests} devcom devcom2 devcom3 watch4 watch5" tests="${tests} unedit-without-baserev" tests="${tests} ignore binfiles binfiles2 binfiles3" tests="${tests} mcopy binwrap binwrap2" @@ -580,14 +590,14 @@ if test x"$*" = x; then tests="${tests} serverpatch log log2 ann ann-id" # Repository Storage (RCS file format, CVS lock files, creating # a repository without "cvs init", &c). - tests="${tests} crerepos rcs rcs2 rcs3 lockfiles" + tests="${tests} crerepos rcs rcs2 rcs3 lockfiles backuprecover" # More history browsing, &c. tests="${tests} history" tests="${tests} big modes modes2 modes3 stamps" # PreservePermissions stuff: permissions, symlinks et al. - tests="${tests} perms symlinks hardlinks" + tests="${tests} perms symlinks symlinks2 hardlinks" # More tag and branch tests, keywords. - tests="${tests} sticky keyword keywordlog" + tests="${tests} sticky keyword keyword2 keywordlog" tests="${tests} head tagdate multibranch2 tag8k" # "cvs admin", reserved checkouts. tests="${tests} admin reserved" @@ -597,7 +607,7 @@ if test x"$*" = x; then tests="${tests} release" # Multiple root directories and low-level protocol tests. tests="${tests} multiroot multiroot2 multiroot3 multiroot4" - tests="${tests} reposmv pserver server client" + tests="${tests} rmroot reposmv pserver server server2 client" else tests="$*" fi @@ -1174,13 +1184,24 @@ ${PROG} [a-z]*: Updating second-dir" cd first-dir dotest basicc-6 "${testcvs} release -d" "" dotest basicc-7 "test -d ../first-dir" "" + # The Linux 2.2 kernel lets you delete ".". That's OK either way, + # the point is that CVS must not mess with anything *outside* "." + # the way that CVS 1.10 and older tried to. dotest basicc-8 "${testcvs} -Q release -d ." \ -"${PROG} release: deletion of directory \. failed: .*" +"" "${PROG} release: deletion of directory \. failed: .*" dotest basicc-9 "test -d ../second-dir" "" - dotest basicc-10 "test -d ../first-dir" "" # For CVS to make a syntactic check for "." wouldn't suffice. + # On Linux 2.2 systems, the cwd may be gone, so we recreate it + # to allow basicc-11 to actually happen + if ! test -d ../first-dir; then + cd .. + mkdir ./first-dir + cd ./first-dir + fi dotest basicc-11 "${testcvs} -Q release -d ./." \ -"${PROG} release: deletion of directory \./\. failed: .*" +"" "${PROG} release: deletion of directory \./\. failed: .*" + dotest basicc-11a "test -d ../second-dir" "" + cd .. cd .. @@ -2173,6 +2194,20 @@ done" "${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \ "${PROG} server: Up-to-date check failed for .\.file' ${PROG} \[server aborted\]: correct above errors first!" + + # Sync up the version numbers so that the rest of the + # tests don't need to expect different numbers based + # local or remote. + dotest files-12-workaround \ +"${testcvs} commit -f -m test sdir/ssdir/.file .file" \ +"Checking in sdir/ssdir/\.file; +${TESTDIR}/cvsroot/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 +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" \ @@ -2185,10 +2220,130 @@ ${TESTDIR}/cvsroot/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 +new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3 +done" + if test "$remote" = yes; then + dotest_fail files-14 \ +"${testcvs} commit -fmtest ../../first-dir/dir/.file" \ +"protocol error: .\.\./\.\./first-dir/dir' has too many \.\." + else + 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 +new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3 +done" + fi cd ../../.. rm -r 1 - rm -rf ${CVSROOT_DIRECTORY}/first-dir + rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + + spacefiles) + # More filename tests, in particular spaces in file names. + # If we start using eval in dotest, this test should become + # easier to write (in fact, it may be possible to just + # change a few of the names in basica or some other test, + # always good to keep the testsuite concise). + + # I wrote this test to worry about problems in do_module; + # but then I found that the CVS server has its own problems + # with filenames starting with "-". Work around it for now. + if test "$remote" = yes; then + dashb=dashb + dashc=dashc + else + dashb=-b + dashc=-c + fi + + mkdir 1; cd 1 + dotest spacefiles-1 "${testcvs} -q co -l ." "" + touch ./${dashc} top + dotest spacefiles-2 "${testcvs} add -- ${dashc} top" \ +"${PROG} [a-z]*: scheduling file .${dashc}. for addition +${PROG} [a-z]*: scheduling file .top. for addition +${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" + dotest spacefiles-3 "${testcvs} -q ci -m add" \ +"RCS file: ${TESTDIR}/cvsroot/${dashc},v +done +Checking in ${dashc}; +${TESTDIR}/cvsroot/${dashc},v <-- ${dashc} +initial revision: 1\.1 +done +RCS file: ${TESTDIR}/cvsroot/top,v +done +Checking in top; +${TESTDIR}/cvsroot/top,v <-- top +initial revision: 1\.1 +done" + mkdir 'first dir' + if ${testcvs} add 'first dir' >${TESTDIR}/output.tmp 2>&1; then + dotest spacefiles-4 "cat ${TESTDIR}/output.tmp" \ +"Directory ${TESTDIR}/cvsroot/first dir added to the repository" + else + fail spacefiles-4 + fi + mkdir ./${dashb} + dotest spacefiles-5 "${testcvs} add -- ${dashb}" \ +"Directory ${TESTDIR}/cvsroot/${dashb} added to the repository" + cd 'first dir' + touch 'a file' + if ${testcvs} add 'a file' >${TESTDIR}/output.tmp 2>&1; then + dotest spacefiles-6 "cat ${TESTDIR}/output.tmp" \ +"${PROG} [a-z]*: scheduling file .a file. for addition +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" + else + fail spacefiles-6 + fi + dotest spacefiles-7 "${testcvs} -q ci -m add" \ +"RCS file: ${TESTDIR}/cvsroot/first dir/a file,v +done +Checking in a file; +${TESTDIR}/cvsroot/first dir/a file,v <-- a file +initial revision: 1\.1 +done" + dotest spacefiles-8 "${testcvs} -q tag new-tag" "T a file" + cd ../.. + + mkdir 2; cd 2 + # Leading slash strikes me as kind of oddball, but there is + # a special case for it in do_module. And (in the case of + # "top", rather than "-c") it has worked in CVS 1.10.6 and + # presumably back to CVS 1.3 or so. + dotest spacefiles-9 "${testcvs} -q co -- /top" "U \./top" + dotest spacefiles-10 "${testcvs} co -- ${dashb}" \ +"${PROG} [a-z]*: Updating ${dashb}" + dotest spacefiles-11 "${testcvs} -q co -- ${dashc}" "U \./${dashc}" + rm ./${dashc} + dotest spacefiles-12 "${testcvs} -q co -- /${dashc}" "U \./${dashc}" + if ${testcvs} -q co 'first dir' >${TESTDIR}/output.tmp 2>&1; then + dotest spacefiles-13 "cat ${TESTDIR}/output.tmp" \ +"U first dir/a file" + else + fail spacefiles-13 + fi + cd .. + + mkdir 3; cd 3 + if ${testcvs} -q co 'first dir/a file' >${TESTDIR}/output.tmp 2>&1 + then + dotest spacefiles-14 "cat ${TESTDIR}/output.tmp" \ +"U first dir/a file" + else + fail spacefiles-14 + fi + cd .. + + rm -r 1 2 3 + rm -rf "${CVSROOT_DIRNAME}/first dir" + rm -r ${CVSROOT_DIRNAME}/${dashb} + rm -f ${CVSROOT_DIRNAME}/${dashc},v ${CVSROOT_DIRNAME}/top,v ;; commit-readonly) @@ -2357,6 +2512,41 @@ diff -c /dev/null trdiff/new:1\.1 # diff says "I know nothing". Shrug. dotest_fail diff-3 "${testcvs} diff xyzpdq" \ "${PROG} [a-z]*: I know nothing about xyzpdq" + touch abc + dotest diff-4 "${testcvs} add abc" \ +"${PROG} [a-z]*: scheduling file .abc. for addition +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" + dotest diff-5 "${testcvs} -q ci -mtest" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/abc,v +done +Checking in abc; +${TESTDIR}/cvsroot/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 +new revision: 1\.2; previous revision: 1\.1 +done" + echo "#include <winsock.h>" >abc + # check the behavior of the --ifdef=MACRO option + dotest_fail diff-7 "${testcvs} -q diff --ifdef=HAVE_WINSOCK_H" \ +"Index: abc +=================================================================== +RCS file: ${TESTDIR}/cvsroot/first-dir/abc,v +retrieving revision 1\.2 +diff --ifdef=HAVE_WINSOCK_H -r1\.2 abc +#ifndef HAVE_WINSOCK_H +extern int gethostname (); +#else /\* HAVE_WINSOCK_H \*/ +#include <winsock\.h> +#endif /\* HAVE_WINSOCK_H \*/" + + if test "$keep" = yes; then + echo Keeping ${TESTDIR} and exiting due to --keep + exit 0 + fi cd ../.. rm -rf ${CVSROOT_DIRNAME}/first-dir @@ -3264,6 +3454,7 @@ Checking in file1; ${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 initial revision: 1\.1 done" + dotest rmadd2-4a "${testcvs} -Q tag tagone" "" dotest rmadd2-5 "${testcvs} rm -f file1" \ "${PROG} [a-z]*: scheduling .file1. for removal ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" @@ -3306,6 +3497,28 @@ done" ${TESTDIR}/cvsroot/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 +Working file: file1 +head: 1\.6 +branch: +locks: strict +access list: +symbolic names: + tagone: 1\.1 +keyword substitution: kv +total revisions: 6 +=============================================================================" + dotest rmadd2-17 "${testcvs} status -v file1" \ +"=================================================================== +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 + + Existing Tags: + tagone (revision: 1.1)" + cd ../.. rm -r 1 @@ -3485,7 +3698,7 @@ ${PROG} update: cannot open CVS/Tag: No such file or directory" else dotest_fail dirs2-10 "${testcvs} update -d -r br" \ "${PROG} update: in directory sdir: -${PROG} \[update aborted\]: there is no version here; do 'cvs checkout' first" +${PROG} \[update aborted\]: there is no version here; do '${PROG} checkout' first" fi cd ../.. @@ -3585,14 +3798,18 @@ done" T file2 T file3 T file4" + # Modify this file before branching, to deal with the case where + # someone is hacking along, says "oops, I should be doing this on + # a branch", and only then creates the branch. + echo 1:br1 >file1 dotest branches-4 "${testcvs} tag -b br1" "${PROG}"' [a-z]*: Tagging \. T file1 T file2 T file3 T file4' dotest branches-5 "${testcvs} update -r br1" \ -"${PROG}"' [a-z]*: Updating \.' - echo 1:br1 >file1 +"${PROG} [a-z]*: Updating \. +M file1" echo 2:br1 >file2 echo 4:br1 >file4 dotest branches-6 "${testcvs} -q ci -m modify" \ @@ -4077,6 +4294,120 @@ ${PROG} \[[a-z]* aborted\]: correct the above errors first!" rm -rf ${CVSROOT_DIRNAME}/first-dir ;; + tagf) + # More tagging tests, including using tag -F to convert a + # branch tag to a regular tag and recovering thereof. + + # Setup; check in first-dir/file1 + mkdir 1; cd 1 + 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" + cd first-dir + touch file1 file2 + dotest tagf-3 "${testcvs} add file1 file2" \ +"${PROG} [a-z]*: scheduling file .file1. for addition +${PROG} [a-z]*: scheduling file .file2. for addition +${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" + dotest tagf-4 "${testcvs} -q ci -m add" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +done +Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done +RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +done +Checking in file2; +${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +initial revision: 1\.1 +done" + + # Now create a branch and commit a revision there. + dotest tagf-5 "${testcvs} -q tag -b br" "T file1 +T file2" + dotest tagf-6 "${testcvs} -q update -r br" "" + echo brmod >> file1 + echo brmod >> file2 + dotest tagf-7 "${testcvs} -q ci -m modify" \ +"Checking in file1; +${TESTDIR}/cvsroot/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 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done" + # Here we make it a non-branch tag. Some think this should + # be an error. But if -F means "I want to put this tag here, + # never mind whether there was a tag of that name before", then + # an error wouldn't fit. + dotest tagf-8 "${testcvs} -q tag -F br" "T file1 +T file2" + echo moremod >> file1 + echo moremod >> file2 + dotest tagf-9 "${testcvs} -q status -v file1" \ +"=================================================================== +File: file1 Status: Locally Modified + + Working revision: 1\.1\.2\.1.* + Repository revision: 1\.1\.2\.1 ${TESTDIR}/cvsroot/first-dir/file1,v + Sticky Tag: br (revision: 1\.1\.2\.1) + Sticky Date: (none) + Sticky Options: (none) + + Existing Tags: + br (revision: 1\.1\.2\.1)" + + # Now, how do we recover? + dotest tagf-10 "${testcvs} -q tag -d br" "D file1 +D file2" + # This creates a new branch, 1.1.4. See the code in RCS_magicrev + # which will notice that there is a (non-magic) 1.1.2 and thus + # skip that number. + 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 +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 +retrieving revision 1\.1\.2\.1 +retrieving revision 1\.1 +Merging differences between 1\.1\.2\.1 and 1\.1 into file1 +rcsmerge: warning: conflicts during merge +${PROG} [a-z]*: conflicts found in file1 +C file1 +M file2" + # CVS is giving a conflict because we are trying to get back to + # 1.1.4. I'm not sure why it is a conflict rather than just + # "M file1". + dotest tagf-14 "cat file1" \ +"<<<<<<< file1 +brmod +moremod +[=]====== +[>]>>>>>> 1\.1" + echo resolve >file1 + dotest tagf-15 "${testcvs} -q ci -m recovered" \ +"Checking in file1; +${TESTDIR}/cvsroot/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 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 +done" + cd ../.. + + rm -r 1 + rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + rcslib) # Test librarification of RCS. # First: test whether `cvs diff' handles $Name expansion @@ -4814,7 +5145,7 @@ ${PROG} [a-z]*: Updating bdir/subdir" # 1.9 did not). dotest_fail importc-7 "${testcvs} -q ci -m modify -r wip_test" \ "${PROG} [a-z]*: in directory adir/sub1/ssdir: -${PROG} \[[a-z]* aborted\]: there is no version here; do .cvs checkout. first" +${PROG} \[[a-z]* aborted\]: there is no version here; do .${PROG} checkout. first" # The workaround is to leave off the "-r wip_test". dotest importc-8 "${testcvs} -q ci -m modify" \ "Checking in cdir/cfile; @@ -4888,7 +5219,17 @@ import-it =============================================================================" cd .. + # Now tests of absolute pathnames and .. as repository directory. + cd ../1 + dotest_fail importc-10 \ +"${testcvs} import -m imp ../other vendor release2" \ +"${PROG} \[[a-z]* aborted\]: directory \.\./other not relative within the repository" + dotest_fail importc-11 \ +"${testcvs} import -m imp ${TESTDIR}/other vendor release3" \ +"${PROG} \[[a-z]* aborted\]: directory ${TESTDIR}/other not relative within the repository" + dotest_fail importc-12 "test -d ${TESTDIR}/other" "" cd .. + rm -r 1 2 rm -rf ${CVSROOT_DIRNAME}/first-dir ;; @@ -6132,7 +6473,7 @@ ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently" # 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 'cvs checkout' first" +${PROG} \[add aborted\]: there is no version here; do '${PROG} checkout' first" cd first-dir fi @@ -7137,7 +7478,7 @@ done" if test "x$remote" = xyes; then dotest_fail modules3-11b \ "${testcvs} -q update ${TESTDIR}/1/src/sub1/sub2/sub3/dir/file1" \ -"${PROG} .server aborted.: absolute pathname .${TESTDIR}/1/src/sub1/sub2/sub3/dir/file1. illegal for server" +"absolute pathname .${TESTDIR}/1/src/sub1/sub2/sub3/dir. illegal for server" fi # end of remote-only tests cd .. @@ -9729,6 +10070,10 @@ Checking in first-dir/sdir10/ssdir/ssfile; ${TESTDIR}/cvsroot/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" cd .. rm -r 1 @@ -10078,6 +10423,31 @@ Fw1 _watched= Enew line here G@#..!@#=&" + # Now test disconnected "cvs edit" and the format of the + # CVS/Notify file. + if test "$remote" = yes; then + CVS_SERVER_SAVED=${CVS_SERVER} + CVS_SERVER=${TESTDIR}/cvs-none; export CVS_SERVER + + # The ${DOTSTAR} matches the exact exec error message + # (which varies) and either "end of file from server" + # (if the process doing the exec exits before the parent + # gets around to sending data to it) or "broken pipe" (if it + # is the other way around). + dotest_fail devcom3-9a "${testcvs} edit w1" \ +"${PROG} \[edit aborted\]: cannot exec ${TESTDIR}/cvs-none: ${DOTSTAR}" + dotest devcom3-9b "test -w w1" "" + dotest devcom3-9c "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" \ +"w1 ${username} tedit tunedit tcommit" + dotest devcom3-9g "${testcvs} unedit w1" "" + dotest devcom3-9h "${testcvs} watchers w1" "" + fi + cd ../.. # OK, now change the tab to a space, and see that CVS gives # a reasonable error (this is database corruption but CVS should @@ -10187,6 +10557,71 @@ C file1" rm -rf ${CVSROOT_DIRNAME}/first-dir ;; + watch5) + # This test was designed to catch a problem in server + # mode where an 'cvs edit'd file disappeared from the + # CVS/Base directory when 'cvs status' or 'cvs update' + # was called on the file after the file was touched. + # + # This test is still here to prevent the bug from + # being reintroduced. + # + # The rationale for having CVS/Base stay around is that + # CVS/Base should be there if "cvs edit" has been run (this + # may be helpful as a "cvs editors" analogue, it is + # client-side and based on working directory not username; + # but more importantly, it isn't clear why a "cvs status" + # would act like an unedit, and even if it does, it would + # need to make the file read-only again). + + mkdir watch5; cd watch5 + 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" + + cd first-dir + dotest watch5-1 "${testcvs} watch on" '' + # This is just like the 173 test + touch file1 + dotest watch5-2 "${testcvs} add file1" \ +"${PROG} [a-z]*: scheduling file .file1. for addition +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" + dotest watch5-3 "${testcvs} -q ci -m add" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +done +Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done" + dotest watch5-4 "${testcvs} edit file1" '' + dotest watch5-5 "test -f CVS/Base/file1" '' + if ${testcvs} status file1 >>${LOGFILE} 2>&1; then + pass watch5-6 + else + fail watch5-6 + fi + dotest watch5-7 "test -f CVS/Base/file1" '' + + # Here's where the file used to dissappear + touch file1 + if ${testcvs} status file1 >>${LOGFILE} 2>&1; then + pass watch5-8 + else + fail watch5-8 + fi + dotest watch5-10 "test -f CVS/Base/file1" '' + + # Make sure update won't remove the file either + touch file1 + dotest watch5-11 "${testcvs} -q up" '' + dotest watch5-12 "test -f CVS/Base/file1" '' + + cd ../.. + rm -r watch5 + rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + unedit-without-baserev) mkdir 1; cd 1 module=x @@ -10912,7 +11347,7 @@ done" cp ../binfile.dat file1 dotest binfiles3-6 "${testcvs} add -kb file1" \ "${PROG} [a-z]*: re-adding file file1 (in place of dead revision 1\.2) -${PROG} [a-z]*: use .cvs commit. to add this file permanently" +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" # The idea behind this test is to make sure that the file # gets opened in binary mode to send to "cvs ci". dotest binfiles3-6a "cat CVS/Entries" \ @@ -13295,6 +13730,12 @@ EOF # features, which always seems to be problematic since then # someone feels like documenting them and things go downhill # from there). + # + # Hmm, if this test is run on the 31st of the month, and 100 + # months from now is a month with only 30 days (e.g. run on + # 31 May 1999), it seems to fail. + # + # Sigh. if ${testcvs} -q update -p -D '100 months' file1 \ >${TESTDIR}/rcs4.tmp 2>&1 then @@ -13460,6 +13901,297 @@ ${PROG} [a-z]*: Rebuilding administrative file database" rm -rf ${CVSROOT_DIRNAME}/first-dir ;; + backuprecover) + # Tests to make sure we get the expected behavior + # when we recover a repository from an old backup + # + # Details: + # Backup will be older than some developer's workspaces + # This means the first attempt at an update will fail + # The workaround for this is to replace the CVS + # directories with those from a "new" checkout from + # the recovered repository. Due to this, multiple + # merges should cause conflicts (the same data + # will be merged more than once). + # A workspace updated before the date of the recovered + # copy will not need any extra attention + # + # Note that backuprecover-15 is probably a failure case + # If nobody else had a more recent update, the data would be lost + # permanently + # Granted, the developer should have been notified not to do this + # by now, but still... + # + mkdir backuprecover; cd backuprecover + mkdir 1; cd 1 + 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" + cd first-dir + mkdir dir + dotest backuprecover-3 "${testcvs} add dir" \ +"Directory ${TESTDIR}/cvsroot/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 +done +Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done +RCS file: ${TESTDIR}/cvsroot/first-dir/dir/file2,v +done +Checking in dir/file2; +${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +initial revision: 1\.1 +done" + echo "Line one" >>file1 + echo " is the place" >>file1 + echo " we like to begin" >>file1 + echo "Anything else" >>file1 + echo " looks like" >>file1 + echo " a sin" >>file1 + echo "File 2" >>dir/file2 + echo " is the place" >>dir/file2 + echo " the rest of it goes" >>dir/file2 + echo "Why I don't use" >>dir/file2 + echo " something like 'foo'" >>dir/file2 + echo " God only knows" >>dir/file2 + dotest backuprecover-6 "${testcvs} -q ci -mtest" \ +"Checking in file1; +${TESTDIR}/cvsroot/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 +new revision: 1\.2; previous revision: 1\.1 +done" + + # Simulate the lazy developer + # (he did some work but didn't check it in...) + cd ../.. + 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 + + # developer 1 is on a roll + cd ../../1/first-dir + echo "I need some more words" >>file1 + echo " to fill up this space" >>file1 + echo " anything else would be a disgrace" >>file1 + echo "My rhymes cross many boundries" >>dir/file2 + echo " this time it's files" >>dir/file2 + 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 +new revision: 1\.3; previous revision: 1\.2 +done +Checking in dir/file2; +${TESTDIR}/cvsroot/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 + + # Simulate developer 3 + cd ../.. + mkdir 3; cd 3 + dotest backuprecover-9a "${testcvs} -Q co first-dir" '' + cd first-dir + echo >>file1 + echo >>dir/file2 + echo "Developer 1 makes very lame rhymes" >>file1 + echo " I think he should quit and become a mime" >>file1 + echo "What the %*^# kind of rhyme crosses a boundry?" >>dir/file2 + 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 +new revision: 1\.4; previous revision: 1\.3 +done +Checking in dir/file2; +${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +new revision: 1\.4; previous revision: 1\.3 +done" + + # Developer 4 so we can simulate a conflict later... + cd ../.. + 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 + + # And back to developer 1 + cd ../../1/first-dir + dotest backuprecover-11 "${testcvs} -Q update" '' + echo >>file1 + echo >>dir/file2 + echo "Oh yeah, well rhyme this" >>file1 + echo " developer three" >>file1 + echo " you want opposition" >>file1 + echo " you found some in me!" >>file1 + echo "I'll give you mimes" >>dir/file2 + echo " and foundries galore!" >>dir/file2 + echo " your head will spin" >>dir/file2 + 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 +new revision: 1\.5; previous revision: 1\.4 +done +Checking in dir/file2; +${TESTDIR}/cvsroot/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 + dotest backuprecover-14 "${testcvs} -q ci -mtest" \ +"Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.6; previous revision: 1\.5 +done" + echo >>file1 + echo "Tee hee hee hee" >>file1 + echo >>dir/file2 + echo "Find what's in store?" >>dir/file2 + echo " Oh, I'm so sure!" >>dir/file2 + 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 + + # Have developer 1 try an update and lose some data + # + # Feel free to imagine the horrific scream of despair + cd ../../1/first-dir + dotest backuprecover-15 "${testcvs} update" \ +"${PROG} [a-z]*: Updating . +U file1 +${PROG} [a-z]*: Updating dir +U dir/file2" + + # Developer 3 tries the same thing (he has an office) + # but fails without losing data since all of his files have + # uncommitted changes + cd ../../3/first-dir + dotest_fail backuprecover-16 "${testcvs} update" \ +"${PROG} [a-z]*: Updating \. +${PROG} \[[a-z]* aborted\]: could not find desired version 1\.6 in ${TESTDIR}/cvsroot/first-dir/file1,v" + + # create our workspace fixin' script + cd ../.. + echo \ +"#!/bin/sh + +# This script will copy the CVS database dirs from the checked out +# version of a newly recovered repository and replace the CVS +# database dirs in a workspace with later revisions than those in the +# recovered repository +cd repos-first-dir +DATADIRS=\`find . -name CVS\` +cd ../first-dir +find . -name CVS |xargs rm -rf +for file in \${DATADIRS}; do + cp -r ../repos-first-dir/\${file} \${file} +done" >fixit + + # We only need to fix the workspaces of developers 3 and 4 + # (1 lost all her data and 2 has an update date from + # before the date the backup was made) + cd 3 + dotest backuprecover-17 \ + "${testcvs} -Q co -d repos-first-dir first-dir" '' + cd ../4 + dotest backuprecover-18 \ + "${testcvs} -Q co -d repos-first-dir first-dir" '' + sh ../fixit + cd ../3; sh ../fixit + + # (re)commit developer 3's stuff + cd first-dir + dotest backuprecover-19 "${testcvs} -q ci -mrecover/merge" \ +"Checking in file1; +${TESTDIR}/cvsroot/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 +new revision: 1\.4; previous revision: 1\.3 +done" + + # and we should get a conflict on developer 4's stuff + cd ../../4/first-dir + dotest backuprecover-20 "${testcvs} update" \ +"${PROG} [a-z]*: Updating \. +RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +retrieving revision 1\.3 +retrieving revision 1\.4 +Merging differences between 1\.3 and 1\.4 into file1 +rcsmerge: warning: conflicts during merge +${PROG} [a-z]*: conflicts found in file1 +C file1 +${PROG} [a-z]*: Updating dir +RCS file: ${TESTDIR}/cvsroot/first-dir/dir/file2,v +retrieving revision 1\.3 +retrieving revision 1\.4 +Merging differences between 1\.3 and 1\.4 into file2 +rcsmerge: warning: conflicts during merge +${PROG} [a-z]*: conflicts found in dir/file2 +C dir/file2" + sed -e \ +"/^<<<<<<</,/^=======/d +/^>>>>>>>/d" file1 >tmp; mv tmp file1 + sed -e \ +"/^<<<<<<</,/^=======/d +/^>>>>>>>/d +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 +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 +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 +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 +new revision: 1\.5; previous revision: 1\.4 +done +Checking in dir/file2; +${TESTDIR}/cvsroot/first-dir/dir/file2,v <-- file2 +new revision: 1\.6; previous revision: 1\.5 +done" + + # and restore the data to developer 1 + cd ../../1/first-dir + dotest backuprecover-24 "${testcvs} -Q update" '' + + cd ../../.. + rm -r backuprecover + rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + history) # CVSROOT/history tests: # history: various "cvs history" invocations @@ -14034,6 +14766,45 @@ done" chmod 444 ${CVSROOT_DIRNAME}/CVSROOT/config ;; + symlinks2) + # Symlinks in working directory without PreservePermissions. + # Also see: symlinks: with PreservePermissions + # rcslib-symlink-*: symlinks in repository. + mkdir 1; cd 1 + 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" + cd first-dir + echo nonsymlink > slink + dotest symlinks2-3 "${testcvs} add slink" \ +"${PROG} [a-z]*: scheduling file .slink. for addition +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" + dotest symlinks2-4 "${testcvs} -q ci -m ''" \ +"RCS file: ${CVSROOT_DIRNAME}/first-dir/slink,v +done +Checking in slink; +${TESTDIR}/cvsroot/first-dir/slink,v <-- slink +initial revision: 1\.1 +done" + rm slink + # Choose name cvslog.* so it is in default ignore list. + echo second file >cvslog.file2 + 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 +new revision: 1\.2; previous revision: 1\.1 +done" + dotest symlinks2-7 "${testcvs} -q update -r 1.1 slink" "[UP] slink" + dotest symlinks2-8 "cat slink" "nonsymlink" + dotest symlinks2-9 "ls -l slink" "-[-rwx]* .* slink" + cd ../.. + + rm -rf 1 + rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + hardlinks) # short cut around checking out and committing CVSROOT rm -f ${CVSROOT_DIRNAME}/CVSROOT/config @@ -14241,6 +15012,7 @@ U file1" "U file1" # "rdiff" tests "cvs co -k". # "binfiles" (and this test) test "cvs update -k". # "binwrap" tests setting the mode from wrappers. + # "keyword2" tests "cvs update -kk -j" with text and binary files # I don't think any test is testing "cvs import -k". # Other keyword expansion tests: # keywordlog - $Log. @@ -14422,12 +15194,20 @@ new revision: 1\.3; previous revision: 1\.2 done" dotest keyword-21 "${testcvs} -q update -r tag1" "[UP] file1" - # FIXME: This test fails when remote. The second expect - # string below should be removed when this is fixed. - dotest keyword-22 "cat file1" '\$'"Name: tag1 "'\$' \ -'\$'"Name: "'\$' + dotest keyword-22 "cat file1" '\$'"Name: tag1 "'\$' - dotest keyword-23 "${testcvs} update -A file1" "[UP] file1" + if test "$remote" = yes; 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 +${PROG} update: checksum failure after patch to \./file1; will refetch +${PROG} client: refetching unpatchable files +U file1" + else + dotest keyword-23 "${testcvs} update -A file1" "[UP] file1" + fi + dotest keyword-24 "cat file1" '\$'"Name: "'\$'" +change" cd ../.. rm -r 1 @@ -14626,10 +15406,199 @@ xx" 1\.5 (${username} *[0-9a-zA-Z-]*): change" cd ../.. + # + # test the operation of 'admin -o' in conjunction with keywords + # (especially Log - this used to munge the RCS file for all time) + # + + dotest keywordlog-24 \ +"${testcvs} admin -oHEAD 1/first-dir/file1" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +deleting revision 1\.5 +done" + + dotest keywordlog-25 \ +"${testcvs} -q co -p first-dir/file1" \ +"initial +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.4 [0-9/]* [0-9:]* ${username} +xx First log line +xx Second log line +xx" + + if test $keep = yes; then + echo Keeping ${TESTDIR} and exiting due to --keep + exit 0 + fi + rm -r 1 2 rm -rf ${CVSROOT_DIRNAME}/first-dir ;; + keyword2) + # Test merging on files with keywords: + # without -kk + # with -kk + # on text files + # on binary files + # Note: This test assumes that CVS has already passed the binfiles + # test sequence + # Note2: We are testing positive on binary corruption here + # we probably really DON'T want to 'cvs update -kk' a binary file... + mkdir 1; cd 1 + 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" + cd first-dir + + echo '$''Revision$' >> file1 + echo "I" >>file1 + echo "like" >>file1 + echo "long" >>file1 + echo "files!" >>file1 + echo "" >>file1 + echo "a test line for our times" >>file1 + echo "" >>file1 + echo "They" >>file1 + echo "make" >>file1 + echo "diff" >>file1 + echo "look like it" >>file1 + echo "did a much better" >>file1 + echo "job." >>file1 + dotest keyword2-3 "${testcvs} add file1" \ +"${PROG} [a-z]*: scheduling file .file1. for addition +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" + + awk 'BEGIN { printf "%c%c%c%sRevision: 1.1 $@%c%c", \ + 2, 10, 137, "$", 13, 10 }' \ + </dev/null | tr '@' '\000' >../binfile.dat + cp ../binfile.dat . + dotest keyword2-5 "${testcvs} add -kb binfile.dat" \ +"${PROG} [a-z]*: scheduling file .binfile\.dat. for addition +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" + + dotest keyword2-6 "${testcvs} -q ci -m add" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/binfile\.dat,v +done +Checking in binfile\.dat; +${TESTDIR}/cvsroot/first-dir/binfile\.dat,v <-- binfile\.dat +initial revision: 1\.1 +done +RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +done +Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done" + + dotest keyword2-7 "${testcvs} -q tag -b branch" \ +"T binfile\.dat +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 +new revision: 1\.2; previous revision: 1\.1 +done" + + dotest keyword2-9 "${testcvs} -q update -r branch" '[UP] file1' + + 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 +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 +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into file1 +rcsmerge: warning: conflicts during merge" + + dotest_fail keyword2-12 "${testcvs} diff file1" \ +"Index: file1 +=================================================================== +RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +retrieving revision 1\.2 +diff -r1\.2 file1 +0a1 +> <<<<<<< file1 +1a3,5 +> ======= +> \\\$""Revision: 1\.1\.2\.1 \\\$ +> >>>>>>> 1\.1\.2\.1 +14a19 +> what else do we have${QUESTION}" + + # 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" \ +"U binfile.dat +U file1 +RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into file1" + else + dotest keyword2-13 "${testcvs} -q update -A -kk -j branch" \ +"U binfile.dat +${PROG} [a-z]*: warning: file1 was lost +U file1 +RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into file1" + fi + + # binfile won't get checked in, but it is now corrupt and could + # have been checked in if it had changed on the branch... + dotest keyword2-14 "${testcvs} -q ci -m change" \ +"Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2 +done" + + dotest_fail keyword2-15 "cmp binfile.dat ../binfile.dat" \ +"binfile\.dat \.\./binfile\.dat differ: char 13, line 2" + + # Okay, restore everything and make CVS try and merge a binary file... + dotest keyword2-16 "${testcvs} -q update -A" \ +"[UP] binfile.dat +[UP] file1" + dotest keyword2-17 "${testcvs} -q tag -b branch2" \ +"T binfile\.dat +T file1" + dotest keyword2-18 "${testcvs} -q update -r branch2" '' + + awk 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \ + </dev/null | tr '@' '\000' >>binfile.dat + dotest keyword2-19 "${testcvs} -q ci -m badbadbad" \ +"Checking in binfile\.dat; +${TESTDIR}/cvsroot/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 +retrieving revision 1\.1 +retrieving revision 1\.1\.4\.1 +Merging differences between 1\.1 and 1\.1\.4\.1 into binfile\.dat +U file1" + + # Yep, it's broke, 'cept for that gal in Hodunk who uses -kk + # so that some files only merge when she says so. Time to clean up... + cd ../.. + rm -r 1 + rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + head) # Testing handling of the HEAD special tag. # There are many cases involving added and removed files @@ -14800,6 +15769,21 @@ done" tagdate) # Test combining -r and -D. + # + # Note that this is not a complete test. It relies on the fact + # that update, checkout and export have a LOT of shared code. + # Notice: + # 1) checkout is never tested at all with -r -D + # 2) update never uses an argument to '-D' besides 'now' + # (this test does not provide enough data to prove + # that 'cvs update' with both a '-r' and a '-D' + # specified does not ignore '-D': a 'cvs up + # -r<branch> -Dnow' and a 'cvs up -r<branch>' + # should specify the same file revision). + # 3) export uses '-r<branch> -D<when there was a different + # revision>', hopefully completing this behavior test + # for checkout and update as well. + # mkdir 1; cd 1 dotest tagdate-1 "${testcvs} -q co -l ." '' mkdir first-dir @@ -14837,11 +15821,95 @@ done" ${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 new revision: 1\.1\.4\.1; previous revision: 1\.1 done" + # Then the case where br2 does have revisions: dotest tagdate-11 "${testcvs} -q update -p -r br1 -D now" "trunk-1" + # For some reason, doing this on a branch seems to be relevant. + dotest_fail tagdate-12 "${testcvs} -q update -j:yesterday" \ +"${PROG} \[[a-z]* aborted\]: argument to join may not contain a date specifier without a tag" + # And check export + + # Wish some shorter sleep interval would suffice, but I need to + # guarantee that the point in time specified by the argument to -D + # in tagdate-14 and tagdate-16 + # falls in the space of time between commits to br2 and I + # figure 60 seconds is probably a large enough range to + # account for most network file system delays and such... + # as it stands, it takes between 1 and 2 seconds between + # calling CVS on my machine and the -D argument being used to + # recall the file revision and this timing will certainly vary + # by several seconds between machines - dependant on CPUspeeds, + # I/O speeds, load, etc. + sleep 60 + + echo br2-2 >file1 + dotest tagdate-13 "${testcvs} -q ci -m modify-2-on-br2" \ +"Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.1\.4\.2; previous revision: 1\.1\.4\.1 +done" cd ../.. - rm -r 1 + mkdir 2; cd + if ${testcvs} -q export -r br2 -D'1 minute ago' first-dir \ + >${TESTDIR}/tagdate.tmp 2>&1; then + if ${EXPR} "`cat ${TESTDIR}/tagdate.tmp`" : \ +"[UP] first-dir/file1" >/dev/null; then + pass tagdate-14 + else + echo "** expected: " >>${LOGFILE} + echo "[UP] first-dir/file1" >>${LOGFILE} + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/tagdate.tmp >>${LOGFILE} + fail tagdate-14 + fi + else + echo "Bad exit status" >>${LOGFILE} + fail tagdate-14 + fi + + if ${EXPR} "`cat first-dir/file1`" : "br2-1" >/dev/null; then + pass tagdate-15 + else + fail tagdate-15 + fi + + # Now for annotate + cd ../1/first-dir + if ${testcvs} annotate -rbr2 -D'1 minute ago' \ + >${TESTDIR}/tagdate.tmp 2>&1; then + if ${EXPR} "`cat ${TESTDIR}/tagdate.tmp`" : \ +"Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1\.4\.1 (${username} *[0-9a-zA-Z-]*): br2-1" >/dev/null; then + pass tagdate-16 + else + echo "** expected: " >>${LOGFILE} + echo "Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1\.4\.1 (${username} *[0-9a-zA-Z-]*): br2-1" >>${LOGFILE} + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/tagdate.tmp >>${LOGFILE} + fail tagdate-16 + fi + else + echo "Bad exit status" >>${LOGFILE} + fail tagdate-16 + fi + + dotest tagdate-17 "${testcvs} annotate -rbr2 -Dnow" \ +"Annotations for file1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +1\.1\.4\.2 (${username} *[0-9a-zA-Z-]*): br2-2" + + if test $keep = yes; then + echo Keeping ${TESTDIR} and exiting due to --keep + exit 0 + fi + + cd ../.. + rm ${TESTDIR}/tagdate.tmp + rm -r 1 2 rm -rf ${CVSROOT_DIRNAME}/first-dir ;; @@ -15084,6 +16152,7 @@ done" # 1.3.2.6::1.3.2 # 1.3.2.1::1.3.2.6 # 1.3::1.3.2.6 (error? or synonym for ::1.3.2.6?) + # -n: admin, tagf tests. mkdir 1; cd 1 dotest admin-1 "${testcvs} -q co -l ." '' @@ -15389,6 +16458,11 @@ total revisions: 2 done" fi # end of tests skipped for remote + # Now test that plain -e is at least parsed right. CVS 1.10 + # would wrongly treat "-e file1" as "-efile1". + dotest_fail admin-19a-2 "${testcvs} -q admin -e file1" \ +"${PROG} \[[a-z]* aborted\]: removing entire access list not yet implemented" + # Add another revision to file2, so we can delete one. echo 'add a line' >> file2 dotest admin-21 "${testcvs} -q ci -m modify file2" \ @@ -17402,24 +18476,24 @@ ${PROG} [a-z]*: Tagging mod2-2" ${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 'cvs commit' to add these files permanently" +${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" else cd mod1-1 dotest multiroot-add-1a "${testcvs} add anotherfile1-1" \ "${PROG} [a-z]*: scheduling file .anotherfile1-1. for addition -${PROG} [a-z]*: use 'cvs commit' to add this file permanently" +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" cd ../mod2-1 dotest multiroot-add-1b "${testcvs} add anotherfile2-1" \ "${PROG} [a-z]*: scheduling file .anotherfile2-1. for addition -${PROG} [a-z]*: use 'cvs commit' to add this file permanently" +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" cd ../mod2-2/mod1-2 dotest multiroot-add-1c "${testcvs} add anotherfile1-2" \ "${PROG} [a-z]*: scheduling file .anotherfile1-2. for addition -${PROG} [a-z]*: use 'cvs commit' to add this file permanently" +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" cd ../../mod1-2/mod2-2 dotest multiroot-add-1d "${testcvs} add anotherfile2-2" \ "${PROG} [a-z]*: scheduling file .anotherfile2-2. for addition -${PROG} [a-z]*: use 'cvs commit' to add this file permanently" +${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" cd ../.. fi @@ -18510,6 +19584,47 @@ done" unset CVSROOT2 ;; + rmroot) + # When the Entries/Root file is removed from an existing + # workspace, CVS should assume $CVSROOT instead + # + # Right now only checking that CVS exits normally on an + # update once CVS/Root is deleted + # + # There was a time when this would core dump when run in + # client/server mode + + mkdir 1; cd 1 + 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" + cd first-dir + touch file1 file2 + dotest rmroot-setup-3 "${testcvs} add file1 file2" \ +"${PROG} [a-z]*: scheduling file .file1. for addition +${PROG} [a-z]*: scheduling file .file2. for addition +${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" + dotest rmroot-setup-4 "${testcvs} -q commit -minit" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +done +Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done +RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +done +Checking in file2; +${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +initial revision: 1\.1 +done" + rm CVS/Root + dotest rmroot-1 "${testcvs} -q update" '' + + cd ../.. + rm -rf 1 + ;; + reposmv) # More tests of repositories and specifying them. # Similar to crerepos but that test is probably getting big @@ -18656,7 +19771,8 @@ Root ${CVSROOT_DIRNAME} noop EOF dotest pserver-4 "cat ${TESTDIR}/pserver.tmp" \ -"I LOVE YOU${DOTSTAR}ok" +"${DOTSTAR} LOVE YOU +ok" ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF BEGIN AUTH REQUEST @@ -18668,7 +19784,8 @@ Root ${TESTDIR}/1 noop EOF dotest pserver-5 "cat ${TESTDIR}/pserver.tmp" \ -"I LOVE YOU${DOTSTAR}E Protocol error: Root says \"${TESTDIR}/1\" but pserver says \"${CVSROOT_DIRNAME}\" +"${DOTSTAR} LOVE YOU +E Protocol error: Root says \"${TESTDIR}/1\" but pserver says \"${CVSROOT_DIRNAME}\" error " ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF @@ -18681,6 +19798,26 @@ EOF dotest pserver-6 "cat ${TESTDIR}/pserver.tmp" \ "I HATE YOU" + ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF +BEGIN VERIFICATION REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d^b?hd +END VERIFICATION REQUEST +EOF + dotest pserver-7 "cat ${TESTDIR}/pserver.tmp" \ +"I HATE YOU" + + ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF +BEGIN VERIFICATION REQUEST +${CVSROOT_DIRNAME} +testme +Ay::'d +END VERIFICATION REQUEST +EOF + dotest pserver-8 "cat ${TESTDIR}/pserver.tmp" \ +"${DOTSTAR} LOVE YOU" + # Clean up. echo "# comments only" >config dotest pserver-cleanup-1 "${testcvs} -q ci -m config-it" \ @@ -18726,14 +19863,14 @@ EOF dotest server-3 "test -d ${TESTDIR}/crerepos/CVSROOT" "" # Now some tests of gzip-file-contents (used by jCVS). - awk 'BEGIN { -printf "%c%c%c%c%c%c.6%c%c+I-.%c%c%c%c5%c;%c%c%c%c", + awk 'BEGIN { \ +printf "%c%c%c%c%c%c.6%c%c+I-.%c%c%c%c5%c;%c%c%c%c", \ 31, 139, 8, 64, 5, 7, 64, 3, 225, 2, 64, 198, 185, 5, 64, 64, 64}' \ </dev/null | tr '\100' '\000' >gzipped.dat - echo Root ${TESTDIR}/crerepos >session.dat # Note that the CVS client sends "-b 1.1.1", and this # test doesn't. But the server also defaults to that. - cat <<EOF >>session.dat + cat <<EOF >session.dat +Root ${TESTDIR}/crerepos UseUnchanged gzip-file-contents 3 Argument -m @@ -18743,7 +19880,7 @@ Argument dir1 Argument tag1 Argument tag2 Directory . -in-real-life-this-is-funky-but-server-seems-to-ignore-it +${TESTDIR}/crerepos Modified file1 u=rw,g=r,o=r z25 @@ -18763,6 +19900,177 @@ ok" dotest server-5 \ "${testcvs} -q -d ${TESTDIR}/crerepos co -p dir1/file1" "test" + # OK, here are some notify tests. + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Notify file1 +E Fri May 7 13:21:09 1999 GMT myhost some-work-dir EUC +noop +EOF + dotest server-6 "cat ${TESTDIR}/server.tmp" \ +"Notified \./ +${TESTDIR}/crerepos/dir1/file1 +ok" + else + echo "exit status was $?" >>${LOGFILE} + fail server-6 + fi + # Sending the second "noop" before waiting for the output + # from the first is bogus but hopefully we can get away + # with it. + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Notify file1 +E Fri May 7 13:21:09 1999 GMT myhost some-work-dir EUC +noop +Notify file1 +E The 57th day of Discord in the YOLD 3165 myhost some-work-dir EUC +noop +EOF + dotest server-7 "cat ${TESTDIR}/server.tmp" \ +"Notified \./ +${TESTDIR}/crerepos/dir1/file1 +ok +Notified \./ +${TESTDIR}/crerepos/dir1/file1 +ok" + else + echo "exit status was $?" >>${LOGFILE} + fail server-7 + fi + + # OK, now test a few error conditions. + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Notify file1 +E Setting Orange, the 52th day of Discord in the YOLD 3165 myhost some-work-dir EUC +noop +EOF + # FIXCVS: should give "error" and no "Notified", like server-9 + dotest server-8 "cat ${TESTDIR}/server.tmp" \ +"E ${PROG} server: invalid character in editor value +Notified \./ +${TESTDIR}/crerepos/dir1/file1 +ok" + else + echo "exit status was $?" >>${LOGFILE} + fail server-8 + fi + + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Notify file1 +E Setting Orange+57th day of Discord myhost some-work-dir EUC +noop +EOF + dotest server-9 "cat ${TESTDIR}/server.tmp" \ +"E Protocol error; misformed Notify request +error " + else + echo "exit status was $?" >>${LOGFILE} + fail server-9 + fi + + # First demonstrate an interesting quirk in the protocol. + # The "watchers" request selects the files to operate based + # on files which exist in the working directory. So if we + # don't send "Entry" or the like, it won't do anything. + # Wants to be documented in cvsclient.texi... + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +watchers +EOF + dotest server-10 "cat ${TESTDIR}/server.tmp" \ +"ok" + else + echo "exit status was $?" >>${LOGFILE} + fail server-10 + fi + + # See if "watchers" and "editors" display the right thing. + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Entry /file1/1.1//// +watchers +EOF + dotest server-11 "cat ${TESTDIR}/server.tmp" \ +"M file1 ${username} tedit tunedit tcommit +ok" + else + echo "exit status was $?" >>${LOGFILE} + fail server-11 + fi + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Entry /file1/1.1//// +editors +EOF + dotest server-12 "cat ${TESTDIR}/server.tmp" \ +"M file1 ${username} The 57th day of Discord in the YOLD 3165 myhost some-work-dir +ok" + else + echo "exit status was $?" >>${LOGFILE} + fail server-12 + fi + + # Now do an unedit. + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +Notify file1 +U 7 May 1999 15:00 GMT myhost some-work-dir EUC +noop +EOF + dotest server-13 "cat ${TESTDIR}/server.tmp" \ +"Notified \./ +${TESTDIR}/crerepos/dir1/file1 +ok" + else + echo "exit status was $?" >>${LOGFILE} + fail server-13 + fi + + # Now try "watchers" and "editors" again. + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +watchers +EOF + dotest server-14 "cat ${TESTDIR}/server.tmp" \ +"ok" + else + echo "exit status was $?" >>${LOGFILE} + fail server-14 + fi + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/crerepos +Directory . +${TESTDIR}/crerepos/dir1 +editors +EOF + dotest server-15 "cat ${TESTDIR}/server.tmp" \ +"ok" + else + echo "exit status was $?" >>${LOGFILE} + fail server-15 + fi + if test "$keep" = yes; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 @@ -18774,6 +20082,73 @@ ok" fi # skip the whole thing for local ;; + server2) + # More server tests, in particular testing that various + # possible security holes are plugged. + if test "$remote" = yes; then + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/cvsroot +Directory . +${TESTDIR}/cvsroot/../dir1 +noop +EOF + dotest server2-1 "cat ${TESTDIR}/server.tmp" \ +"E protocol error: directory '${TESTDIR}/cvsroot/\.\./dir1' not within root '${TESTDIR}/cvsroot' +error " + else + echo "exit status was $?" >>${LOGFILE} + fail server2-1 + fi + + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/cvsroot +Directory . +${TESTDIR}/cvsrootdir1 +noop +EOF + dotest server2-2 "cat ${TESTDIR}/server.tmp" \ +"E protocol error: directory '${TESTDIR}/cvsrootdir1' not within root '${TESTDIR}/cvsroot' +error " + else + echo "exit status was $?" >>${LOGFILE} + fail server2-2 + fi + + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/cvsroot +Directory . +${TESTDIR} +noop +EOF + dotest server2-3 "cat ${TESTDIR}/server.tmp" \ +"E protocol error: directory '${TESTDIR}' not within root '${TESTDIR}/cvsroot' +error " + else + echo "exit status was $?" >>${LOGFILE} + fail server2-3 + fi + + # OK, now a few tests for the rule that one cannot pass a + # filename containing a slash to Modified, Is-modified, + # Notify, Questionable, or Unchanged. For completeness + # we'd try them all. For lazyness/conciseness we don't. + if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then +Root ${TESTDIR}/cvsroot +Directory . +${TESTDIR}/cvsroot +Unchanged foo/bar +noop +EOF + dotest server2-4 "cat ${TESTDIR}/server.tmp" \ +"E protocol error: directory 'foo/bar' not within current directory +error " + else + echo "exit status was $?" >>${LOGFILE} + fail server2-4 + fi + fi + ;; + client) # Some tests of the client (independent of the server). if test "$remote" = yes; then @@ -18917,8 +20292,6 @@ echo "OK, all tests completed." # * Test ability to send notifications in response to watches. (currently # hard to test because CVS doesn't send notifications if username is the # same). -# * Test that remote edit and/or unedit works when disconnected from -# server (e.g. set CVS_SERVER to "foobar"). # * Test the contents of adm files other than Root and Repository. # Entries seems the next most important thing. # * Test the following compatibility issues: diff --git a/gnu/usr.bin/cvs/src/status.c b/gnu/usr.bin/cvs/src/status.c index c405c454515..4e5ddcbd658 100644 --- a/gnu/usr.bin/cvs/src/status.c +++ b/gnu/usr.bin/cvs/src/status.c @@ -67,37 +67,38 @@ cvsstatus (argc, argv) wrap_setup (); #ifdef CLIENT_SUPPORT - if (client_active) { - start_server (); + if (client_active) + { + start_server (); - ign_setup (); + ign_setup (); - if (long_format) - send_arg("-v"); - if (local) - send_arg("-l"); + if (long_format) + send_arg("-v"); + if (local) + send_arg("-l"); - /* For a while, we tried setting SEND_NO_CONTENTS here so this - could be a fast operation. That prevents the - server from updating our timestamp if the timestamp is - changed but the file is unmodified. Worse, it is user-visible - (shows "locally modified" instead of "up to date" if - timestamp is changed but file is not). And there is no good - workaround (you might not want to run "cvs update"; "cvs -n - update" doesn't update CVS/Entries; "cvs diff --brief" or - something perhaps could be made to work but somehow that - seems nonintuitive to me even if so). Given that timestamps - seem to have the potential to get munged for any number of - reasons, it seems better to not rely too much on them. */ + /* For a while, we tried setting SEND_NO_CONTENTS here so this + could be a fast operation. That prevents the + server from updating our timestamp if the timestamp is + changed but the file is unmodified. Worse, it is user-visible + (shows "locally modified" instead of "up to date" if + timestamp is changed but file is not). And there is no good + workaround (you might not want to run "cvs update"; "cvs -n + update" doesn't update CVS/Entries; "cvs diff --brief" or + something perhaps could be made to work but somehow that + seems nonintuitive to me even if so). Given that timestamps + seem to have the potential to get munged for any number of + reasons, it seems better to not rely too much on them. */ - send_files (argc, argv, local, 0, 0); + send_files (argc, argv, local, 0, 0); - send_file_names (argc, argv, SEND_EXPAND_WILD); + send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server ("status\012", 0); - err = get_responses_and_close (); + send_to_server ("status\012", 0); + err = get_responses_and_close (); - return err; + return err; } #endif @@ -288,20 +289,20 @@ status_fileproc (callerdat, finfo) } else if (!really_quiet) cvs_output (" Sticky Options:\t(none)\n", 0); + } - if (long_format && vers->srcfile) - { - List *symbols = RCS_symbols(vers->srcfile); + if (long_format && vers->srcfile) + { + List *symbols = RCS_symbols(vers->srcfile); - cvs_output ("\n Existing Tags:\n", 0); - if (symbols) - { - xrcsnode = finfo->rcs; - (void) walklist (symbols, tag_list_proc, NULL); - } - else - cvs_output ("\tNo Tags Exist\n", 0); + cvs_output ("\n Existing Tags:\n", 0); + if (symbols) + { + xrcsnode = finfo->rcs; + (void) walklist (symbols, tag_list_proc, NULL); } + else + cvs_output ("\tNo Tags Exist\n", 0); } cvs_output ("\n", 0); diff --git a/gnu/usr.bin/cvs/src/subr.c b/gnu/usr.bin/cvs/src/subr.c index b2e250c0e40..6a97f287d5f 100644 --- a/gnu/usr.bin/cvs/src/subr.c +++ b/gnu/usr.bin/cvs/src/subr.c @@ -16,7 +16,7 @@ extern char *getlogin (); /* * malloc some data and die if it fails */ -char * +void * xmalloc (bytes) size_t bytes; { @@ -30,8 +30,12 @@ xmalloc (bytes) cp = malloc (bytes); if (cp == NULL) - error (1, 0, "out of memory; can not allocate %lu bytes", - (unsigned long) bytes); + { + char buf[80]; + sprintf (buf, "out of memory; can not allocate %lu bytes", + (unsigned long) bytes); + error (1, 0, buf); + } return (cp); } @@ -53,7 +57,12 @@ xrealloc (ptr, bytes) cp = realloc (ptr, bytes); if (cp == NULL) - error (1, 0, "can not reallocate %lu bytes", (unsigned long) bytes); + { + char buf[80]; + sprintf (buf, "out of memory; can not reallocate %lu bytes", + (unsigned long) bytes); + error (1, 0, buf); + } return (cp); } @@ -623,15 +632,14 @@ get_file (name, fullname, mode, buf, bufsize, len) } else { - if (CVS_LSTAT (name, &s) < 0) - error (1, errno, "can't stat %s", fullname); + /* Although it would be cleaner in some ways to just read + until end of file, reallocating the buffer, this function + does get called on files in the working directory which can + be of arbitrary size, so I think we better do all that + extra allocation. */ - /* Don't attempt to read special files or symlinks. */ - if (!S_ISREG (s.st_mode)) - { - *len = 0; - return; - } + if (CVS_STAT (name, &s) < 0) + error (1, errno, "can't stat %s", fullname); /* Convert from signed to unsigned. */ filesize = s.st_size; @@ -660,9 +668,7 @@ get_file (name, fullname, mode, buf, bufsize, len) if (feof (e)) break; - /* It's probably paranoid to think S.ST_SIZE might be - too small to hold the entire file contents, but we - handle it just in case. */ + /* Allocate more space if needed. */ if (tobuf == *buf + *bufsize) { int c; diff --git a/gnu/usr.bin/cvs/src/tag.c b/gnu/usr.bin/cvs/src/tag.c index fa713455d96..fb19cbae78a 100644 --- a/gnu/usr.bin/cvs/src/tag.c +++ b/gnu/usr.bin/cvs/src/tag.c @@ -914,6 +914,13 @@ tag_check_valid_join (join_tag, argc, argv, local, aflag, repository) join_tag); *s = '\0'; + /* hmmm... I think it makes sense to allow -j:<date>, but + * for now this fixes a bug where CVS just spins and spins (I + * think in the RCS code) looking for a zero length tag. + */ + if (!*c) + error (1, 0, + "argument to join may not contain a date specifier without a tag"); } tag_check_valid (c, argc, argv, local, aflag, repository); diff --git a/gnu/usr.bin/cvs/src/version.c b/gnu/usr.bin/cvs/src/version.c index ca5a98b21b4..97622ffa797 100644 --- a/gnu/usr.bin/cvs/src/version.c +++ b/gnu/usr.bin/cvs/src/version.c @@ -12,7 +12,7 @@ #include "cvs.h" -char *version_string = "\nConcurrent Versions System (CVS) 1.10.5"; +char *version_string = "\nConcurrent Versions System (CVS) 1.10.7"; #ifdef CLIENT_SUPPORT #ifdef SERVER_SUPPORT |