summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/cvs/src
diff options
context:
space:
mode:
authortholo <tholo@openbsd.org>1997-03-18 01:54:58 +0000
committertholo <tholo@openbsd.org>1997-03-18 01:54:58 +0000
commit780d15dfff9934c79e6717020f46114c9b7d7d04 (patch)
treec30bfaa01ad0bbfdf5b53084f97efc0cf0c14039 /gnu/usr.bin/cvs/src
parentFrom Scott Reynolds <scottr@netbsd.org> (, but compilable ;-) (diff)
downloadwireguard-openbsd-780d15dfff9934c79e6717020f46114c9b7d7d04.tar.xz
wireguard-openbsd-780d15dfff9934c79e6717020f46114c9b7d7d04.zip
New release from Cyclic Software
Diffstat (limited to 'gnu/usr.bin/cvs/src')
-rw-r--r--gnu/usr.bin/cvs/src/ChangeLog443
-rw-r--r--gnu/usr.bin/cvs/src/Makefile.in1
-rw-r--r--gnu/usr.bin/cvs/src/add.c76
-rw-r--r--gnu/usr.bin/cvs/src/admin.c5
-rw-r--r--gnu/usr.bin/cvs/src/checkin.c9
-rw-r--r--gnu/usr.bin/cvs/src/client.c112
-rw-r--r--gnu/usr.bin/cvs/src/client.h2
-rw-r--r--gnu/usr.bin/cvs/src/diff.c11
-rw-r--r--gnu/usr.bin/cvs/src/edit.c4
-rw-r--r--gnu/usr.bin/cvs/src/error.c2
-rw-r--r--gnu/usr.bin/cvs/src/expand_path.c96
-rw-r--r--gnu/usr.bin/cvs/src/fileattr.c51
-rw-r--r--gnu/usr.bin/cvs/src/fileattr.h9
-rw-r--r--gnu/usr.bin/cvs/src/filesubr.c7
-rw-r--r--gnu/usr.bin/cvs/src/find_names.c17
-rw-r--r--gnu/usr.bin/cvs/src/hash.c5
-rw-r--r--gnu/usr.bin/cvs/src/history.c63
-rw-r--r--gnu/usr.bin/cvs/src/import.c98
-rw-r--r--gnu/usr.bin/cvs/src/log.c2
-rw-r--r--gnu/usr.bin/cvs/src/login.c108
-rw-r--r--gnu/usr.bin/cvs/src/logmsg.c59
-rw-r--r--gnu/usr.bin/cvs/src/mkmodules.c53
-rw-r--r--gnu/usr.bin/cvs/src/modules.c105
-rw-r--r--gnu/usr.bin/cvs/src/myndbm.c19
-rw-r--r--gnu/usr.bin/cvs/src/parseinfo.c30
-rw-r--r--gnu/usr.bin/cvs/src/rcs.c71
-rw-r--r--gnu/usr.bin/cvs/src/recurse.c92
-rw-r--r--gnu/usr.bin/cvs/src/release.c13
-rw-r--r--gnu/usr.bin/cvs/src/remove.c51
-rw-r--r--gnu/usr.bin/cvs/src/repos.c38
-rw-r--r--gnu/usr.bin/cvs/src/root.c54
-rw-r--r--gnu/usr.bin/cvs/src/rtag.c27
-rw-r--r--gnu/usr.bin/cvs/src/run.c32
-rw-r--r--gnu/usr.bin/cvs/src/sanity.sh534
-rw-r--r--gnu/usr.bin/cvs/src/status.c7
-rw-r--r--gnu/usr.bin/cvs/src/subr.c79
-rw-r--r--gnu/usr.bin/cvs/src/tag.c4
-rw-r--r--gnu/usr.bin/cvs/src/version.c2
-rw-r--r--gnu/usr.bin/cvs/src/watch.c4
-rw-r--r--gnu/usr.bin/cvs/src/wrapper.c53
40 files changed, 2024 insertions, 424 deletions
diff --git a/gnu/usr.bin/cvs/src/ChangeLog b/gnu/usr.bin/cvs/src/ChangeLog
index c9d0f394f64..a78216d0505 100644
--- a/gnu/usr.bin/cvs/src/ChangeLog
+++ b/gnu/usr.bin/cvs/src/ChangeLog
@@ -1,5 +1,448 @@
+Sun Mar 16 10:18:28 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * version.c: Version 1.9.4.
+
+ * rcscmds.c (RCS_checkin): Preserve the mode of the rcsfile.
+ RCS_CI usually, but not always, does this for us.
+ * commit.c (fix_rcs_modes): Replace algorithm with a more
+ CVSUMASK-friendly one.
+ * sanity.sh (modes): Update tests modes-5, modes-7, modes-10, and
+ modes-15 so they test that CVSUMASK is honored.
+
+Sun Mar 16 10:18:28 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (modes): New tests modes-7a and modes-7b test behavior
+ if one manually changes the modes in the repository.
+
+ * server.c (server): Revise code which checks for errors creating
+ temporary directory. This won't solve the intermittent
+ can't create temporary directory
+ Unknown error -1
+ but it will mean (a) the right message based on errno gets
+ printed, instead of "unknown error -1", and (b) the message says
+ that it happened in chmod instead of mkdir_p.
+
+Sat Mar 15 16:47:12 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (modes): New tests. Note that (for now) these are
+ just testing how CVS already behaves; I want to record that before
+ I move on to changing CVS's behavior with modes of RCS files.
+
+13 Mar 1997 Jim Kingdon
+
+ * subr.c (line2argv): Change argv_allocated from size_t to int.
+
+Wed Mar 12 22:16:44 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * add.c (add_directory): If repository has an extraneous "."
+ directory at the end, strip it off. This fixes a bug which was
+ introduced when strip_path was nuked (this fix is much more
+ limited in scope than strip_path was; I _think_ that is a good
+ thing).
+ (add): Likewise, for client.
+ (combine_dir): New function, helps with above.
+ * sanity.sh (modules3): Reenable tests for this behavior.
+ (basica-0b, basicb-0e): Adjust test to reflect "foo/bar" instead
+ of "foo/./bar" in message. As with the rest of this, I believe
+ this is just restoring the behavior prior to the strip_path nuking
+ (I tried it with CVS 1.9).
+
+Sun Mar 9 10:06:29 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * root.c (parse_cvsroot), server.c (serve_root, serve_init):
+ If CVSroot_directory is not an absolute pathname, give a fatal error.
+ * sanity.sh (crerepos): New tests crerepos-6* test for above fixes.
+
+Sat Mar 8 22:06:17 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ This cleans up the last known code which can overflow its buffers
+ (except the Mac client). I've skimmed through much of CVS looking
+ for other such places; but I didn't read everything. If I missed
+ any please report it to bug-cvs.
+ * logmsg.c (logfile_write, title_proc): Realloc str_list as
+ needed; don't assume MAXLISTLEN is enough.
+ * cvs.h (MAXLISTLEN, MAXFILEPERDIR): Removed; no longer used.
+ * add.c, myndbm.c, parseinfo.c, update.c: Nuke MAXLINELEN limit.
+ * parseinfo.c, update.c, mkmodules.c: Check for errors reading file.
+ * cvs.h (MAXLINELEN): Removed; no longer used.
+ * logmsg (MAXHOSTNAMELEN): Removed; not used.
+ * main.c (cmd_synonyms): Allocate based on fullname, nick1, and
+ nick2, just in case someone makes those big enough so that 100
+ bytes is not enough.
+ (Make_Date): Use MAXDATELEN rather than our own fixed size.
+ * mkmodules.c (mkmodules): Nuke arbitrary limit on line length.
+ * rcs.c (ALLOCINCR): Remove; not used.
+ (RCS_check_kflag): Add comment concerning karg size.
+ * run.c: Allocate run_prog to the needed size, rather than
+ allocating a fixed size buffer.
+
+Fri Mar 7 22:39:08 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * logmsg.c (logfile_write): Allocate prog to needed length rather
+ than assuming MAXPROGLEN is enough.
+ * cvs.h (MAXPROGLEN): Removed; no longer used.
+ * subr.c (MIN_INCR): Update comment to reflect MAXPROGLEN's demise.
+
+ * subr.c (free_names): Fix comment: this function is not used to
+ free memory allocated by Find_Names (at least it hasn't for a long
+ time).
+ * subr.c, cvs.h (line2argv): Change calling convention so that we
+ allocate argv array rather than the caller. The previous one had
+ no way of checking whether we overflowed the passed-in buffer.
+ * subr.c (free_names): Free the argv array too.
+ * modules.c (do_module, cat_module): Update callers.
+
+Thu Mar 6 12:44:42 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * import.c: Allocate vhead and vbranch dynamically; removes
+ arbitrary limit.
+ * history.c: Likewise (since_rev, since_tag, backto, rec_types).
+ * ignore.c: Likewise (line). Also check for errors from getline
+ and add 'copyright' notice to top of file.
+ * wrapper.c (wrap_add_file): Likewise (line). Also check for
+ errors from various calls and add 'copyright' notice to top of file.
+
+Tue Mar 4 17:39:15 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * client.c (update_entries): Add comment about "move away <file>"
+ message.
+
+Mon Mar 3 21:51:40 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (basicb): Clean up topfile,v at end of test. Fixes
+ failure in modules-155b.
+
+Sun Mar 2 18:11:09 1997 Dan Wilder <dan@gasboy.com>
+ and Jim Kingdon
+
+ * admin.c (admin): Arrange to perform recursion if "cvs admin"
+ is passed only options.
+
+Sun Mar 2 18:11:09 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (basicb): New tests basicb-0* test for files at top
+ level.
+
+ * error.c (error): Add newline to "out of memory" message. I think
+ that its omission probably could cause the message to be lost in
+ the bowels of server.c and never passed to the user.
+
+ * client.c (start_rsh_server): Add comment about "remsh" vs. "rsh".
+
+ * cvs.h: Move copyright notice to top of file.
+
+Sun Mar 2 13:44:36 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * sanity.sh: Use -n when testing whether rsh works.
+
+ * server.c (serve_root): Free path.
+
+Sun Mar 2 13:12:46 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ The following are things that I noticed in the process of trying
+ to track down:
+ can't create temporary directory
+ Unknown error -1
+ FAIL: test 28
+ from nightly testing. I'm not sure that either item explains that
+ message however.
+ * server.c (server): Allocate pending_error_text;
+ print_pending_error will try to free it so
+ pending_error_text = "foo"
+ won't work.
+ (mkdir_p): Don't assume that isdir will leave errno unmolested.
+
+Thu Feb 27 15:29:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * remove.c (cvsremove): When forcing removal in client mode, use
+ start_recursion rather than calling CVS_UNLINK on each argument.
+ (remove_force_fileproc): New static function.
+ * sanity.sh (deep): Add tests deep-rm7 through deep-rm10 for above
+ patch.
+
+ * sanity.sh (death): Enable death-76a0 and death-76a1 tests for
+ remote, since they now work.
+
+Wed Feb 26 16:13:26 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * client.c (add_prune_candidate): Skip adding this directory if
+ it is the same as the first directory already on the list.
+
+Mon Feb 24 21:36:43 1997 Noel Cragg <noel@gargle.rain.org>
+
+ * main.c (lookup_command_attribute): Add the "init" command to the
+ list of commands that don't use the current working directory.
+
+Sun Feb 23 09:54:49 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh (devcom3): Clean up at end of test.
+
+ * sanity.sh (basicb): Add commented out test basicb-8a0, for
+ whether CVS can print an error on bad numeric revision to diff.
+ Commented out until we get around to fixing CVS.
+ * diff.c (diff_file_nodiff): Add comment about this case.
+
+ * fileattr.c (fileattr_read): If a filename is duplicated,
+ continue to ignore subsequent lines but free the node so that we
+ don't leak memory.
+ * sanity.sh (devcom3): New tests devcom3-8 and devcom3-9 test for
+ behavior on duplicated filenames.
+
+ * fileattr.h: Add comment about unrecognized ENT-TYPE and order of
+ lines in fileattr file.
+ * fileattr.c (struct unrecog, unrecog_head): New variables, to
+ record unrecognized lines.
+ (fileattr_startdir): Assert that unrecog_head == NULL.
+ (fileattr_read): Record unrecognized lines in unrecog_head linked
+ list rather than ignoring them.
+ (fileattr_write): Also write out unrecognized lines, if any.
+ * sanity.sh (devcom3): New tests, test for above fix.
+
+ * fileattr.h (fileattr_modify): Fix example in comment.
+
+Sat Feb 22 08:30:27 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh: Add variable username.
+ (basica rdiff multibranch log log2): Use it instead of our own
+ (inconsistent) ways of matching an author name.
+
+ * filesubr.c, root.c, rtag.c, server.c, subr.c, update.c,
+ wrapper.c: Nuke PATH_MAX.
+ * cvs.h, wrapper.c (wrap_fromcvs_process_file): Now returns void
+ (return value had been unused).
+ * cvs.h: Adjust comment to reflect the fact that PATH_MAX is
+ gone, at least from src/*.c (except safe_location, as noted).
+
+22 Feb 1997 patch by Tom Hageman <tom@basil.icce.rug.nl> (4 Jun 1996)
+ updated and commented by Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * update.c (checkout_file): Call unlink_file_dir on backup, not
+ unlink_file.
+
+Fri Feb 21 16:40:03 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * Makefile.in (DISTFILES): Remove NOTES.
+
+ * NOTES: Removed. bcopy->memcpy is done. "static buffers" I
+ assume refers to what is covered by reentrancy text in HACKING.
+ Obstack idea moved to comment in hash.c (at nodecache). Checking
+ system calls for error returns largely done, and isn't a very
+ helpful suggestion unless you know where the bogus calls are
+ anyway. Sizing limits--we're in the progress of removing them
+ (assuming it meant things like PATH_MAX and earlier, already
+ nuked, limits). Removed various items about changes which were
+ done a long time ago (I realize that the ChangeLog's probably
+ aren't reliable that far back, but I'm not convinced anyone cares
+ anymore). CONFIRM_DIRECTORY_ADDS: I assume this is a
+ reference to the #if 0'd code in add_directory which asks for
+ confirmation--a better way of making it harder to accidentally add
+ directories would be to have to add and commit directories like
+ for files. I don't know what FORCE_MESSAGE_ON_ADD meant.
+
+ * rcs.c (RCS_getrevtime): Fix documentation (in particular, the
+ size of the array that DATE must point to, but many other things
+ too).
+ * patch.c, recurse.c, release.c, remove.c, repos.c: Nuke PATH_MAX.
+ (patch_fileproc): Use MAXDATELEN not hardcoded 50.
+
+Sun Feb 16 12:00:44 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * client.c (client_process_import_file): New variable fullname;
+ pass it to send_modified. This finishes the job of untangling the
+ old short_pathname variable into update_dir vs. fullname.
+
+ * client.c (client_process_import_file): Nuke first_time. If
+ toplevel_repos were ever NULL here, the code would dump core in
+ strncmp a few lines down. And client_import_setup ensures
+ toplevel_repos is not NULL.
+
+Sun Feb 16 08:16:48 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * client.c (client_process_import_file): Rename short_pathname to
+ update_dir (to reflect its function) and make sure that it doesn't
+ point to uninitialized memory if repository and toplevel_repos
+ contain the same string.
+
+Sun Feb 16 08:16:48 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * client.c (start_rsh_server): Nuke comment about weirdnesses with
+ pre-1.5 versions of CVS and .bashrc/.cshrc. The remote protocol
+ is interoperable only back to 1.5, and people who need to know are
+ unlikely to see this comment anyway.
+
+Sun Dec 15 13:12:30 1996 Michael Douglass <mikedoug@texas.net>
+ and Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * main.c (cmds): Added an entry for new logout command.
+ (cmd_usage): Added an entry for new logout command.
+ (lookup_command_attribute): Added 'logout' to list of commands
+ that set need_to_crate_root to 1.
+ * login.c, cvs.h (logout): New command for removing entries from
+ the .cvspass file.
+ (logout_usage): Usage information on the logout command.
+
+Wed Feb 12 11:19:42 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * client.c (struct send_data): Fix indentation.
+
+Wed Feb 12 08:48:04 1997 Greg A. Woods <woods@most.weird.com>
+
+ * mkmodules.c (loginfo_contents): add missing comma in
+ initializer statement (caused syntax error on SunOS-4).
+
+Tue Feb 11 21:14:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * commit.c (find_fileproc): If force_ci is set, set the status to
+ T_MODIFIED even if the file hasn't changed.
+ (commit): Pass force_ci to send_files as new force argument.
+ * client.c (struct send_data): Define.
+ (send_fileproc): The callerdat parameter now points to a send_data
+ struct. If force is set, always call send_modified.
+ (send_dirent_proc): The callerdat parameter now points to a
+ send_data struct.
+ (send_files): Add force parameter. Change all callers. Set up a
+ send_data struct and pass it to start_recursion as callerdat.
+ * client.h (send_files): Update declaration.
+ * sanity.sh (basica): Add a simple test for the above patch.
+
+Sun Feb 9 12:58:59 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * tag.c (cvstag), rtag.c (rtag): Pass -f to server if specified in
+ the client. I haven't tried to come up with a test case because
+ the fix seems obvious.
+
+ * import.c (add_rcs_file): Change size of altdate1 and altdate2 to
+ MAXDATELEN.
+ * cvs.h (MAXDATELEN): Fix comments; describe what this is for.
+
+ * diff.c (diff_usage): Document --ifdef and try to briefly say
+ what "rcsdiff-options" means.
+
+ * update.c (update): If update had a nonzero status and we haven't
+ yet tried to fetch unpatchable files, go ahead and try it again.
+ The previous behavior was to quit, which meant that updates would
+ keep failing until you hacked around the problem. Patch and bug
+ report by Ian; comment, ChangeLog entry, and willingness to take
+ the flak if checking it is premature by Jim.
+
+ * server.c (alloc_pending): New function.
+ * server.c: Call it. Fixes places where we had neglected to
+ check for NULL return from malloc.
+
+ * sanity.sh (binwrap): Add test binwrap-0, tests for import.c fix
+ below.
+
+Sun, 9 Feb 1997 (submitted 19 Jul 1996) John Polstra <jdp@polstra.com>
+
+ * import.c (import): Give error if the same tag is specified more
+ than once. The previous behavior was to write an RCS file which
+ had the same tag listed twice, once pointing to each revision,
+ which is not legal.
+
+Sun Feb 9 12:37:09 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * checkin.c (Checkin): Use cvs_output to print message (should
+ make out of order bugs no worse, as it merely substitues a
+ protocol_pipe vs. stderr_pipe race instead of a stdout_pipe
+ vs. stderr_pipe race). Add comment about stdout vs. stderr.
+
+Fri Feb 7 08:29:52 1997 Josef Nelissen <josef.nelissen@munich.ixos.de>
+
+ * server.c (check_command_legal_p): Don't use ANSI-style definition.
+
+Thu Feb 6 10:55:37 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * patch.c (patch): Give a fatal error for -V option (see comment
+ for rationale).
+
+ * diff.c (diff): Also send "options" to server. Pretty much the
+ patch submitted independently by josef.nelissen@munich.ixos.de and
+ Ronald Khoo <ronald@demon.net>.
+
+Wed Feb 5 18:57:14 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * modules.c (do_module): Fix typo in 30 Jan 97 PATH_MAX nuking
+ (free -> free_cwd). Testsuite test 151 gets credit for catching
+ this one.
+
+Mon Feb 3 16:14:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * main.c (lookup_command_attribute): Don't use an ANSI prototype
+ when defining the function.
+
+Fri Jan 31 12:49:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * modules.c (do_module): Actually goto found if is_found is set
+ (fixes thinko in PATH_MAX nuking of 30 Jan 97).
+
+Fri Jan 31 12:49:02 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * sanity.sh: Add modules3 and big to list of tests to run
+ by default; they were omitted by accident.
+
+Thu Jan 30 11:46:33 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * logmsg.c, main.c, mkmodules.c, modules.c, parseinfo.c, patch.c:
+ Nuke more PATH_MAX.
+
+ * server.c (server_updated): After we send Created or
+ Update-existing for a file, mark it as unchanged, in case we
+ process it again.
+ * sanity.sh (modules3): New tests, test for above fix.
+
+ * logmsg.c (do_verify): Error return from fopen is NULL, not -1.
+ Pass errno to error().
+
+ * login.c [_CRAY]: Don't declare getpass.
+
+Mon Jan 27 17:25:27 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * import.c (process_import_file): Fix freeing of rcs (Don't free
+ it before we are done using it, and don't free it twice).
+
+ * modules.c (cat_module): Allocate line right before we use
+ it. The previous code was wrong because the length of the
+ s_h->rest changes between the time we allocate line and the time we
+ sprintf s_h->rest into it.
+
+Sun Jan 26 21:58:16 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * expand_path.c (expand_path): Revise to call expand_string as
+ needed. Nuke PATH_MAX.
+ * find_names.c (find_dirs): Likewise.
+ * import.c, lock.c: Nuke more PATH_MAX.
+
+ * server.c (mkdir_p): Set retval to 0 at start of function.
+ Previously it had been uninitialized for some cases. Thanks are
+ due to nightly testing for catching this one.
+
+Sat Jan 25 21:34:19 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * subr.c, cvs.h (expand_string): New function.
+ * rcs.c (getrcskey, getrcsrev): Call it. This greatly reduces the
+ number of calls to realloc if there is a very large file in the
+ RCS file. Credit goes to Mike Heath <mike@pswtech.com> for
+ pointing out the problem and the basic solution (MIN_INCR,
+ MAX_INCR); I adapted it into the separate function expand_string.
+ * sanity.sh (big): New test helps insure this hasn't broken
+ anything obvious.
+
+Wed Jan 22 10:06:13 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+
+ * status.c (status_fileproc): Change message which is printed for
+ T_MODIFIED and ts_conflict set, so that it doesn't say "unresolved
+ confict". This message occurs whether the conflict is resolved or
+ not.
+ * sanity.sh (conflicts): Add tests conflicts-status-* to test
+ output of "cvs status" in the context of conflicts. Tests for
+ above fix.
+
+ * rtag.c (rtag): Send -n if run_module_prog is NOT true.
+
Thu Jan 16 00:06:00 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
+ * version.c: Change version number to 1.9.3.
+
* version.c: Version 1.9.2.
Wed Jan 15 09:14:38 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
diff --git a/gnu/usr.bin/cvs/src/Makefile.in b/gnu/usr.bin/cvs/src/Makefile.in
index 9b9621df09f..e2dbe8d8db3 100644
--- a/gnu/usr.bin/cvs/src/Makefile.in
+++ b/gnu/usr.bin/cvs/src/Makefile.in
@@ -61,7 +61,6 @@ TAGFILES = $(HEADERS) options.h.in $(SOURCES)
DISTFILES = .cvsignore Makefile.in \
ChangeLog ChangeLog-96 ChangeLog-9395 ChangeLog-9194 \
- NOTES \
sanity.sh cvsbug.sh $(TAGFILES) build_src.com
PROGS = cvs cvsbug
diff --git a/gnu/usr.bin/cvs/src/add.c b/gnu/usr.bin/cvs/src/add.c
index fadc48bf3a0..28faecc7839 100644
--- a/gnu/usr.bin/cvs/src/add.c
+++ b/gnu/usr.bin/cvs/src/add.c
@@ -39,6 +39,47 @@ static const char *const add_usage[] =
NULL
};
+static char *combine_dir PROTO ((char *, char *));
+
+/* Given a directory DIR and a subdirectory within it, SUBDIR, combine
+ the two into a new directory name. Returns a newly malloc'd string.
+ For now this is a fairly simple affair, but perhaps it will want
+ to have grander ambitions in the context of VMS or others (or perhaps
+ not, perhaps that should all be hidden inside CVS_FOPEN and libc and so
+ on, and CVS should just see foo/bar/baz style pathnames). */
+static char *
+combine_dir (dir, subdir)
+ char *dir;
+ char *subdir;
+{
+ char *retval;
+ size_t dir_len;
+
+ dir_len = strlen (dir);
+ retval = xmalloc (dir_len + strlen (subdir) + 10);
+ if (dir_len >= 2
+ && dir[dir_len - 1] == '.'
+ && ISDIRSEP (dir[dir_len - 2]))
+ {
+ /* The dir name has an extraneous "." at the end.
+ I'm not completely sure that this is the best place
+ to strip it off--it is possible that Name_Repository
+ should do so, or it shouldn't be in the CVS/Repository
+ file in the first place. Fixing it here seems like
+ a safe, small change, but I'm not sure it catches
+ all the cases. */
+ strncpy (retval, dir, dir_len - 2);
+ retval[dir_len - 2] = '\0';
+ }
+ else
+ {
+ strcpy (retval, dir);
+ }
+ strcat (retval, "/");
+ strcat (retval, subdir);
+ return retval;
+}
+
int
add (argc, argv)
int argc;
@@ -106,14 +147,13 @@ add (argc, argv)
{
char *tag;
char *date;
- char *rcsdir = xmalloc (strlen (repository)
- + strlen (argv[i]) + 10);
+ char *rcsdir;
/* before we do anything else, see if we have any
per-directory tags */
ParseTag (&tag, &date);
- sprintf (rcsdir, "%s/%s", repository, argv[i]);
+ rcsdir = combine_dir (repository, argv[i]);
strip_trailing_slashes (argv[i]);
@@ -139,7 +179,7 @@ add (argc, argv)
}
}
send_file_names (argc, argv, SEND_EXPAND_WILD);
- send_files (argc, argv, 0, 0, 1);
+ send_files (argc, argv, 0, 0, 1, 0);
send_to_server ("add\012", 0);
return get_responses_and_close ();
}
@@ -440,8 +480,7 @@ add_directory (repository, entries, dir)
goto out;
}
- rcsdir = xmalloc (strlen (repository) + strlen (dir) + 10);
- (void) sprintf (rcsdir, "%s/%s", repository, dir);
+ rcsdir = combine_dir (repository, dir);
if (isfile (rcsdir) && !isdir (rcsdir))
{
error (0, 0, "%s is not a directory; %s not added", rcsdir, dir);
@@ -471,20 +510,13 @@ add_directory (repository, entries, dir)
List *ulist;
struct logfile_info *li;
-#if 0
- char line[MAXLINELEN];
-
- (void) printf ("Add directory %s to the repository (y/n) [n] ? ",
- rcsdir);
- (void) fflush (stdout);
- clearerr (stdin);
- if (fgets (line, sizeof (line), stdin) == NULL ||
- (line[0] != 'y' && line[0] != 'Y'))
- {
- error (0, 0, "directory %s not added", rcsdir);
- goto out;
- }
-#endif
+ /* There used to be some code here which would prompt for
+ whether to add the directory. The details of that code had
+ bitrotted, but more to the point it can't work
+ client/server, doesn't ask in the right way for GUIs, etc.
+ A better way of making it harder to accidentally add
+ directories would be to have to add and commit directories
+ like for files. The code was #if 0'd at least since CVS 1.5. */
if (!noexec)
{
@@ -562,7 +594,7 @@ build_entry (repository, user, options, message, entries, tag)
char *tag;
{
char *fname;
- char line[MAXLINELEN];
+ char *line;
FILE *fp;
if (noexec)
@@ -587,7 +619,9 @@ build_entry (repository, user, options, message, entries, tag)
* without needing to clean anything up (well, we could clean up the
* ,t file, but who cares).
*/
+ line = xmalloc (strlen (user) + 20);
(void) sprintf (line, "Initial %s", user);
Register (entries, user, "0", line, options, tag, (char *) 0, (char *) 0);
+ free (line);
return (0);
}
diff --git a/gnu/usr.bin/cvs/src/admin.c b/gnu/usr.bin/cvs/src/admin.c
index c3dd0add1f3..763eb981d29 100644
--- a/gnu/usr.bin/cvs/src/admin.c
+++ b/gnu/usr.bin/cvs/src/admin.c
@@ -38,6 +38,7 @@ admin (argc, argv)
int err;
#ifdef CVS_ADMIN_GROUP
struct group *grp;
+ struct group *getgrnam();
#endif
if (argc <= 1)
usage (admin_usage);
@@ -77,8 +78,6 @@ admin (argc, argv)
av = argv + 1;
argv += ac;
ac--;
- if (ac == 0 || argc == 0)
- usage (admin_usage);
#ifdef CLIENT_SUPPORT
if (client_active)
@@ -97,7 +96,7 @@ admin (argc, argv)
/* FIXME: We shouldn't have to send current files, but I'm not sure
whether it works. So send the files --
it's slower but it works. */
- send_files (argc, argv, 0, 0, 0);
+ send_files (argc, argv, 0, 0, 0, 0);
send_to_server ("admin\012", 0);
return get_responses_and_close ();
}
diff --git a/gnu/usr.bin/cvs/src/checkin.c b/gnu/usr.bin/cvs/src/checkin.c
index 4f54a8bc333..c5b5d073f16 100644
--- a/gnu/usr.bin/cvs/src/checkin.c
+++ b/gnu/usr.bin/cvs/src/checkin.c
@@ -34,7 +34,14 @@ Checkin (type, finfo, rcs, rev, tag, options, message)
int set_time;
char *tocvsPath = NULL;
- (void) printf ("Checking in %s;\n", finfo->fullname);
+ /* Hmm. This message goes to stdout and the "foo,v <-- foo"
+ message from "ci" goes to stderr. This doesn't make a whole
+ lot of sense, but making everything go to stdout can only be
+ gracefully achieved once RCS_checkin is librarified. */
+ cvs_output ("Checking in ", 0);
+ cvs_output (finfo->fullname, 0);
+ cvs_output (";\n", 0);
+
fname = xmalloc (strlen (finfo->file) + 80);
(void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
diff --git a/gnu/usr.bin/cvs/src/client.c b/gnu/usr.bin/cvs/src/client.c
index 2a2cfb90bb6..61b3d620258 100644
--- a/gnu/usr.bin/cvs/src/client.c
+++ b/gnu/usr.bin/cvs/src/client.c
@@ -1421,6 +1421,24 @@ update_entries (data_arg, ent_list, short_pathname, filename)
char buf[8192];
+ /* This error might be confusing; it isn't really clear to
+ the user what to do about it. Keep in mind that it has
+ several causes: (1) something/someone creates the file
+ during the time that CVS is running, (2) the repository
+ has two files whose names clash for the client because
+ of case-insensitivity or similar causes, (3) a special
+ case of this is that a file gets renamed for example
+ from a.c to A.C. A "cvs update" on a case-insensitive
+ client will get this error. Repeating the update takes
+ care of the problem, but is it clear to the user what
+ is going on and what to do about it?, (4) the client
+ has a file which the server doesn't know about (e.g. "?
+ foo" file), and that name clashes with a file the
+ server does know about, (5) classify.c will print the same
+ message for other reasons.
+
+ I hope the above paragraph makes it clear that making this
+ clearer is not a one-line fix. */
error (0, 0, "move away %s; it is in the way", short_pathname);
discard_file_and_return:
@@ -2160,7 +2178,9 @@ add_prune_candidate (dir)
{
struct save_dir *p;
- if (dir[0] == '.' && dir[1] == '\0')
+ if ((dir[0] == '.' && dir[1] == '\0')
+ || (prune_candidates != NULL
+ && strcmp (dir, prune_candidates->dir) == 0))
return;
p = (struct save_dir *) xmalloc (sizeof (struct save_dir));
p->dir = xstrdup (dir);
@@ -2554,7 +2574,7 @@ client_send_expansions (local, where, build_dirs)
{
argv[0] = where ? where : modules_vector[i];
if (isfile (argv[0]))
- send_files (1, argv, local, 0, build_dirs);
+ send_files (1, argv, local, 0, build_dirs, 0);
}
send_a_repository ("", CVSroot_directory, "");
}
@@ -3668,15 +3688,30 @@ start_rsh_server (tofdp, fromfdp)
char *rsh_argv[10];
if (!cvs_rsh)
+ /* People sometimes suggest or assume that this should default
+ to "remsh" on systems like HPUX in which that is the
+ system-supplied name for the rsh program. However, that
+ causes various problems (keep in mind that systems such as
+ HPUX might have non-system-supplied versions of "rsh", like
+ a Kerberized one, which one might want to use). If we
+ based the name on what is found in the PATH of the person
+ who runs configure, that would make it harder to
+ consistently produce the same result in the face of
+ different people producing binary distributions. If we
+ based it on "remsh" always being the default for HPUX
+ (e.g. based on uname), that might be slightly better but
+ would require us to keep track of what the defaults are for
+ each system type, and probably would cope poorly if the
+ existence of remsh or rsh varies from OS version to OS
+ version. Therefore, it seems best to have the default
+ remain "rsh", and tell HPUX users to specify remsh, for
+ example in CVS_RSH or other such mechanisms to be devised,
+ if that is what they want (the manual already tells them
+ that). */
cvs_rsh = "rsh";
if (!cvs_server)
cvs_server = "cvs";
- /* If you are running a very old (Nov 3, 1994, before 1.5)
- * version of the server, you need to make sure that your .bashrc
- * on the server machine does not set CVSROOT to something
- * containing a colon (or better yet, upgrade the server). */
-
/* The command line starts out with rsh. */
rsh_argv[i++] = cvs_rsh;
@@ -4048,6 +4083,16 @@ send_modified (file, short_pathname, vers)
free (mode_string);
}
+/* The address of an instance of this structure is passed to
+ send_fileproc, send_filesdoneproc, and send_direntproc, as the
+ callerdat parameter. */
+
+struct send_data
+{
+ int build_dirs;
+ int force;
+};
+
static int send_fileproc PROTO ((void *callerdat, struct file_info *finfo));
/* Deal with one file. */
@@ -4056,6 +4101,7 @@ send_fileproc (callerdat, finfo)
void *callerdat;
struct file_info *finfo;
{
+ struct send_data *args = (struct send_data *) callerdat;
Vers_TS *vers;
struct file_info xfinfo;
/* File name to actually use. Might differ in case from
@@ -4117,6 +4163,7 @@ send_fileproc (callerdat, finfo)
just happen. */
}
else if (vers->ts_rcs == NULL
+ || args->force
|| strcmp (vers->ts_user, vers->ts_rcs) != 0)
{
send_modified (filename, finfo->fullname, vers);
@@ -4203,7 +4250,7 @@ send_dirent_proc (callerdat, dir, repository, update_dir, entries)
char *update_dir;
List *entries;
{
- int build_dirs = *(int *) callerdat;
+ struct send_data *args = (struct send_data *) callerdat;
int dir_exists;
char *cvsadm_name;
char *cvsadm_repos_name;
@@ -4256,7 +4303,7 @@ send_dirent_proc (callerdat, dir, repository, update_dir, entries)
new directories (build_dirs is true). Otherwise, CVS may
see a D line in an Entries file, and recreate a directory
which the user removed by hand. */
- if (dir_exists || build_dirs)
+ if (dir_exists || args->build_dirs)
send_a_repository (dir, repository, update_dir);
}
free (cvsadm_repos_name);
@@ -4442,18 +4489,21 @@ send_file_names (argc, argv, flags)
* Send Repository, Modified and Entry. argc and argv contain only
* the files to operate on (or empty for everything), not options.
* local is nonzero if we should not recurse (-l option). build_dirs
- * is nonzero if nonexistent directories should be sent. Also sends
- * Argument lines for argc and argv, so should be called after options
- * are sent.
+ * is nonzero if nonexistent directories should be sent. force is
+ * nonzero if we should send unmodified files to the server as though
+ * they were modified. Also sends Argument lines for argc and argv,
+ * so should be called after options are sent.
*/
void
-send_files (argc, argv, local, aflag, build_dirs)
+send_files (argc, argv, local, aflag, build_dirs, force)
int argc;
char **argv;
int local;
int aflag;
int build_dirs;
+ int force;
{
+ struct send_data args;
int err;
/*
@@ -4461,9 +4511,11 @@ send_files (argc, argv, local, aflag, build_dirs)
* But we don't actually use it, so I don't think it matters what we pass
* for aflag here.
*/
+ args.build_dirs = build_dirs;
+ args.force = force;
err = start_recursion
(send_fileproc, send_filesdoneproc,
- send_dirent_proc, (DIRLEAVEPROC)NULL, (void *) &build_dirs,
+ send_dirent_proc, (DIRLEAVEPROC)NULL, (void *) &args,
argc, argv, local, W_LOCAL, aflag, 0, (char *)NULL, 0);
if (err)
error_exit ();
@@ -4499,28 +4551,34 @@ client_process_import_file (message, vfile, vtag, targc, targv, repository)
char *targv[];
char *repository;
{
- char *short_pathname;
- int first_time;
-
- /* FIXME: I think this is always false now that we call
- client_import_setup at the start. */
-
- first_time = toplevel_repos == NULL;
+ char *update_dir;
+ char *fullname;
- if (first_time)
- send_a_repository ("", repository, "");
+ assert (toplevel_repos != NULL);
if (strncmp (repository, toplevel_repos, strlen (toplevel_repos)) != 0)
error (1, 0,
"internal error: pathname `%s' doesn't specify file in `%s'",
repository, toplevel_repos);
- short_pathname = repository + strlen (toplevel_repos) + 1;
- if (!first_time)
+ if (strcmp (repository, toplevel_repos) == 0)
+ {
+ update_dir = "";
+ fullname = xstrdup (vfile);
+ }
+ else
{
- send_a_repository ("", repository, short_pathname);
+ update_dir = repository + strlen (toplevel_repos) + 1;
+
+ fullname = xmalloc (strlen (vfile) + strlen (update_dir) + 10);
+ strcpy (fullname, update_dir);
+ strcat (fullname, "/");
+ strcat (fullname, vfile);
}
- send_modified (vfile, short_pathname, NULL);
+
+ send_a_repository ("", repository, update_dir);
+ send_modified (vfile, fullname, NULL);
+ free (fullname);
return 0;
}
diff --git a/gnu/usr.bin/cvs/src/client.h b/gnu/usr.bin/cvs/src/client.h
index 10e1759f049..d313c965e6e 100644
--- a/gnu/usr.bin/cvs/src/client.h
+++ b/gnu/usr.bin/cvs/src/client.h
@@ -83,7 +83,7 @@ send_file_names PROTO((int argc, char **argv, unsigned int flags));
*/
void
send_files PROTO((int argc, char **argv, int local, int aflag,
- int build_dirs));
+ int build_dirs, int force));
/* Send an argument to the remote server. */
void
diff --git a/gnu/usr.bin/cvs/src/diff.c b/gnu/usr.bin/cvs/src/diff.c
index 7163c3e7481..24bc7b60d9c 100644
--- a/gnu/usr.bin/cvs/src/diff.c
+++ b/gnu/usr.bin/cvs/src/diff.c
@@ -69,6 +69,9 @@ static const char *const diff_usage[] =
"\t-N\tinclude diffs for added and removed files.\n",
"\t-r rev1\tDiff revision for rev1 against working file.\n",
"\t-r rev2\tDiff rev1/date1 against rev2.\n",
+ "\t--ifdef=arg\tOutput diffs in ifdef format.\n",
+ "(consult the documentation for your diff program for rcsdiff-options.\n",
+ "The most popular is -c for context diffs but there are many more).\n",
NULL
};
@@ -294,6 +297,8 @@ diff (argc, argv)
if (empty_files)
send_arg("-N");
send_option_string (opts);
+ if (options[0] != '\0')
+ send_arg (options);
if (diff_rev1)
option_with_arg ("-r", diff_rev1);
if (diff_date1)
@@ -312,7 +317,7 @@ diff (argc, argv)
/* Send the current files unless diffing two revs from the archive */
if (diff_rev2 == NULL && diff_date2 == NULL)
#endif
- send_files (argc, argv, local, 0, 0);
+ send_files (argc, argv, local, 0, 0, 0);
send_to_server ("diff\012", 0);
err = get_responses_and_close ();
@@ -776,6 +781,10 @@ diff_file_nodiff (finfo, vers, empty_file)
true, treat this as an added file. Otherwise, warn
about the missing tag. */
if (use_rev2 == NULL)
+ /* At least in the case where DIFF_REV1 and DIFF_REV2
+ are both numeric, we should be returning some kind
+ of error (see basicb-8a0 in testsuite). The symbolic
+ case may be more complicated. */
return DIFF_SAME;
else if (empty_files)
return DIFF_ADDED;
diff --git a/gnu/usr.bin/cvs/src/edit.c b/gnu/usr.bin/cvs/src/edit.c
index ae7964d9645..7593da43d20 100644
--- a/gnu/usr.bin/cvs/src/edit.c
+++ b/gnu/usr.bin/cvs/src/edit.c
@@ -90,7 +90,7 @@ watch_onoff (argc, argv)
/* FIXME: We shouldn't have to send current files, but I'm not sure
whether it works. So send the files --
it's slower but it works. */
- send_files (argc, argv, local, 0, 0);
+ send_files (argc, argv, local, 0, 0, 0);
send_to_server (turning_on ? "watch-on\012" : "watch-off\012", 0);
return get_responses_and_close ();
}
@@ -1002,7 +1002,7 @@ editors (argc, argv)
/* FIXME: We shouldn't have to send current files, but I'm not sure
whether it works. So send the files --
it's slower but it works. */
- send_files (argc, argv, local, 0, 0);
+ send_files (argc, argv, local, 0, 0, 0);
send_to_server ("editors\012", 0);
return get_responses_and_close ();
}
diff --git a/gnu/usr.bin/cvs/src/error.c b/gnu/usr.bin/cvs/src/error.c
index a772cca0e8f..0ed7eb24d37 100644
--- a/gnu/usr.bin/cvs/src/error.c
+++ b/gnu/usr.bin/cvs/src/error.c
@@ -149,7 +149,7 @@ error (status, errnum, message, va_alist)
free (mess);
}
}
- cvs_outerr (entire ? entire : "out of memory", 0);
+ cvs_outerr (entire ? entire : "out of memory\n", 0);
if (entire != NULL)
free (entire);
}
diff --git a/gnu/usr.bin/cvs/src/expand_path.c b/gnu/usr.bin/cvs/src/expand_path.c
index ab093512955..7d0bc39e5ab 100644
--- a/gnu/usr.bin/cvs/src/expand_path.c
+++ b/gnu/usr.bin/cvs/src/expand_path.c
@@ -95,40 +95,82 @@ expand_path (name, file, line)
{
char *s;
char *d;
- /* FIXME: arbitrary limit. */
- char mybuf[PATH_MAX];
- char buf[PATH_MAX];
+
+ char *mybuf = NULL;
+ size_t mybuf_size = 0;
+ char *buf = NULL;
+ size_t buf_size = 0;
+
+ size_t doff;
+
char *result;
+
+ /* Sorry this routine is so ugly; it is a head-on collision
+ between the `traditional' unix *d++ style and the need to
+ dynamically allocate. It would be much cleaner (and probably
+ faster, not that this is a bottleneck for CVS) with more use of
+ strcpy & friends, but I haven't taken the effort to rewrite it
+ thusly. */
+
+ /* First copy from NAME to MYBUF, expanding $<foo> as we go. */
s = name;
d = mybuf;
+ doff = d - mybuf;
+ expand_string (&mybuf, &mybuf_size, doff + 1);
+ d = mybuf + doff;
while ((*d++ = *s))
+ {
if (*s++ == '$')
{
char *p = d;
char *e;
int flag = (*s == '{');
+ doff = d - mybuf;
+ expand_string (&mybuf, &mybuf_size, doff + 1);
+ d = mybuf + doff;
for (; (*d++ = *s); s++)
+ {
if (flag
? *s =='}'
: isalnum (*s) == 0 && *s != '_')
break;
- *--d = 0;
+ doff = d - mybuf;
+ expand_string (&mybuf, &mybuf_size, doff + 1);
+ d = mybuf + doff;
+ }
+ *--d = '\0';
e = expand_variable (&p[flag], file, line);
if (e)
{
+ doff = d - mybuf;
+ expand_string (&mybuf, &mybuf_size, doff + 1);
+ d = mybuf + doff;
for (d = &p[-1]; (*d++ = *e++);)
- ;
+ {
+ doff = d - mybuf;
+ expand_string (&mybuf, &mybuf_size, doff + 1);
+ d = mybuf + doff;
+ }
--d;
if (flag && *s)
s++;
}
else
/* expand_variable has already printed an error message. */
- return NULL;
+ goto error_exit;
}
- *d = 0;
+ doff = d - mybuf;
+ expand_string (&mybuf, &mybuf_size, doff + 1);
+ d = mybuf + doff;
+ }
+ doff = d - mybuf;
+ expand_string (&mybuf, &mybuf_size, doff + 1);
+ d = mybuf + doff;
+ *d = '\0';
+
+ /* Then copy from MYBUF to BUF, expanding ~. */
s = mybuf;
d = buf;
/* If you don't want ~username ~/ to be expanded simply remove
@@ -158,8 +200,15 @@ expand_path (name, file, line)
}
t = ps->pw_dir;
}
+ doff = d - buf;
+ expand_string (&buf, &buf_size, doff + 1);
+ d = buf + doff;
while ((*d++ = *t++))
- ;
+ {
+ doff = d - buf;
+ expand_string (&buf, &buf_size, doff + 1);
+ d = buf + doff;
+ }
--d;
if (*p == 0)
*p = '/'; /* always add / */
@@ -168,12 +217,35 @@ expand_path (name, file, line)
else
--s;
/* Kill up to here */
+ doff = d - buf;
+ expand_string (&buf, &buf_size, doff + 1);
+ d = buf + doff;
while ((*d++ = *s++))
- ;
- *d=0;
- result = xmalloc (sizeof(char) * strlen(buf)+1);
- strcpy (result, buf);
+ {
+ doff = d - buf;
+ expand_string (&buf, &buf_size, doff + 1);
+ d = buf + doff;
+ }
+ doff = d - buf;
+ expand_string (&buf, &buf_size, doff + 1);
+ d = buf + doff;
+ *d = '\0';
+
+ /* OK, buf contains the value we want to return. Clean up and return
+ it. */
+ free (mybuf);
+ /* Save a little memory with xstrdup; buf will tend to allocate
+ more than it needs to. */
+ result = xstrdup (buf);
+ free (buf);
return result;
+
+ error_exit:
+ if (mybuf != NULL)
+ free (mybuf);
+ if (buf != NULL)
+ free (buf);
+ return NULL;
}
static char *
diff --git a/gnu/usr.bin/cvs/src/fileattr.c b/gnu/usr.bin/cvs/src/fileattr.c
index c64596bfe87..eda7753492a 100644
--- a/gnu/usr.bin/cvs/src/fileattr.c
+++ b/gnu/usr.bin/cvs/src/fileattr.c
@@ -31,6 +31,14 @@ static int attr_read_attempted;
/* Have the in-memory attributes been modified since we read them? */
static int attrs_modified;
+/* More in-memory attributes: linked list of unrecognized
+ fileattr lines. We pass these on unchanged. */
+struct unrecog {
+ char *line;
+ struct unrecog *next;
+};
+static struct unrecog *unrecog_head;
+
/* Note that if noone calls fileattr_get, this is very cheap. No stat(),
no open(), no nothing. */
void
@@ -41,6 +49,7 @@ fileattr_startdir (repos)
fileattr_stored_repos = xstrdup (repos);
assert (attrlist == NULL);
attr_read_attempted = 0;
+ assert (unrecog_head == NULL);
}
static void
@@ -108,7 +117,12 @@ fileattr_read ()
newnode->delproc = fileattr_delproc;
newnode->key = xstrdup (line + 1);
newnode->data = xstrdup (p);
- addnode (attrlist, newnode);
+ if (addnode (attrlist, newnode) != 0)
+ /* If the same filename appears twice in the file, discard
+ any line other than the first for that filename. This
+ is the way that CVS has behaved since file attributes
+ were first introduced. */
+ free (newnode);
}
else if (line[0] == 'D')
{
@@ -119,7 +133,17 @@ fileattr_read ()
++p;
fileattr_default_attrs = xstrdup (p);
}
- /* else just ignore the line, for future expansion. */
+ else
+ {
+ /* Unrecognized type, we want to just preserve the line without
+ changing it, for future expansion. */
+ struct unrecog *new;
+
+ new = (struct unrecog *) xmalloc (sizeof (struct unrecog));
+ new->line = xstrdup (line);
+ new->next = unrecog_head;
+ unrecog_head = new;
+ }
}
if (ferror (fp))
error (0, errno, "cannot read %s", fname);
@@ -421,7 +445,9 @@ fileattr_write ()
strcat (fname, "/");
strcat (fname, CVSREP_FILEATTR);
- if (list_isempty (attrlist) && fileattr_default_attrs == NULL)
+ if (list_isempty (attrlist)
+ && fileattr_default_attrs == NULL
+ && unrecog_head == NULL)
{
/* There are no attributes. */
if (unlink_file (fname) < 0)
@@ -489,13 +515,32 @@ fileattr_write ()
}
}
(void) umask (omask);
+
+ /* First write the "F" attributes. */
walklist (attrlist, writeattr_proc, fp);
+
+ /* Then the "D" attribute. */
if (fileattr_default_attrs != NULL)
{
fputs ("D\t", fp);
fputs (fileattr_default_attrs, fp);
fputs ("\012", fp);
}
+
+ /* Then any other attributes. */
+ while (unrecog_head != NULL)
+ {
+ struct unrecog *p;
+
+ p = unrecog_head;
+ fputs (p->line, fp);
+ fputs ("\012", fp);
+
+ unrecog_head = p->next;
+ free (p->line);
+ free (p);
+ }
+
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", fname);
attrs_modified = 0;
diff --git a/gnu/usr.bin/cvs/src/fileattr.h b/gnu/usr.bin/cvs/src/fileattr.h
index 0ca7eae1515..c6362afa993 100644
--- a/gnu/usr.bin/cvs/src/fileattr.h
+++ b/gnu/usr.bin/cvs/src/fileattr.h
@@ -23,6 +23,13 @@
ENT-TYPE is 'D', and FILENAME empty, to specify default attributes
to be used for newly added files.
+ 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.
+
+ 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
@@ -91,7 +98,7 @@ extern char *fileattr_get0 PROTO ((const char *filename,
=> "abc=val;def=v2"
fileattr_modify ("abc=v1;def=v2", "def", "val", '=', ';'))
=> "abc=v1;def=val"
- fileattr_modify ("abc=v1;def=v2", "xxx", "val"))
+ fileattr_modify ("abc=v1;def=v2", "xxx", "val", '=', ';'))
=> "abc=v1;def=v2;xxx=val"
fileattr_modify ("abc=v1;def=v2;ghi=v3", "def", "val", '=', ';'))
=> "abc=v1;def=val;ghi=v3"
diff --git a/gnu/usr.bin/cvs/src/filesubr.c b/gnu/usr.bin/cvs/src/filesubr.c
index 03d8cdce47f..b3142545f9b 100644
--- a/gnu/usr.bin/cvs/src/filesubr.c
+++ b/gnu/usr.bin/cvs/src/filesubr.c
@@ -463,7 +463,6 @@ deep_remove_dir (path)
{
DIR *dirp;
struct dirent *dp;
- char buf[PATH_MAX];
if (rmdir (path) != 0)
{
@@ -482,10 +481,13 @@ deep_remove_dir (path)
while ((dp = readdir (dirp)) != NULL)
{
+ char *buf;
+
if (strcmp (dp->d_name, ".") == 0 ||
strcmp (dp->d_name, "..") == 0)
continue;
+ buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5);
sprintf (buf, "%s/%s", path, dp->d_name);
/* See comment in unlink_file_dir explanation of why we use
@@ -496,6 +498,7 @@ deep_remove_dir (path)
if (deep_remove_dir(buf))
{
closedir(dirp);
+ free (buf);
return -1;
}
}
@@ -504,9 +507,11 @@ deep_remove_dir (path)
if (unlink (buf) != 0)
{
closedir(dirp);
+ free (buf);
return -1;
}
}
+ free (buf);
}
closedir (dirp);
return rmdir (path);
diff --git a/gnu/usr.bin/cvs/src/find_names.c b/gnu/usr.bin/cvs/src/find_names.c
index 8bfce8c75b7..a7a91bbfd3e 100644
--- a/gnu/usr.bin/cvs/src/find_names.c
+++ b/gnu/usr.bin/cvs/src/find_names.c
@@ -288,7 +288,8 @@ find_dirs (dir, list, checkadm, entries)
List *entries;
{
Node *p;
- char tmp[PATH_MAX];
+ char *tmp = NULL;
+ size_t tmp_size = 0;
struct dirent *dp;
DIR *dirp;
@@ -322,6 +323,9 @@ find_dirs (dir, list, checkadm, entries)
if (fnmatch (RCSPAT, dp->d_name, 0) == 0)
continue;
+ expand_string (&tmp,
+ &tmp_size,
+ strlen (dir) + strlen (dp->d_name) + 10);
sprintf (tmp, "%s/%s", dir, dp->d_name);
if (!isdir (tmp))
continue;
@@ -341,9 +345,8 @@ find_dirs (dir, list, checkadm, entries)
if (dp->d_type == DT_LNK)
continue;
#endif
- /* FIXME: tmp is not set here, or doesn't seem to be.
- This would appear to just be a mistake... Needs more
- investigation to be sure... */
+ /* Note that we only get here if we already set tmp
+ above. */
if (islink (tmp))
continue;
#ifdef DT_DIR
@@ -351,6 +354,10 @@ find_dirs (dir, list, checkadm, entries)
#endif
/* check for new style */
+ expand_string (&tmp,
+ &tmp_size,
+ (strlen (dir) + strlen (dp->d_name)
+ + sizeof (CVSADM) + 10));
(void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM);
if (!isdir (tmp))
continue;
@@ -364,5 +371,7 @@ find_dirs (dir, list, checkadm, entries)
freenode (p);
}
(void) closedir (dirp);
+ if (tmp != NULL)
+ free (tmp);
return (0);
}
diff --git a/gnu/usr.bin/cvs/src/hash.c b/gnu/usr.bin/cvs/src/hash.c
index e9f49355f5b..60998d108f9 100644
--- a/gnu/usr.bin/cvs/src/hash.c
+++ b/gnu/usr.bin/cvs/src/hash.c
@@ -10,7 +10,10 @@
#include "cvs.h"
#include <assert.h>
-/* global caches */
+/* Global caches. The idea is that we maintain a linked list of "free"d
+ nodes or lists, and get new items from there. It has been suggested
+ to use an obstack instead, but off the top of my head, I'm not sure
+ that would gain enough to be worth worrying about. */
static List *listcache = NULL;
static Node *nodecache = NULL;
diff --git a/gnu/usr.bin/cvs/src/history.c b/gnu/usr.bin/cvs/src/history.c
index ac55dad6377..1d19418bc8a 100644
--- a/gnu/usr.bin/cvs/src/history.c
+++ b/gnu/usr.bin/cvs/src/history.c
@@ -238,13 +238,24 @@ static char *tz_name = "+0000";
static char tz_name[] = "LT";
#endif
+/* -r, -t, or -b options, malloc'd. These are "" if the option in
+ question is not specified or is overridden by another option. The
+ main reason for using "" rather than NULL is historical. Together
+ with since_date, these are a mutually exclusive set; one overrides the
+ others. */
+static char *since_rev;
+static char *since_tag;
+static char *backto;
+/* -D option, or 0 if not specified. */
static time_t since_date;
-static char since_rev[20]; /* Maxrev ~= 99.99.99.999 */
-static char since_tag[64];
+
static struct hrec *last_since_tag;
-static char backto[128];
static struct hrec *last_backto;
-static char rec_types[20];
+
+/* Record types to look for, malloc'd. Probably could be statically
+ allocated, but only if we wanted to check for duplicates more than
+ we do. */
+static char *rec_types;
static int hrec_count;
static int hrec_max;
@@ -374,6 +385,10 @@ history (argc, argv)
if (argc == -1)
usage (history_usg);
+ since_rev = xstrdup ("");
+ since_tag = xstrdup ("");
+ backto = xstrdup ("");
+ rec_types = xstrdup ("");
optind = 1;
while ((c = getopt (argc, argv, "Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:")) != -1)
{
@@ -393,7 +408,8 @@ history (argc, argv)
case 'e':
report_count++;
extract++;
- (void) strcpy (rec_types, ALL_REC_TYPES);
+ free (rec_types);
+ rec_types = xstrdup (ALL_REC_TYPES);
break;
case 'l': /* Find Last file record */
last_entry = 1;
@@ -423,13 +439,8 @@ history (argc, argv)
*since_rev = *since_tag = '\0';
since_date = 0;
}
- if (strlen (optarg) >= sizeof (backto))
- {
- error (0, 0, "backto truncated to %d bytes",
- (int) sizeof (backto) - 1);
- optarg[sizeof (backto) - 1] = '\0';
- }
- (void) strcpy (backto, optarg);
+ free (backto);
+ backto = xstrdup (optarg);
break;
case 'f': /* For specified file */
save_file ("", optarg, (char *) NULL);
@@ -450,7 +461,8 @@ history (argc, argv)
*since_tag = *backto = '\0';
since_date = 0;
}
- (void) strcpy (since_rev, optarg);
+ free (since_rev);
+ since_rev = xstrdup (optarg);
break;
case 't': /* Since specified Tag/Rev */
if (since_date || *since_rev || *backto)
@@ -459,7 +471,8 @@ history (argc, argv)
*since_rev = *backto = '\0';
since_date = 0;
}
- (void) strcpy (since_tag, optarg); /* tag */
+ free (since_tag);
+ since_tag = xstrdup (optarg);
break;
case 'u': /* For specified username */
save_user (optarg);
@@ -474,7 +487,8 @@ history (argc, argv)
if (!strchr (ALL_REC_TYPES, *cp))
error (1, 0, "%c is not a valid report type", *cp);
}
- (void) strcpy (rec_types, optarg);
+ free (rec_types);
+ rec_types = xstrdup (optarg);
break;
case 'z':
#ifndef HAVE_RCS5
@@ -590,7 +604,10 @@ history (argc, argv)
if (tag_report)
{
if (!strchr (rec_types, 'T'))
+ {
+ rec_types = xrealloc (rec_types, strlen (rec_types) + 5);
(void) strcat (rec_types, "T");
+ }
}
else if (extract)
{
@@ -599,7 +616,8 @@ history (argc, argv)
}
else if (modified)
{
- (void) strcpy (rec_types, "MAR");
+ free (rec_types);
+ rec_types = xstrdup ("MAR");
/*
* If the user has not specified a date oriented flag ("Since"), sort
* by Repository/file before date. Default is "just" date.
@@ -618,7 +636,8 @@ history (argc, argv)
}
else if (module_report)
{
- (void) strcpy (rec_types, last_entry ? "OMAR" : ALL_REC_TYPES);
+ free (rec_types);
+ rec_types = xstrdup (last_entry ? "OMAR" : ALL_REC_TYPES);
module_sort++;
repos_sort++;
file_sort++;
@@ -627,7 +646,8 @@ history (argc, argv)
else
/* Must be "checkout" or default */
{
- (void) strcpy (rec_types, "OF");
+ free (rec_types);
+ rec_types = xstrdup ("OF");
/* See comments in "modified" above */
if (!last_entry && user_list)
user_sort++;
@@ -641,7 +661,10 @@ history (argc, argv)
/* If we're looking back to a Tag value, must consider "Tag" records */
if (*since_tag && !strchr (rec_types, 'T'))
+ {
+ rec_types = xrealloc (rec_types, strlen (rec_types) + 5);
(void) strcat (rec_types, "T");
+ }
argc -= c;
argv += c;
@@ -662,6 +685,10 @@ history (argc, argv)
qsort ((PTR) hrec_head, hrec_count, sizeof (struct hrec), sort_order);
report_hrecs ();
free (fname);
+ free (since_rev);
+ free (since_tag);
+ free (backto);
+ free (rec_types);
return (0);
}
diff --git a/gnu/usr.bin/cvs/src/import.c b/gnu/usr.bin/cvs/src/import.c
index 99501362853..38cb55b3e65 100644
--- a/gnu/usr.bin/cvs/src/import.c
+++ b/gnu/usr.bin/cvs/src/import.c
@@ -39,10 +39,10 @@ static int update_rcs_file PROTO((char *message, char *vfile, char *vtag, int ta
static void add_log PROTO((int ch, char *fname));
static int repos_len;
-static char vhead[50];
-static char vbranch[50];
+static char *vhead;
+static char *vbranch;
static FILE *logfp;
-static char repository[PATH_MAX];
+static char *repository;
static int conflicts;
static int use_file_modtime;
static char *keyword_opt = NULL;
@@ -79,7 +79,7 @@ import (argc, argv)
ign_setup ();
wrap_setup ();
- (void) strcpy (vbranch, CVSBRANCH);
+ vbranch = xstrdup (CVSBRANCH);
optind = 1;
while ((c = getopt (argc, argv, "Qqdb:m:I:k:W:")) != -1)
{
@@ -100,7 +100,8 @@ import (argc, argv)
use_file_modtime = 1;
break;
case 'b':
- (void) strcpy (vbranch, optarg);
+ free (vbranch);
+ vbranch = xstrdup (optarg);
break;
case 'm':
#ifdef FORCE_USE_EDITOR
@@ -135,7 +136,14 @@ import (argc, argv)
usage (import_usage);
for (i = 1; i < argc; i++) /* check the tags for validity */
+ {
+ int j;
+
RCS_check_tag (argv[i]);
+ for (j = 1; j < i; j++)
+ if (strcmp (argv[j], argv[i]) == 0)
+ error (1, 0, "tag `%s' was specified more than once", argv[i]);
+ }
/* XXX - this should be a module, not just a pathname */
if (! isabsolute (argv[0]))
@@ -146,11 +154,14 @@ import (argc, argv)
error (1, 0, "Set it or specify the '-d' option to %s.",
program_name);
}
+ repository = xmalloc (strlen (CVSroot_directory) + strlen (argv[0])
+ + 10);
(void) sprintf (repository, "%s/%s", CVSroot_directory, argv[0]);
repos_len = strlen (CVSroot_directory);
}
else
{
+ repository = xmalloc (strlen (argv[0]) + 5);
(void) strcpy (repository, argv[0]);
repos_len = 0;
}
@@ -166,7 +177,7 @@ import (argc, argv)
error (1, 0, "%s is not a numeric branch", vbranch);
if (numdots (vbranch) != 2)
error (1, 0, "Only branches with two dots are supported: %s", vbranch);
- (void) strcpy (vhead, vbranch);
+ vhead = xstrdup (vbranch);
cp = strrchr (vhead, '.');
*cp = '\0';
@@ -318,6 +329,9 @@ import (argc, argv)
if (message)
free (message);
+ free (repository);
+ free (vbranch);
+ free (vhead);
return (err);
}
@@ -435,28 +449,39 @@ process_import_file (message, vfile, vtag, targc, targv)
int targc;
char *targv[];
{
- char attic_name[PATH_MAX];
- char rcs[PATH_MAX];
+ char *rcs;
int inattic = 0;
+ rcs = xmalloc (strlen (repository) + strlen (vfile) + sizeof (RCSEXT)
+ + 5);
(void) sprintf (rcs, "%s/%s%s", repository, vfile, RCSEXT);
if (!isfile (rcs))
{
+ char *attic_name;
+
+ attic_name = xmalloc (strlen (repository) + strlen (vfile) +
+ sizeof (CVSATTIC) + sizeof (RCSEXT) + 10);
(void) sprintf (attic_name, "%s/%s/%s%s", repository, CVSATTIC,
vfile, RCSEXT);
if (!isfile (attic_name))
{
+ int retval;
+ free (attic_name);
/*
* A new import source file; it doesn't exist as a ,v within the
* repository nor in the Attic -- create it anew.
*/
add_log ('N', vfile);
- return (add_rcs_file (message, rcs, vfile, vtag, targc, targv));
+ retval = add_rcs_file (message, rcs, vfile, vtag, targc, targv);
+ free (rcs);
+ return retval;
}
+ free (attic_name);
inattic = 1;
}
+ free (rcs);
/*
* an rcs file exists. have to do things the official, slow, way.
*/
@@ -495,10 +520,11 @@ update_rcs_file (message, vfile, vtag, targc, targv, inattic)
if (vers->vn_rcs != NULL
&& !RCS_isdead(vers->srcfile, vers->vn_rcs))
{
- char xtmpfile[PATH_MAX];
+ char *xtmpfile;
int different;
int retcode = 0;
+ xtmpfile = xmalloc (strlen (Tmpdir) + 40);
(void) sprintf (xtmpfile, "%s/cvs-imp%ld", Tmpdir, (long) getpid());
/*
@@ -528,6 +554,7 @@ update_rcs_file (message, vfile, vtag, targc, targv, inattic)
"ERROR: cannot co revision %s of file %s", vers->vn_rcs,
vers->srcfile->path);
(void) unlink_file (xtmpfile);
+ free (xtmpfile);
return (1);
}
@@ -538,6 +565,7 @@ update_rcs_file (message, vfile, vtag, targc, targv, inattic)
error (0, errno, "cannot remove %s", tocvsPath);
(void) unlink_file (xtmpfile);
+ free (xtmpfile);
if (!different)
{
int retval = 0;
@@ -833,9 +861,11 @@ get_comment (user)
char *user;
{
char *cp, *suffix;
- char suffix_path[PATH_MAX];
+ char *suffix_path;
int i;
+ char *retval;
+ suffix_path = xmalloc (strlen (user) + 5);
cp = strrchr (user, '.');
if (cp != NULL)
{
@@ -855,11 +885,21 @@ get_comment (user)
suffix = ""; /* will use the default */
for (i = 0;; i++)
{
- if (comtable[i].suffix == NULL) /* default */
- return (comtable[i].comlead);
+ if (comtable[i].suffix == NULL)
+ {
+ /* Default. Note we'll always hit this case before we
+ ever return NULL. */
+ retval = comtable[i].comlead;
+ break;
+ }
if (strcmp (suffix, comtable[i].suffix) == 0)
- return (comtable[i].comlead);
+ {
+ retval = comtable[i].comlead;
+ break;
+ }
}
+ free (suffix_path);
+ return retval;
}
static int
@@ -875,9 +915,9 @@ add_rcs_file (message, rcs, user, vtag, targc, targv)
struct stat sb;
struct tm *ftm;
time_t now;
- char altdate1[50];
+ char altdate1[MAXDATELEN];
#ifndef HAVE_RCS5
- char altdate2[50];
+ char altdate2[MAXDATELEN];
#endif
char *author;
int i, ierrno, err = 0;
@@ -1175,6 +1215,7 @@ import_descend_dir (message, dir, vtag, targc, targv)
struct saved_cwd cwd;
char *cp;
int ierrno, err;
+ char *rcs = NULL;
if (islink (dir))
return (0);
@@ -1183,13 +1224,24 @@ import_descend_dir (message, dir, vtag, targc, targv)
fperror (logfp, 0, 0, "ERROR: cannot get working directory");
return (1);
}
+
+ /* Concatenate DIR to the end of REPOSITORY. */
if (repository[0] == '\0')
- (void) strcpy (repository, dir);
+ {
+ char *new = xstrdup (dir);
+ free (repository);
+ repository = new;
+ }
else
{
- (void) strcat (repository, "/");
- (void) strcat (repository, dir);
+ char *new = xmalloc (strlen (repository) + strlen (dir) + 10);
+ strcpy (new, repository);
+ (void) strcat (new, "/");
+ (void) strcat (new, dir);
+ free (repository);
+ repository = new;
}
+
#ifdef CLIENT_SUPPORT
if (!quiet && !client_active)
#else
@@ -1211,12 +1263,12 @@ import_descend_dir (message, dir, vtag, targc, targv)
if (!isdir (repository))
#endif
{
- char rcs[PATH_MAX];
-
+ rcs = xmalloc (strlen (repository) + sizeof (RCSEXT) + 5);
(void) sprintf (rcs, "%s%s", repository, RCSEXT);
if (isfile (repository) || isfile(rcs))
{
- fperror (logfp, 0, 0, "ERROR: %s is a file, should be a directory!",
+ fperror (logfp, 0, 0,
+ "ERROR: %s is a file, should be a directory!",
repository);
error (0, 0, "ERROR: %s is a file, should be a directory!",
repository);
@@ -1236,6 +1288,8 @@ import_descend_dir (message, dir, vtag, targc, targv)
}
err = import_descend (message, vtag, targc, targv);
out:
+ if (rcs != NULL)
+ free (rcs);
if ((cp = strrchr (repository, '/')) != NULL)
*cp = '\0';
else
diff --git a/gnu/usr.bin/cvs/src/log.c b/gnu/usr.bin/cvs/src/log.c
index 3bb7eb2a907..8c6634ba66c 100644
--- a/gnu/usr.bin/cvs/src/log.c
+++ b/gnu/usr.bin/cvs/src/log.c
@@ -236,7 +236,7 @@ cvslog (argc, argv)
/* FIXME: We shouldn't have to send current files to get log entries, but it
doesn't work yet and I haven't debugged it. So send the files --
it's slower but it works. gnu@cygnus.com Apr94 */
- send_files (argc - i, argv + i, local, 0, 0);
+ send_files (argc - i, argv + i, local, 0, 0, 0);
send_to_server ("log\012", 0);
err = get_responses_and_close ();
diff --git a/gnu/usr.bin/cvs/src/login.c b/gnu/usr.bin/cvs/src/login.c
index a0fab6a3ac0..656ff4171db 100644
--- a/gnu/usr.bin/cvs/src/login.c
+++ b/gnu/usr.bin/cvs/src/login.c
@@ -12,7 +12,16 @@
#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */
+/* There seems to be very little agreement on which system header
+ getpass is declared in. With a lot of fancy autoconfiscation,
+ we could perhaps detect this, but for now we'll just rely on
+ _CRAY, since Cray is perhaps the only system on which our own
+ declaration won't work (some Crays declare the 2#$@% thing as
+ varadic, believe it or not). On Cray, getpass will be declared
+ in either stdlib.h or unistd.h. */
+#ifndef _CRAY
extern char *getpass ();
+#endif
#ifndef CVS_PASSWORD_FILE
#define CVS_PASSWORD_FILE ".cvspass"
@@ -258,10 +267,6 @@ login (argc, argv)
return 0;
}
-/* todo: "cvs logout" could erase an entry from the file.
- * But to what purpose?
- */
-
/* Returns the _scrambled_ password. The server must descramble
before hashing and comparing. */
char *
@@ -362,4 +367,99 @@ get_cvs_password ()
return NULL;
}
+static const char *const logout_usage[] =
+{
+ "Usage: %s %s\n",
+ NULL
+};
+
+/* Remove any entry for the CVSRoot repository found in "CVS/.cvspass". */
+int
+logout (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *passfile;
+ FILE *fp;
+ char *tmp_name;
+ FILE *tmp_fp;
+ char *linebuf = (char *) NULL;
+ size_t linebuf_len;
+ int root_len, found = 0;
+
+ if (argc < 0)
+ usage (logout_usage);
+
+ if (CVSroot_method != pserver_method)
+ {
+ error (0, 0, "can only use pserver method with `logout' command");
+ error (1, 0, "CVSROOT: %s", CVSroot_original);
+ }
+
+ if (! CVSroot_username)
+ {
+ error (0, 0, "CVSROOT \"%s\" is not fully-qualified.",
+ CVSroot_original);
+ error (1, 0, "Please make sure to specify \"user@host\"!");
+ }
+
+ /* Hmm. Do we want a variant of this command which deletes _all_
+ the entries from the current .cvspass? Might be easier to
+ remember than "rm ~/.cvspass" but then again if people are
+ mucking with HOME (common in Win95 as the system doesn't set
+ it), then this variant of "cvs logout" might give a false sense
+ of security, in that it wouldn't delete entries from any
+ .cvspass files but the current one. */
+
+ printf ("(Logging out of %s@%s)\n", CVSroot_username, CVSroot_hostname);
+ fflush (stdout);
+
+ /* IF we have a password for this "[user@]host:/path" already
+ * THEN
+ * drop the entry
+ * ELSE
+ * do nothing
+ */
+
+ passfile = construct_cvspass_filename ();
+ tmp_name = cvs_temp_name ();
+ if ((tmp_fp = CVS_FOPEN (tmp_name, "w")) == NULL)
+ {
+ error (1, errno, "unable to open temp file %s", tmp_name);
+ return 1;
+ }
+ chmod (tmp_name, 0600);
+
+ root_len = strlen (CVSroot_original);
+
+ fp = CVS_FOPEN (passfile, "r");
+ if (fp == NULL)
+ error (1, errno, "Error opening %s", passfile);
+
+ /* Check each line to see if we have this entry. */
+ /* Copy only those lines that do not match this entry */
+ while (getline (&linebuf, &linebuf_len, fp) >= 0)
+ {
+ if (strncmp (CVSroot_original, linebuf, root_len))
+ fprintf (tmp_fp, "%s", linebuf);
+ else
+ found = TRUE;
+ }
+ fclose (fp);
+ fclose (tmp_fp);
+
+ if (! found)
+ {
+ printf ("Entry not found for %s\n", CVSroot_original);
+ unlink_file (tmp_name);
+ }
+ else
+ {
+ copy_file (tmp_name, passfile);
+ unlink_file (tmp_name);
+ chmod (passfile, 0600);
+ }
+ return 0;
+}
+
#endif /* AUTH_CLIENT_SUPPORT from beginning of file. */
diff --git a/gnu/usr.bin/cvs/src/logmsg.c b/gnu/usr.bin/cvs/src/logmsg.c
index 0a4ffb601fc..98e4ae1ff93 100644
--- a/gnu/usr.bin/cvs/src/logmsg.c
+++ b/gnu/usr.bin/cvs/src/logmsg.c
@@ -409,9 +409,10 @@ do_verify (message, repository)
fname = cvs_temp_name ();
- if ((fp = fopen (fname, "w")) < 0)
+ fp = fopen (fname, "w");
+ if (fp == NULL)
{
- error (1, 0, "cannot create temporary file %s", fname);
+ error (1, errno, "cannot create temporary file %s", fname);
return;
}
else
@@ -552,10 +553,13 @@ title_proc (p, closure)
You can verify that this assumption is safe by checking the
code in add.c (add_directory) and import.c (import). */
+ str_list = xrealloc (str_list, strlen (str_list) + 5);
(void) strcat (str_list, " ");
if (li->type == T_TITLE)
{
+ str_list = xrealloc (str_list,
+ strlen (str_list) + strlen (p->key) + 5);
(void) strcat (str_list, p->key);
}
else
@@ -567,13 +571,28 @@ title_proc (p, closure)
switch (*c)
{
case 's':
+ str_list =
+ xrealloc (str_list,
+ strlen (str_list) + strlen (p->key) + 5);
(void) strcat (str_list, p->key);
break;
case 'V':
+ str_list =
+ xrealloc (str_list,
+ (strlen (str_list)
+ + (li->rev_old ? strlen (li->rev_old) : 0)
+ + 10)
+ );
(void) strcat (str_list, (li->rev_old
? li->rev_old : "NONE"));
break;
case 'v':
+ str_list =
+ xrealloc (str_list,
+ (strlen (str_list)
+ + (li->rev_new ? strlen (li->rev_new) : 0)
+ + 10)
+ );
(void) strcat (str_list, (li->rev_new
? li->rev_new : "NONE"));
break;
@@ -584,7 +603,10 @@ title_proc (p, closure)
won't blow up on an old CVS. */
}
if (*(c + 1) != '\0')
+ {
+ str_list = xrealloc (str_list, strlen (str_list) + 5);
(void) strcat (str_list, ",");
+ }
}
}
}
@@ -592,12 +614,6 @@ title_proc (p, closure)
}
/*
- * Since some systems don't define this... */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 256
-#endif
-
-/*
* Writes some stuff to the logfile "filter" and returns the status of the
* filter program.
*/
@@ -609,7 +625,6 @@ logfile_write (repository, filter, message, logfp, changes)
FILE *logfp;
List *changes;
{
- char cwd[PATH_MAX];
FILE *pipefp;
char *prog;
char *cp;
@@ -618,8 +633,6 @@ logfile_write (repository, filter, message, logfp, changes)
char *fmt_percent; /* the location of the percent sign
that starts the format string. */
- prog = xmalloc (MAXPROGLEN);
-
/* The user may specify a format string as part of the filter.
Originally, `%s' was the only valid string. The string that
was substituted for it was:
@@ -736,11 +749,11 @@ logfile_write (repository, filter, message, logfp, changes)
str_list_format = xmalloc (sizeof (char) * (len + 1));
strncpy (str_list_format, fmt_begin, len);
str_list_format[len] = '\0';
-
- /* Allocate a chunk of memory to hold the string. */
+ /* Allocate an initial chunk of memory. As we build up the string
+ we will realloc it. */
if (!str_list)
- str_list = xmalloc (MAXLISTLEN);
+ str_list = xmalloc (1);
str_list[0] = '\0';
/* Add entries to the string. Don't bother looking for
@@ -762,6 +775,9 @@ logfile_write (repository, filter, message, logfp, changes)
srepos = Short_Repository (repository);
+ prog = xmalloc ((fmt_percent - filter) + strlen (srepos)
+ + strlen (str_list) + strlen (fmt_continue)
+ + 10);
(void) strncpy (prog, filter, fmt_percent - filter);
prog[fmt_percent - filter] = '\0';
(void) strcat (prog, "'");
@@ -778,7 +794,7 @@ logfile_write (repository, filter, message, logfp, changes)
else
{
/* There's no format string. */
- strcpy (prog, filter);
+ prog = xstrdup (filter);
}
if ((pipefp = run_popen (prog, "w")) == NULL)
@@ -789,8 +805,17 @@ logfile_write (repository, filter, message, logfp, changes)
return (1);
}
(void) fprintf (pipefp, "Update of %s\n", repository);
- (void) fprintf (pipefp, "In directory %s:%s\n\n", hostname,
- ((cp = getwd (cwd)) != NULL) ? cp : cwd);
+ (void) fprintf (pipefp, "In directory %s:", hostname);
+ cp = xgetwd ();
+ if (cp == NULL)
+ fprintf (pipefp, "<cannot get working directory: %s>\n\n",
+ strerror (errno));
+ else
+ {
+ fprintf (pipefp, "%s\n\n", cp);
+ free (cp);
+ }
+
setup_tmpfile (pipefp, "", changes);
(void) fprintf (pipefp, "Log Message:\n%s\n", message);
if (logfp != (FILE *) 0)
diff --git a/gnu/usr.bin/cvs/src/mkmodules.c b/gnu/usr.bin/cvs/src/mkmodules.c
index 9f3f797cc48..add69b8c5a8 100644
--- a/gnu/usr.bin/cvs/src/mkmodules.c
+++ b/gnu/usr.bin/cvs/src/mkmodules.c
@@ -7,13 +7,14 @@
#include "cvs.h"
#include "savecwd.h"
+#include "getline.h"
#ifndef DBLKSIZ
#define DBLKSIZ 4096 /* since GNU ndbm doesn't define it */
#endif
static int checkout_file PROTO((char *file, char *temp));
-static void make_tempfile PROTO((char *temp));
+static char *make_tempfile PROTO((void));
static void rename_rcsfile PROTO((char *temp, char *real));
#ifndef MY_NDBM
@@ -46,7 +47,7 @@ struct admin_file {
};
static const char *const loginfo_contents[] = {
- "# The \"loginfo\" file controls where \"cvs commit\" log information\n"
+ "# The \"loginfo\" file controls where \"cvs commit\" log information\n",
"# is sent. The first entry on a line is a regular expression which must match\n",
"# the directory that the change is being made to, relative to the\n",
"# $CVSROOT. If a match is found, then the remainder of the line is a filter\n",
@@ -332,15 +333,14 @@ mkmodules (dir)
char *dir;
{
struct saved_cwd cwd;
- /* FIXME: arbitrary limit */
- char temp[PATH_MAX];
+ char *temp;
char *cp, *last, *fname;
#ifdef MY_NDBM
DBM *db;
#endif
FILE *fp;
- /* FIXME: arbitrary limit */
- char line[512];
+ char *line = NULL;
+ size_t line_allocated = 0;
const struct admin_file *fileptr;
if (save_cwd (&cwd))
@@ -352,7 +352,7 @@ mkmodules (dir)
/*
* First, do the work necessary to update the "modules" database.
*/
- make_tempfile (temp);
+ temp = make_tempfile ();
switch (checkout_file (CVSROOTADM_MODULES, temp))
{
@@ -381,12 +381,13 @@ mkmodules (dir)
} /* switch on checkout_file() */
(void) unlink_file (temp);
+ free (temp);
/* Checkout the files that need it in CVSROOT dir */
for (fileptr = filelist; fileptr && fileptr->filename; fileptr++) {
if (fileptr->errormsg == NULL)
continue;
- make_tempfile (temp);
+ temp = make_tempfile ();
if (checkout_file (fileptr->filename, temp) == 0)
rename_rcsfile (temp, fileptr->filename);
#if 0
@@ -401,9 +402,9 @@ mkmodules (dir)
error (0, 0, fileptr->errormsg, fileptr->filename);
#endif
(void) unlink_file (temp);
+ free (temp);
}
- /* Use 'fopen' instead of 'open_file' because we want to ignore error */
fp = CVS_FOPEN (CVSROOTADM_CHECKOUTLIST, "r");
if (fp)
{
@@ -413,7 +414,7 @@ mkmodules (dir)
*
* comment lines begin with '#'
*/
- while (fgets (line, sizeof (line), fp) != NULL)
+ while (getline (&line, &line_allocated, fp) >= 0)
{
/* skip lines starting with # */
if (line[0] == '#')
@@ -431,7 +432,7 @@ mkmodules (dir)
;
*cp = '\0';
- make_tempfile (temp);
+ temp = make_tempfile ();
if (checkout_file (fname, temp) == 0)
{
rename_rcsfile (temp, fname);
@@ -443,8 +444,18 @@ mkmodules (dir)
if (cp < last && *cp)
error (0, 0, cp, fname);
}
+ free (temp);
}
- (void) fclose (fp);
+ if (ferror (fp))
+ error (0, errno, "cannot read %s", CVSROOTADM_CHECKOUTLIST);
+ if (fclose (fp) < 0)
+ error (0, errno, "cannot close %s", CVSROOTADM_CHECKOUTLIST);
+ }
+ else
+ {
+ /* Error from CVS_FOPEN. */
+ if (!existence_error (errno))
+ error (0, errno, "cannot open %s", CVSROOTADM_CHECKOUTLIST);
}
if (restore_cwd (&cwd, NULL))
@@ -457,15 +468,16 @@ mkmodules (dir)
/*
* Yeah, I know, there are NFS race conditions here.
*/
-static void
-make_tempfile (temp)
- char *temp;
+static char *
+make_tempfile ()
{
static int seed = 0;
int fd;
+ char *temp;
if (seed == 0)
seed = getpid ();
+ temp = xmalloc (sizeof (BAKPREFIX) + 40);
while (1)
{
(void) sprintf (temp, "%s%d", BAKPREFIX, seed++);
@@ -476,6 +488,7 @@ make_tempfile (temp)
}
if (close(fd) < 0)
error(1, errno, "cannot close temporary file %s", temp);
+ return temp;
}
static int
@@ -655,21 +668,25 @@ rename_rcsfile (temp, real)
char *temp;
char *real;
{
- char bak[50];
+ char *bak;
struct stat statbuf;
- char rcs[PATH_MAX];
-
+ char *rcs;
+
/* Set "x" bits if set in original. */
+ rcs = xmalloc (strlen (real) + sizeof (RCSEXT) + 10);
(void) sprintf (rcs, "%s%s", real, RCSEXT);
statbuf.st_mode = 0; /* in case rcs file doesn't exist, but it should... */
(void) CVS_STAT (rcs, &statbuf);
+ free (rcs);
if (chmod (temp, 0444 | (statbuf.st_mode & 0111)) < 0)
error (0, errno, "warning: cannot chmod %s", temp);
+ bak = xmalloc (strlen (real) + sizeof (BAKPREFIX) + 10);
(void) sprintf (bak, "%s%s", BAKPREFIX, real);
(void) unlink_file (bak); /* rm .#loginfo */
(void) CVS_RENAME (real, bak); /* mv loginfo .#loginfo */
(void) CVS_RENAME (temp, real); /* mv "temp" loginfo */
+ free (bak);
}
const char *const init_usage[] = {
diff --git a/gnu/usr.bin/cvs/src/modules.c b/gnu/usr.bin/cvs/src/modules.c
index c9261f944c7..8ec1b7a38f5 100644
--- a/gnu/usr.bin/cvs/src/modules.c
+++ b/gnu/usr.bin/cvs/src/modules.c
@@ -54,16 +54,21 @@ static void save_d PROTO((char *k, int ks, char *d, int ds));
DBM *
open_module ()
{
- char mfile[PATH_MAX];
+ char *mfile;
+ DBM *retval;
if (CVSroot_original == NULL)
{
error (0, 0, "must set the CVSROOT environment variable");
error (1, 0, "or specify the '-d' global option");
}
+ mfile = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM)
+ + sizeof (CVSROOTADM_MODULES) + 20);
(void) sprintf (mfile, "%s/%s/%s", CVSroot_directory,
CVSROOTADM, CVSROOTADM_MODULES);
- return (dbm_open (mfile, O_RDONLY, 0666));
+ retval = dbm_open (mfile, O_RDONLY, 0666);
+ free (mfile);
+ return retval;
}
/*
@@ -102,17 +107,18 @@ do_module (db, mname, m_type, msg, callback_proc, where,
char *tag_prog = NULL;
char *update_prog = NULL;
struct saved_cwd cwd;
+ int cwd_saved = 0;
char *line;
int modargc;
int xmodargc;
char **modargv;
- char *xmodargv[MAXFILEPERDIR];
+ char **xmodargv;
char *value;
- char *zvalue;
+ char *zvalue = NULL;
char *mwhere = NULL;
char *mfile = NULL;
char *spec_opt = NULL;
- char xvalue[PATH_MAX];
+ char *xvalue = NULL;
int alias = 0;
datum key, val;
char *cp;
@@ -147,7 +153,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
if (mname[0] == '!' && mname[1] != '\0')
{
ign_dir_add (mname+1);
- return(err);
+ goto do_module_return;
}
/* strip extra stuff from the module name */
@@ -195,13 +201,16 @@ do_module (db, mname, m_type, msg, callback_proc, where,
}
else
{
- char file[PATH_MAX];
- char attic_file[PATH_MAX];
+ char *file;
+ char *attic_file;
char *acp;
+ int is_found = 0;
/* check to see if mname is a directory or file */
-
+ file = xmalloc (strlen (CVSroot_directory) + strlen (mname) + 10);
(void) sprintf (file, "%s/%s", CVSroot_directory, mname);
+ attic_file = xmalloc (strlen (CVSroot_directory) + strlen (mname)
+ + sizeof (CVSATTIC) + sizeof (RCSEXT) + 15);
if ((acp = strrchr (mname, '/')) != NULL)
{
*acp = '\0';
@@ -216,7 +225,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
if (isdir (file))
{
value = mname;
- goto found;
+ is_found = 1;
}
else
{
@@ -228,7 +237,9 @@ do_module (db, mname, m_type, msg, callback_proc, where,
{
char *slashp;
- /* put the ' ' in a copy so we don't mess up the original */
+ /* 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 = ' ';
@@ -243,19 +254,26 @@ 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);
}
else
{
/* otherwise just copy it */
+ xvalue = xmalloc (strlen (mname) + 10);
value = strcpy (xvalue, ". ");
(void) strcat (xvalue, mname);
}
}
- goto found;
+ is_found = 1;
}
}
+ free (attic_file);
+ free (file);
+
+ if (is_found)
+ goto found;
}
/* look up everything to the first / as a module */
@@ -306,9 +324,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
/* if we got here, we couldn't find it using our search, so give up */
error (0, 0, "cannot find module `%s' - ignored", mname);
err++;
- if (mwhere)
- free (mwhere);
- return (err);
+ goto do_module_return;
/*
@@ -320,6 +336,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
/* remember where we start */
if (save_cwd (&cwd))
error_exit ();
+ cwd_saved = 1;
/* copy value to our own string since if we go recursive we'll be
really screwed if we do another dbm lookup */
@@ -365,8 +382,12 @@ do_module (db, mname, m_type, msg, callback_proc, where,
}
if (!isfile (CVSADM))
{
- char nullrepos[PATH_MAX];
+ char *nullrepos;
+ nullrepos = xmalloc (strlen (CVSroot_directory)
+ + sizeof (CVSROOTADM)
+ + sizeof (CVSNULLREPOS)
+ + 10);
(void) sprintf (nullrepos, "%s/%s/%s", CVSroot_directory,
CVSROOTADM, CVSNULLREPOS);
if (!isfile (nullrepos))
@@ -393,6 +414,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
server_set_entstat (dir, nullrepos);
#endif
}
+ free (nullrepos);
}
out:
goto do_special;
@@ -417,7 +439,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
(void) sprintf (line, "%s %s", "XXX", value);
/* turn the line into an argv[] array */
- line2argv (&xmodargc, xmodargv, line);
+ line2argv (&xmodargc, &xmodargv, line);
free (line);
modargc = xmodargc;
modargv = xmodargv;
@@ -466,11 +488,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
"modules file has invalid option for key %s value %s",
key.dptr, val.dptr);
err++;
- if (mwhere)
- free (mwhere);
- free (zvalue);
- free_cwd (&cwd);
- return (err);
+ goto do_module_return;
}
}
modargc -= optind;
@@ -478,11 +496,8 @@ do_module (db, mname, m_type, msg, callback_proc, where,
if (modargc == 0)
{
error (0, 0, "modules file missing directory for module %s", mname);
- if (mwhere)
- free (mwhere);
- free (zvalue);
- free_cwd (&cwd);
- return (++err);
+ ++err;
+ goto do_module_return;
}
if (alias && nonalias_opt)
@@ -493,7 +508,8 @@ do_module (db, mname, m_type, msg, callback_proc, where,
situation. */
error (0, 0, "\
-a cannot be specified in the modules file along with other options");
- return ++err;
+ ++err;
+ goto do_module_return;
}
/* if this was an alias, call ourselves recursively for each module */
@@ -512,11 +528,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
where, shorten, local_specified,
run_module_prog, extra_arg);
}
- if (mwhere)
- free (mwhere);
- free (zvalue);
- free_cwd (&cwd);
- return (err);
+ goto do_module_return;
}
/* otherwise, process this module */
@@ -647,6 +659,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
if (restore_cwd (&cwd, NULL))
error_exit ();
free_cwd (&cwd);
+ cwd_saved = 0;
/* run checkout or tag prog if appropriate */
if (err == 0 && run_module_prog)
@@ -661,7 +674,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
* if we can't find a matching program, just punt and use
* whatever is specified in the modules file.
*/
- char real_prog[PATH_MAX];
+ char *real_prog = NULL;
char *prog = (m_type == TAG ? tag_prog :
(m_type == CHECKOUT ? checkout_prog : export_prog));
char *real_where = (where != NULL ? where : mwhere);
@@ -669,6 +682,8 @@ do_module (db, mname, m_type, msg, callback_proc, where,
if ((*prog != '/') && (*prog != '.'))
{
+ real_prog = xmalloc (strlen (real_where) + strlen (prog)
+ + 10);
(void) sprintf (real_prog, "%s/%s", real_where, prog);
if (isfile (real_prog))
prog = real_prog;
@@ -695,14 +710,21 @@ do_module (db, mname, m_type, msg, callback_proc, where,
err += run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
free (expanded_path);
}
+ free (real_prog);
}
}
+ do_module_return:
/* clean up */
if (mwhere)
free (mwhere);
- free (zvalue);
+ if (cwd_saved)
+ free_cwd (&cwd);
+ if (zvalue != NULL)
+ free (zvalue);
+ if (xvalue != NULL)
+ free (xvalue);
return (err);
}
@@ -857,8 +879,7 @@ cat_module (status)
int moduleargc;
struct sortrec *s_h;
char *cp, *cp2, **argv;
- char *line;
- char *moduleargv[MAXFILEPERDIR];
+ char **moduleargv;
Status = status;
@@ -884,23 +905,27 @@ cat_module (status)
fill = cols - (indent + 2);
for (s_h = s_head, i = 0; i < s_count; i++, s_h++)
{
- line = xmalloc (strlen (s_h->modname) + strlen (s_h->rest)
- + strlen (status ? s_h->status : "") + 15);
+ char *line;
/* Print module name (and status, if wanted) */
+ line = xmalloc (strlen (s_h->modname) + 15);
sprintf (line, "%-12s", s_h->modname);
cvs_output (line, 0);
+ free (line);
if (status)
{
+ line = xmalloc (strlen (s_h->status) + 15);
sprintf (line, " %-11s", s_h->status);
cvs_output (line, 0);
if (s_h->status != def_status)
*(s_h->status + strlen (s_h->status)) = ' ';
+ free (line);
}
+ line = xmalloc (strlen (s_h->modname) + strlen (s_h->rest) + 15);
/* Parse module file entry as command line and print options */
(void) sprintf (line, "%s %s", s_h->modname, s_h->rest);
- line2argv (&moduleargc, moduleargv, line);
+ line2argv (&moduleargc, &moduleargv, line);
free (line);
argc = moduleargc;
argv = moduleargv;
diff --git a/gnu/usr.bin/cvs/src/myndbm.c b/gnu/usr.bin/cvs/src/myndbm.c
index 99fe9521ace..1a3fcaea1a2 100644
--- a/gnu/usr.bin/cvs/src/myndbm.c
+++ b/gnu/usr.bin/cvs/src/myndbm.c
@@ -199,11 +199,14 @@ mydbm_load_file (fp, list)
{
char *line = NULL;
size_t line_len;
- /* FIXME: arbitrary limit. */
- char value[MAXLINELEN];
+ char *value;
+ size_t value_allocated;
char *cp, *vp;
int len, cont;
+ value_allocated = 1;
+ value = xmalloc (value_allocated);
+
for (cont = 0; getline (&line, &line_len, fp) >= 0;)
{
if ((cp = strrchr (line, '\012')) != NULL)
@@ -221,9 +224,8 @@ mydbm_load_file (fp, list)
* line; otherwise at the beginning, but only after any trailing
* backslash is removed.
*/
- vp = value;
- if (cont)
- vp += strlen (value);
+ if (!cont)
+ value[0] = '\0';
/*
* See if the line we read is a continuation line, and strip the
@@ -243,7 +245,11 @@ mydbm_load_file (fp, list)
{
cont = 0;
}
- (void) strcpy (vp, line);
+ expand_string (&value,
+ &value_allocated,
+ strlen (value) + strlen (line) + 5);
+ strcat (value, line);
+
if (value[0] == '#')
continue; /* comment line */
vp = value;
@@ -283,6 +289,7 @@ mydbm_load_file (fp, list)
}
}
free (line);
+ free (value);
}
#endif /* MY_NDBM */
diff --git a/gnu/usr.bin/cvs/src/parseinfo.c b/gnu/usr.bin/cvs/src/parseinfo.c
index e68fd0bfbe7..1011965835e 100644
--- a/gnu/usr.bin/cvs/src/parseinfo.c
+++ b/gnu/usr.bin/cvs/src/parseinfo.c
@@ -7,6 +7,7 @@
*/
#include "cvs.h"
+#include "getline.h"
/*
* Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for
@@ -24,8 +25,9 @@ Parse_Info (infofile, repository, callproc, all)
{
int err = 0;
FILE *fp_info;
- char infopath[PATH_MAX];
- char line[MAXLINELEN];
+ char *infopath;
+ char *line = NULL;
+ size_t line_allocated = 0;
char *default_value = NULL;
char *expanded_value= NULL;
int callback_done, line_number;
@@ -40,10 +42,20 @@ Parse_Info (infofile, repository, callproc, all)
}
/* find the info file and open it */
+ infopath = xmalloc (strlen (CVSroot_directory)
+ + strlen (infofile)
+ + sizeof (CVSROOTADM)
+ + 10);
(void) sprintf (infopath, "%s/%s/%s", CVSroot_directory,
CVSROOTADM, infofile);
- if ((fp_info = CVS_FOPEN (infopath, "r")) == NULL)
- return (0); /* no file -> nothing special done */
+ fp_info = CVS_FOPEN (infopath, "r");
+ if (fp_info == NULL)
+ {
+ /* If no file, don't do anything special. */
+ if (!existence_error (errno))
+ error (0, errno, "cannot open %s", infopath);
+ return 0;
+ }
/* strip off the CVSROOT if repository was absolute */
srepos = Short_Repository (repository);
@@ -54,7 +66,7 @@ Parse_Info (infofile, repository, callproc, all)
/* search the info file for lines that match */
callback_done = line_number = 0;
- while (fgets (line, sizeof (line), fp_info) != NULL)
+ while (getline (&line, &line_allocated, fp_info) >= 0)
{
line_number++;
@@ -146,7 +158,10 @@ Parse_Info (infofile, repository, callproc, all)
err += callproc (repository, expanded_value);
callback_done = 1;
}
- (void) fclose (fp_info);
+ if (ferror (fp_info))
+ error (0, errno, "cannot read %s", infopath);
+ if (fclose (fp_info) < 0)
+ error (0, errno, "cannot close %s", infopath);
/* if we fell through and didn't callback at all, do the default */
if (callback_done == 0 && default_value != NULL)
@@ -157,6 +172,9 @@ Parse_Info (infofile, repository, callproc, all)
free (default_value);
if (expanded_value != NULL)
free (expanded_value);
+ free (infopath);
+ if (line != NULL)
+ free (line);
return (err);
}
diff --git a/gnu/usr.bin/cvs/src/rcs.c b/gnu/usr.bin/cvs/src/rcs.c
index f5cef712298..405d375174c 100644
--- a/gnu/usr.bin/cvs/src/rcs.c
+++ b/gnu/usr.bin/cvs/src/rcs.c
@@ -778,8 +778,6 @@ static char *value = NULL;
static size_t keysize = 0;
static size_t valsize = 0;
-#define ALLOCINCR 1024
-
static int
getrcskey (fp, keyp, valp, lenp)
FILE *fp;
@@ -813,9 +811,9 @@ getrcskey (fp, keyp, valp, lenp)
{
if (cur >= max)
{
- key = xrealloc (key, keysize + ALLOCINCR);
- cur = key + keysize;
- keysize += ALLOCINCR;
+ size_t curoff = cur - key;
+ expand_string (&key, &keysize, keysize + 1);
+ cur = key + curoff;
max = key + keysize;
}
*cur++ = c;
@@ -830,9 +828,9 @@ getrcskey (fp, keyp, valp, lenp)
}
if (cur >= max)
{
- key = xrealloc (key, keysize + ALLOCINCR);
- cur = key + keysize;
- keysize += ALLOCINCR;
+ size_t curoff = cur - key;
+ expand_string (&key, &keysize, keysize + 1);
+ cur = key + curoff;
max = key + keysize;
}
*cur = '\0';
@@ -897,9 +895,9 @@ getrcskey (fp, keyp, valp, lenp)
if (cur >= max)
{
- value = xrealloc (value, valsize + ALLOCINCR);
- cur = value + valsize;
- valsize += ALLOCINCR;
+ size_t curoff = cur - value;
+ expand_string (&value, &valsize, valsize + 1);
+ cur = value + curoff;
max = value + valsize;
}
*cur++ = c;
@@ -926,9 +924,9 @@ getrcskey (fp, keyp, valp, lenp)
if (cur >= max)
{
- value = xrealloc (value, valsize + ALLOCINCR);
- cur = value + valsize;
- valsize += ALLOCINCR;
+ size_t curoff = cur - value;
+ expand_string (&value, &valsize, valsize + 1);
+ cur = value + curoff;
max = value + valsize;
}
*cur++ = ' ';
@@ -940,9 +938,9 @@ getrcskey (fp, keyp, valp, lenp)
if (cur >= max)
{
- value = xrealloc (value, valsize + ALLOCINCR);
- cur = value + valsize;
- valsize += ALLOCINCR;
+ size_t curoff = cur - value;
+ expand_string (&value, &valsize, valsize + 1);
+ cur = value + curoff;
max = value + valsize;
}
*cur++ = c;
@@ -959,9 +957,9 @@ getrcskey (fp, keyp, valp, lenp)
/* terminate the string */
if (cur >= max)
{
- value = xrealloc (value, valsize + ALLOCINCR);
- cur = value + valsize;
- valsize += ALLOCINCR;
+ size_t curoff = cur - value;
+ expand_string (&value, &valsize, valsize + 1);
+ cur = value + curoff;
max = value + valsize;
}
*cur = '\0';
@@ -1008,9 +1006,9 @@ getrcsrev (fp, revp)
{
if (cur >= max)
{
- key = xrealloc (key, keysize + ALLOCINCR);
- cur = key + keysize;
- keysize += ALLOCINCR;
+ size_t curoff = cur - key;
+ expand_string (&key, &keysize, keysize + 1);
+ cur = key + curoff;
max = key + keysize;
}
*cur++ = c;
@@ -1025,9 +1023,9 @@ getrcsrev (fp, revp)
if (cur >= max)
{
- key = xrealloc (key, keysize + ALLOCINCR);
- cur = key + keysize;
- keysize += ALLOCINCR;
+ size_t curoff = cur - key;
+ expand_string (&key, &keysize, keysize + 1);
+ cur = key + curoff;
max = key + keysize;
}
*cur = '\0';
@@ -1821,13 +1819,17 @@ RCS_datecmp (date1, date2)
return (length_diff ? length_diff : strcmp (date1, date2));
}
-/*
- * Lookup the specified revision in the ,v file and return, in the date
- * argument, the date specified for the revision *minus one second*, so that
- * the logically previous revision will be found later.
- *
- * Returns zero on failure, RCS revision time as a Unix "time_t" on success.
- */
+/* Look up revision REV in RCS and return the date specified for the
+ revision minus FUDGE seconds (FUDGE will generally be one, so that the
+ logically previous revision will be found later, or zero, if we want
+ the exact date).
+
+ The return value is the date being returned as a time_t, or (time_t)-1
+ on error (previously was documented as zero on error; I haven't checked
+ the callers to make sure that they really check for (time_t)-1, but
+ the latter is what this function really returns). If DATE is non-NULL,
+ then it must point to MAXDATELEN characters, and we store the same
+ return value there in DATEFORM format. */
time_t
RCS_getrevtime (rcs, rev, date, fudge)
RCSNode *rcs;
@@ -2005,6 +2007,7 @@ RCS_check_kflag (arg)
" -kb\tGenerate binary file unmodified (merges not allowed) (RCS 5.7).\n",
NULL,
};
+ /* Big enough to hold any of the strings from kflags. */
char karg[10];
char const *const *cpp = NULL;
@@ -3364,7 +3367,7 @@ annotate (argc, argv)
/* FIXME: We shouldn't have to send current files, but I'm not sure
whether it works. So send the files --
it's slower but it works. */
- send_files (argc, argv, local, 0, 0);
+ send_files (argc, argv, local, 0, 0, 0);
send_to_server ("annotate\012", 0);
return get_responses_and_close ();
}
diff --git a/gnu/usr.bin/cvs/src/recurse.c b/gnu/usr.bin/cvs/src/recurse.c
index 7eb7fe99c69..8a7a290173b 100644
--- a/gnu/usr.bin/cvs/src/recurse.c
+++ b/gnu/usr.bin/cvs/src/recurse.c
@@ -19,7 +19,7 @@ static void addlist PROTO((List ** listp, char *key));
static int unroll_files_proc PROTO((Node *p, void *closure));
static void addfile PROTO((List **listp, char *dir, char *file));
-static char update_dir[PATH_MAX];
+static char *update_dir;
static char *repository = NULL;
static List *filelist = NULL; /* holds list of files on which to operate */
static List *dirlist = NULL; /* holds list of directories on which to operate */
@@ -123,9 +123,9 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
expand_wild (argc, argv, &argc, &argv);
if (update_preload == NULL)
- update_dir[0] = '\0';
+ update_dir = xstrdup ("");
else
- (void) strcpy (update_dir, update_preload);
+ update_dir = xstrdup (update_preload);
/* clean up from any previous calls to start_recursion */
if (repository)
@@ -155,7 +155,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
addlist (&dirlist, ".");
err += do_recursion (&frame);
- return(err);
+ goto out;
}
@@ -183,7 +183,6 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
/* otherwise, split argument into directory and component names. */
char *dir;
char *comp;
- char tmp[PATH_MAX];
char *file_to_try;
/* Now break out argv[i] into directory part (DIR) and file part (COMP).
@@ -209,42 +208,47 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
if (!(which & W_LOCAL))
{
/* If doing rtag, we've done a chdir to the repository. */
- sprintf (tmp, "%s%s", argv[i], RCSEXT);
- file_to_try = tmp;
+ file_to_try = xmalloc (strlen (argv[i]) + sizeof (RCSEXT) + 5);
+ sprintf (file_to_try, "%s%s", argv[i], RCSEXT);
}
else
- file_to_try = argv[i];
+ file_to_try = xstrdup (argv[i]);
- if(isfile(file_to_try))
+ if (isfile (file_to_try))
addfile (&files_by_dir, dir, comp);
else if (isdir (dir))
{
if ((which & W_LOCAL) && isdir (CVSADM))
{
/* otherwise, look for it in the repository. */
- char *save_update_dir;
+ char *tmp_update_dir;
char *repos;
-
- /* save & set (aka push) update_dir */
- save_update_dir = xstrdup (update_dir);
+ char *reposfile;
+
+ tmp_update_dir = xmalloc (strlen (update_dir)
+ + strlen (dir)
+ + 5);
+ strcpy (tmp_update_dir, update_dir);
- if (*update_dir != '\0')
- (void) strcat (update_dir, "/");
+ if (*tmp_update_dir != '\0')
+ (void) strcat (tmp_update_dir, "/");
+
+ (void) strcat (tmp_update_dir, dir);
- (void) strcat (update_dir, dir);
-
/* look for it in the repository. */
- repos = Name_Repository (dir, update_dir);
- (void) sprintf (tmp, "%s/%s", repos, comp);
+ repos = Name_Repository (dir, tmp_update_dir);
+ reposfile = xmalloc (strlen (repos)
+ + strlen (comp)
+ + 5);
+ (void) sprintf (reposfile, "%s/%s", repos, comp);
free (repos);
- if (!wrap_name_has (comp, WRAP_TOCVS) && isdir(tmp))
+ if (!wrap_name_has (comp, WRAP_TOCVS) && isdir (reposfile))
addlist (&dirlist, argv[i]);
else
addfile (&files_by_dir, dir, comp);
- (void) sprintf (update_dir, "%s", save_update_dir);
- free (save_update_dir);
+ free (tmp_update_dir);
}
else
addfile (&files_by_dir, dir, comp);
@@ -252,6 +256,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
else
error (1, 0, "no such directory `%s'", dir);
+ free (file_to_try);
free (dir);
free (comp);
}
@@ -272,6 +277,9 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
free (argv[i]);
free (argv);
+ out:
+ free (update_dir);
+ update_dir = NULL;
return (err);
}
@@ -351,8 +359,9 @@ do_recursion (frame)
}
else
{
- repository = xmalloc (PATH_MAX);
- (void) getwd (repository);
+ repository = xgetwd ();
+ if (repository == NULL)
+ error (1, errno, "could not get working directory");
}
srepository = repository; /* remember what to free */
@@ -545,7 +554,7 @@ do_dir_proc (p, closure)
struct recursion_frame *frame = frent->frame;
struct recursion_frame xframe;
char *dir = p->key;
- char newrepos[PATH_MAX];
+ char *newrepos;
List *sdirlist;
char *srepository;
char *cp;
@@ -553,6 +562,13 @@ do_dir_proc (p, closure)
int stripped_dot = 0;
int err = 0;
struct saved_cwd cwd;
+ char *saved_update_dir;
+
+ saved_update_dir = update_dir;
+ update_dir = xmalloc (strlen (saved_update_dir)
+ + strlen (dir)
+ + 5);
+ strcpy (update_dir, saved_update_dir);
/* set up update_dir - skip dots if not at start */
if (strcmp (dir, ".") != 0)
@@ -573,9 +589,12 @@ do_dir_proc (p, closure)
* update -d and in that case the generated name will be correct.
*/
if (repository == NULL)
- newrepos[0] = '\0';
+ newrepos = xstrdup ("");
else
+ {
+ newrepos = xmalloc (strlen (repository) + strlen (dir) + 5);
(void) sprintf (newrepos, "%s/%s", repository, dir);
+ }
}
else
{
@@ -583,15 +602,16 @@ do_dir_proc (p, closure)
(void) strcpy (update_dir, dir);
if (repository == NULL)
- newrepos[0] = '\0';
+ newrepos = xstrdup ("");
else
- (void) strcpy (newrepos, repository);
+ newrepos = xstrdup (repository);
}
/* call-back dir entry proc (if any) */
if (frame->direntproc != NULL)
dir_return = frame->direntproc (frame->callerdat, dir, newrepos,
update_dir, frent->entries);
+ free (newrepos);
/* only process the dir if the return code was 0 */
if (dir_return != R_SKIP_ALL)
@@ -640,12 +660,16 @@ do_dir_proc (p, closure)
repository = srepository;
}
- /* put back update_dir */
+ /* Put back update_dir. I think this is the same as just setting
+ update_dir back to saved_update_dir, but there are a few cases I'm
+ not sure about (in particular, if DIR is "." and update_dir is
+ not ""), so for conservatism I'm leaving this here. */
cp = last_component (update_dir);
if (cp > update_dir)
cp[-1] = '\0';
else
update_dir[0] = '\0';
+ free (saved_update_dir);
return (err);
}
@@ -722,7 +746,11 @@ unroll_files_proc (p, closure)
if ( CVS_CHDIR (p->key) < 0)
error (1, errno, "could not chdir to %s", p->key);
- save_update_dir = xstrdup (update_dir);
+ save_update_dir = update_dir;
+ update_dir = xmalloc (strlen (save_update_dir)
+ + strlen (p->key)
+ + 5);
+ strcpy (update_dir, save_update_dir);
if (*update_dir != '\0')
(void) strcat (update_dir, "/");
@@ -734,8 +762,8 @@ unroll_files_proc (p, closure)
if (save_update_dir != NULL)
{
- (void) strcpy (update_dir, save_update_dir);
- free (save_update_dir);
+ free (update_dir);
+ update_dir = save_update_dir;
if (restore_cwd (&cwd, NULL))
error_exit ();
diff --git a/gnu/usr.bin/cvs/src/release.c b/gnu/usr.bin/cvs/src/release.c
index 8e5c992d3d0..d387e6e5b7b 100644
--- a/gnu/usr.bin/cvs/src/release.c
+++ b/gnu/usr.bin/cvs/src/release.c
@@ -6,6 +6,7 @@
*/
#include "cvs.h"
+#include "getline.h"
static void release_delete PROTO((char *dir));
@@ -64,7 +65,9 @@ release (argc, argv)
FILE *fp;
int i, c;
char *repository;
- char line[PATH_MAX], update_cmd[PATH_MAX];
+ char *line = NULL;
+ size_t line_allocated = 0;
+ char *update_cmd;
char *thisarg;
int arg_start_idx;
int err = 0;
@@ -106,6 +109,9 @@ release (argc, argv)
* questions asked. Else we prompt, then maybe release.
*/
/* Construct the update command. */
+ update_cmd = xmalloc (strlen (program_path)
+ + strlen (CVSroot_original)
+ + 20);
sprintf (update_cmd, "%s -n -q -d %s update",
program_path, CVSroot_original);
@@ -159,7 +165,7 @@ release (argc, argv)
fp = run_popen (update_cmd, "r");
c = 0;
- while (fgets (line, sizeof (line), fp))
+ while (getline (&line, &line_allocated, fp) >= 0)
{
if (strchr ("MARCZ", *line))
c++;
@@ -242,6 +248,9 @@ release (argc, argv)
}
#endif /* CLIENT_SUPPORT */
+ free (update_cmd);
+ if (line != NULL)
+ free (line);
return err;
}
diff --git a/gnu/usr.bin/cvs/src/remove.c b/gnu/usr.bin/cvs/src/remove.c
index 08a67bed58c..6f31e0acb55 100644
--- a/gnu/usr.bin/cvs/src/remove.c
+++ b/gnu/usr.bin/cvs/src/remove.c
@@ -17,6 +17,10 @@
#include "cvs.h"
+#ifdef CLIENT_SUPPORT
+static int remove_force_fileproc PROTO ((void *callerdat,
+ struct file_info *finfo));
+#endif
static int remove_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static Dtype remove_dirproc PROTO ((void *callerdat, char *dir,
char *repos, char *update_dir,
@@ -82,15 +86,10 @@ cvsremove (argc, argv)
{
if (!noexec)
{
- int i;
-
- for (i = 0; i < argc; i++)
- {
- if ( CVS_UNLINK (argv[i]) < 0 && ! existence_error (errno))
- {
- error (0, errno, "unable to remove %s", argv[i]);
- }
- }
+ start_recursion (remove_force_fileproc, (FILESDONEPROC) NULL,
+ (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL,
+ (void *) NULL, argc, argv, local, W_LOCAL,
+ 0, 0, (char *) NULL, 0);
}
/* else FIXME should probably act as if the file doesn't exist
in doing the following checks. */
@@ -101,7 +100,7 @@ cvsremove (argc, argv)
if (local)
send_arg("-l");
send_file_names (argc, argv, 0);
- send_files (argc, argv, local, 0, 0);
+ send_files (argc, argv, local, 0, 0, 0);
send_to_server ("remove\012", 0);
return get_responses_and_close ();
}
@@ -127,6 +126,26 @@ cvsremove (argc, argv)
return (err);
}
+#ifdef CLIENT_SUPPORT
+
+/*
+ * This is called via start_recursion if we are running as the client
+ * and the -f option was used. We just physically remove the file.
+ */
+
+/*ARGSUSED*/
+static int
+remove_force_fileproc (callerdat, finfo)
+ void *callerdat;
+ struct file_info *finfo;
+{
+ if (CVS_UNLINK (finfo->file) < 0 && ! existence_error (errno))
+ error (0, errno, "unable to remove %s", finfo->fullname);
+ return 0;
+}
+
+#endif
+
/*
* remove the file, only if it has already been physically removed
*/
@@ -136,7 +155,6 @@ remove_fileproc (callerdat, finfo)
void *callerdat;
struct file_info *finfo;
{
- char fname[PATH_MAX];
Vers_TS *vers;
if (force)
@@ -168,11 +186,17 @@ remove_fileproc (callerdat, finfo)
}
else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
{
+ char *fname;
+
/*
* It's a file that has been added, but not commited yet. So,
* remove the ,t file for it and scratch it from the
* entries file. */
Scratch_Entry (finfo->entries, finfo->file);
+ fname = xmalloc (strlen (finfo->file)
+ + sizeof (CVSADM)
+ + sizeof (CVSEXT_LOG)
+ + 10);
(void) sprintf (fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
(void) unlink_file (fname);
if (!quiet)
@@ -182,6 +206,7 @@ remove_fileproc (callerdat, finfo)
if (server_active)
server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
#endif
+ free (fname);
}
else if (vers->vn_user[0] == '-')
{
@@ -191,7 +216,10 @@ remove_fileproc (callerdat, finfo)
}
else
{
+ char *fname;
+
/* Re-register it with a negative version number. */
+ fname = xmalloc (strlen (vers->vn_user) + 5);
(void) strcpy (fname, "-");
(void) strcat (fname, vers->vn_user);
Register (finfo->entries, finfo->file, fname, vers->ts_rcs, vers->options,
@@ -204,6 +232,7 @@ remove_fileproc (callerdat, finfo)
if (server_active)
server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
#endif
+ free (fname);
}
freevers_ts (&vers);
diff --git a/gnu/usr.bin/cvs/src/repos.c b/gnu/usr.bin/cvs/src/repos.c
index d774c342120..2590df5a930 100644
--- a/gnu/usr.bin/cvs/src/repos.c
+++ b/gnu/usr.bin/cvs/src/repos.c
@@ -7,6 +7,7 @@
*/
#include "cvs.h"
+#include "getline.h"
/* Determine the name of the RCS repository for directory DIR in the
current working directory, or for the current working directory
@@ -23,10 +24,10 @@ Name_Repository (dir, update_dir)
char *update_dir;
{
FILE *fpin;
- char *ret, *xupdate_dir;
- char repos[PATH_MAX];
- char path[PATH_MAX];
- char tmp[PATH_MAX];
+ char *xupdate_dir;
+ char *repos = NULL;
+ size_t repos_allocated = 0;
+ char *tmp;
char *cp;
if (update_dir && *update_dir)
@@ -35,9 +36,12 @@ Name_Repository (dir, update_dir)
xupdate_dir = ".";
if (dir != NULL)
+ {
+ tmp = xmalloc (strlen (dir) + sizeof (CVSADM_REP) + 10);
(void) sprintf (tmp, "%s/%s", dir, CVSADM_REP);
+ }
else
- (void) strcpy (tmp, CVSADM_REP);
+ tmp = xstrdup (CVSADM_REP);
/*
* The assumption here is that the repository is always contained in the
@@ -48,12 +52,15 @@ Name_Repository (dir, update_dir)
if (fpin == NULL)
{
int save_errno = errno;
- char cvsadm[PATH_MAX];
+ char *cvsadm;
if (dir != NULL)
+ {
+ cvsadm = xmalloc (strlen (dir) + sizeof (CVSADM) + 10);
(void) sprintf (cvsadm, "%s/%s", dir, CVSADM);
+ }
else
- (void) strcpy (cvsadm, CVSADM);
+ cvsadm = xstrdup (CVSADM);
if (!isdir (cvsadm))
{
@@ -61,6 +68,7 @@ Name_Repository (dir, update_dir)
error (1, 0, "there is no version here; do '%s checkout' first",
program_name);
}
+ free (cvsadm);
if (existence_error (save_errno))
{
@@ -78,9 +86,11 @@ Name_Repository (dir, update_dir)
error (1, save_errno, "cannot open %s", tmp);
}
+ free (tmp);
- if (fgets (repos, PATH_MAX, fpin) == NULL)
+ if (getline (&repos, &repos_allocated, fpin) < 0)
{
+ /* FIXME: should be checking for end of file separately. */
error (0, 0, "in directory %s:", xupdate_dir);
error (1, errno, "cannot read %s", CVSADM_REP);
}
@@ -101,6 +111,8 @@ Name_Repository (dir, update_dir)
}
if (! isabsolute(repos))
{
+ char *newrepos;
+
if (CVSroot_original == NULL)
{
error (0, 0, "in directory %s:", xupdate_dir);
@@ -108,14 +120,14 @@ Name_Repository (dir, update_dir)
error (0, 0, "or specify the '-d' option to %s.", program_name);
error (1, 0, "illegal repository setting");
}
- (void) strcpy (path, repos);
- (void) sprintf (repos, "%s/%s", CVSroot_directory, path);
+ newrepos = xmalloc (strlen (CVSroot_directory) + strlen (repos) + 10);
+ (void) sprintf (newrepos, "%s/%s", CVSroot_directory, repos);
+ free (repos);
+ repos = newrepos;
}
- /* allocate space to return and fill it in */
strip_trailing_slashes (repos);
- ret = xstrdup (repos);
- return (ret);
+ return repos;
}
/*
diff --git a/gnu/usr.bin/cvs/src/root.c b/gnu/usr.bin/cvs/src/root.c
index 71e8f2883df..1e38c31478a 100644
--- a/gnu/usr.bin/cvs/src/root.c
+++ b/gnu/usr.bin/cvs/src/root.c
@@ -12,6 +12,7 @@
*/
#include "cvs.h"
+#include "getline.h"
/* Printable names for things in the CVSroot_method enum variable.
Watch out if the enum is changed in cvs.h! */
@@ -29,9 +30,10 @@ Name_Root(dir, update_dir)
{
FILE *fpin;
char *ret, *xupdate_dir;
- char root[PATH_MAX];
- char tmp[PATH_MAX];
- char cvsadm[PATH_MAX];
+ char *root = NULL;
+ size_t root_allocated = 0;
+ char *tmp;
+ char *cvsadm;
char *cp;
if (update_dir && *update_dir)
@@ -41,13 +43,15 @@ Name_Root(dir, update_dir)
if (dir != NULL)
{
+ cvsadm = xmalloc (strlen (dir) + sizeof (CVSADM) + 10);
(void) sprintf (cvsadm, "%s/%s", dir, CVSADM);
+ tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ROOT) + 10);
(void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
}
else
{
- (void) strcpy (cvsadm, CVSADM);
- (void) strcpy (tmp, CVSADM_ROOT);
+ cvsadm = xstrdup (CVSADM);
+ tmp = xstrdup (CVSADM_ROOT);
}
/*
@@ -59,7 +63,10 @@ Name_Root(dir, update_dir)
* /path/name or have the environment variable CVSROOT set in
* order to continue. */
if ((!isdir (cvsadm)) || (!isreadable (tmp)))
- return (NULL);
+ {
+ ret = NULL;
+ goto out;
+ }
/*
* The assumption here is that the CVS Root is always contained in the
@@ -67,12 +74,15 @@ Name_Root(dir, update_dir)
*/
fpin = open_file (tmp, "r");
- if (fgets (root, PATH_MAX, fpin) == NULL)
+ if (getline (&root, &root_allocated, fpin) < 0)
{
+ /* FIXME: should be checking for end of file separately; errno
+ is not set in that case. */
error (0, 0, "in directory %s:", xupdate_dir);
error (0, errno, "cannot read %s", CVSADM_ROOT);
error (0, 0, "please correct this problem");
- return (NULL);
+ ret = NULL;
+ goto out;
}
(void) fclose (fpin);
if ((cp = strrchr (root, '\n')) != NULL)
@@ -93,7 +103,8 @@ Name_Root(dir, update_dir)
error (0, 0,
"ignoring %s because it does not contain an absolute pathname.",
CVSADM_ROOT);
- return (NULL);
+ ret = NULL;
+ goto out;
}
#ifdef CLIENT_SUPPORT
@@ -106,12 +117,18 @@ Name_Root(dir, update_dir)
error (0, 0,
"ignoring %s because it specifies a non-existent repository %s",
CVSADM_ROOT, root);
- return (NULL);
+ ret = NULL;
+ goto out;
}
/* allocate space to return and fill it in */
strip_trailing_slashes (root);
ret = xstrdup (root);
+ out:
+ free (cvsadm);
+ free (tmp);
+ if (root != NULL)
+ free (root);
return (ret);
}
@@ -153,7 +170,7 @@ Create_Root (dir, rootdir)
char *rootdir;
{
FILE *fout;
- char tmp[PATH_MAX];
+ char *tmp;
if (noexec)
return;
@@ -163,14 +180,19 @@ Create_Root (dir, rootdir)
if (rootdir != NULL)
{
if (dir != NULL)
+ {
+ tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ROOT) + 10);
(void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
+ }
else
- (void) strcpy (tmp, CVSADM_ROOT);
+ tmp = xstrdup (CVSADM_ROOT);
+
fout = open_file (tmp, "w+");
if (fprintf (fout, "%s\n", rootdir) < 0)
error (1, errno, "write to %s failed", tmp);
if (fclose (fout) == EOF)
error (1, errno, "cannot close %s", tmp);
+ free (tmp);
}
}
@@ -349,6 +371,14 @@ parse_cvsroot (CVSroot)
error (0, 0, "(%s)", CVSroot);
return 1;
}
+ /* cvs.texinfo has always told people that CVSROOT must be an
+ absolute pathname. Furthermore, attempts to use a relative
+ pathname produced various errors (I couldn't get it to work),
+ so there would seem to be little risk in making this a fatal
+ error. */
+ if (!isabsolute (CVSroot_directory))
+ error (1, 0, "CVSROOT %s must be an absolute pathname",
+ CVSroot_directory);
break;
case kserver_method:
#ifndef HAVE_KERBEROS
diff --git a/gnu/usr.bin/cvs/src/rtag.c b/gnu/usr.bin/cvs/src/rtag.c
index dfc3c9364eb..d499e0b3fe5 100644
--- a/gnu/usr.bin/cvs/src/rtag.c
+++ b/gnu/usr.bin/cvs/src/rtag.c
@@ -164,9 +164,11 @@ rtag (argc, argv)
{
/* We're the client side. Fire up the remote server. */
start_server ();
-
+
ign_setup ();
+ if (!force_tag_match)
+ send_arg ("-f");
if (local)
send_arg("-l");
if (delete_flag)
@@ -175,7 +177,7 @@ rtag (argc, argv)
send_arg("-b");
if (force_tag_move)
send_arg("-F");
- if (run_module_prog)
+ if (!run_module_prog)
send_arg("-n");
if (attic_too)
send_arg("-a");
@@ -229,19 +231,25 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
char *mname;
char *msg;
{
+ /* Begin section which is identical to patch_proc--should this
+ be abstracted out somehow? */
int err = 0;
int which;
- char repository[PATH_MAX];
- char where[PATH_MAX];
+ char *repository;
+ char *where;
+ repository = xmalloc (strlen (CVSroot_directory) + strlen (argv[0])
+ + (mfile == NULL ? 0 : strlen (mfile)) + 30);
(void) sprintf (repository, "%s/%s", CVSroot_directory, argv[0]);
+ where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile))
+ + 10);
(void) strcpy (where, argv[0]);
/* if mfile isn't null, we need to set up to do only part of the module */
if (mfile != NULL)
{
char *cp;
- char path[PATH_MAX];
+ char *path;
/* if the portion of the module is a path, put the dir part on repos */
if ((cp = strrchr (mfile, '/')) != NULL)
@@ -255,6 +263,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
}
/* take care of the rest */
+ path = xmalloc (strlen (repository) + strlen (mfile) + 5);
(void) sprintf (path, "%s/%s", repository, mfile);
if (isdir (path))
{
@@ -273,14 +282,18 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
argv[1] = xstrdup (mfile);
(*pargc) = 2;
}
+ free (path);
}
- /* chdir to the starting directory */
+ /* cd to the starting repository */
if ( CVS_CHDIR (repository) < 0)
{
error (0, errno, "cannot chdir to %s", repository);
+ free (repository);
return (1);
}
+ free (repository);
+ /* End section which is identical to patch_proc. */
if (delete_flag || attic_too || (force_tag_match && numtag))
which = W_REPOS | W_ATTIC;
@@ -312,7 +325,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
(DIRLEAVEPROC) NULL, NULL,
*pargc - 1, argv + 1, local,
which, 0, 0, where, 1);
-
+ free (where);
dellist(&mtlist);
return (err);
diff --git a/gnu/usr.bin/cvs/src/run.c b/gnu/usr.bin/cvs/src/run.c
index df594312a8f..74e418dc3ed 100644
--- a/gnu/usr.bin/cvs/src/run.c
+++ b/gnu/usr.bin/cvs/src/run.c
@@ -28,10 +28,11 @@
#endif
static void run_add_arg PROTO((const char *s));
-static void run_init_prog PROTO((void));
extern char *strtok ();
+extern int vasprintf ();
+
/*
* To exec a program under CVS, first call run_setup() to setup any initial
* arguments. The options to run_setup are essentially like printf(). The
@@ -45,7 +46,6 @@ extern char *strtok ();
* The execvp() syscall will be used, so that the PATH is searched correctly.
* File redirections can be performed in the call to run_exec().
*/
-static char *run_prog;
static char **run_argv;
static int run_argc;
static int run_argc_allocated;
@@ -66,8 +66,7 @@ run_setup (fmt, va_alist)
#endif
char *cp;
int i;
-
- run_init_prog ();
+ char *run_prog;
/* clean out any malloc'ed values from run_argv */
for (i = 0; i < run_argc; i++)
@@ -83,15 +82,18 @@ run_setup (fmt, va_alist)
/* process the varargs into run_prog */
#ifdef HAVE_VPRINTF
VA_START (args, fmt);
- (void) vsprintf (run_prog, fmt, args);
+ (void) vasprintf (&run_prog, fmt, args);
va_end (args);
#else
- (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
+ you lose
#endif
+ if (run_prog == NULL)
+ error (1, 0, "out of memory");
/* put each word into run_argv, allocating it as we go */
for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
run_add_arg (cp);
+ free (run_prog);
}
void
@@ -115,20 +117,22 @@ run_args (fmt, va_alist)
#ifdef HAVE_VPRINTF
va_list args;
#endif
-
- run_init_prog ();
+ char *run_prog;
/* process the varargs into run_prog */
#ifdef HAVE_VPRINTF
VA_START (args, fmt);
- (void) vsprintf (run_prog, fmt, args);
+ (void) vasprintf (&run_prog, fmt, args);
va_end (args);
#else
- (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
+ you lose
#endif
+ if (run_prog == NULL)
+ error (1, 0, "out of memory");
/* and add the (single) argument to the run_argv list */
run_add_arg (run_prog);
+ free (run_prog);
}
static void
@@ -149,14 +153,6 @@ run_add_arg (s)
run_argv[run_argc] = (char *) 0; /* not post-incremented on purpose! */
}
-static void
-run_init_prog ()
-{
- /* make sure that run_prog is allocated once */
- if (run_prog == (char *) 0)
- run_prog = xmalloc (10 * 1024); /* 10K of args for _setup and _arg */
-}
-
int
run_exec (stin, stout, sterr, flags)
char *stin;
diff --git a/gnu/usr.bin/cvs/src/sanity.sh b/gnu/usr.bin/cvs/src/sanity.sh
index ecf296cf028..84e678c25bb 100644
--- a/gnu/usr.bin/cvs/src/sanity.sh
+++ b/gnu/usr.bin/cvs/src/sanity.sh
@@ -41,7 +41,7 @@ if test x"$1" = x"-r"; then
remote=yes
# If we're going to do remote testing, make sure 'rsh' works first.
host="`hostname`"
- if test "x`${CVS_RSH-rsh} $host 'echo hi'`" != "xhi"; then
+ if test "x`${CVS_RSH-rsh} $host -n 'echo hi'`" != "xhi"; then
echo "ERROR: cannot test remote CVS, because \`rsh $host' fails." >&2
exit 1
fi
@@ -80,6 +80,11 @@ shift
# special characters we are probably in big trouble.
PROG=`basename ${testcvs}`
+# Regexp to match an author name. I'm not really sure what characters
+# should be here. a-zA-Z obviously. People complained when 0-9 were
+# not allowed in usernames. Other than that I'm not sure.
+username="[a-zA-Z0-9][a-zA-Z0-9]*"
+
# FIXME: try things (what things? checkins?) without -m.
#
# Some of these tests are written to expect -Q. But testing with
@@ -451,7 +456,7 @@ HOME=${TESTDIR}/home; export HOME
# tests.
if test x"$*" = x; then
- tests="basica basicb basic1 deep basic2 rdiff death death2 branches multibranch import join new newb conflicts conflicts2 modules modules2 mflag errmsg1 devcom devcom2 ignore binfiles binwrap info serverpatch log log2 crerepos rcs"
+ tests="basica basicb basic1 deep basic2 rdiff death death2 branches multibranch import join new newb conflicts conflicts2 modules modules2 modules3 mflag errmsg1 devcom devcom2 devcom3 ignore binfiles binwrap info serverpatch log log2 crerepos rcs big modes"
else
tests="$*"
fi
@@ -526,7 +531,7 @@ for what in $tests; do
dotest basica-0a "${testcvs} -q co -l ." ''
mkdir first-dir
dotest basica-0b "${testcvs} add first-dir" \
-"Directory /tmp/cvs-sanity/cvsroot/\./first-dir added to the repository"
+"Directory /tmp/cvs-sanity/cvsroot/first-dir added to the repository"
cd ..
rm -rf 1
@@ -626,6 +631,22 @@ done'
'"${PROG}"' \[[a-z]* aborted\]: correct above errors first!'
dotest basica-8 "${testcvs} -q update" ''
+ # Test the -f option to ci
+ cd sdir/ssdir
+ dotest basica-8a "${testcvs} -q ci -f -m force-it" \
+'Checking in ssfile;
+/tmp/cvs-sanity/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile
+new revision: 1\.3; previous revision: 1\.2
+done'
+ cd ../..
+ dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" \
+'Index: sdir/ssdir/ssfile
+===================================================================
+RCS file: /tmp/cvs-sanity/cvsroot/first-dir/sdir/ssdir/ssfile,v
+retrieving revision 1\.2
+retrieving revision 1\.3
+diff -r1\.2 -r1\.3'
+
# The .* here will normally be "No such file or directory",
# but if memory serves some systems (AIX?) have a different message.
: dotest_fail basica-9 \
@@ -638,8 +659,8 @@ done'
dotest basica-10 "${testcvs} annotate" \
'Annotations for sdir/ssdir/ssfile
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1 .[a-z0-9@][a-z0-9@ ]* [0-9a-zA-Z-]*.: ssfile
-1\.2 .[a-z0-9@][a-z0-9@ ]* [0-9a-zA-Z-]*.: ssfile line 2'
+1\.1 .'"${username}"' *[0-9a-zA-Z-]*.: ssfile
+1\.2 .'"${username}"' *[0-9a-zA-Z-]*.: ssfile line 2'
cd ..
rm -rf ${CVSROOT_DIRNAME}/first-dir
@@ -648,7 +669,30 @@ done'
basicb)
# More basic tests, including non-branch tags and co -d.
- mkdir ${CVSROOT_DIRNAME}/first-dir
+ mkdir 1; cd 1
+ dotest basicb-0a "${testcvs} -q co -l ." ''
+ touch topfile
+ dotest basicb-0b "${testcvs} add topfile" \
+"${PROG} [a-z]*: scheduling file .topfile. for addition
+${PROG} [a-z]*: use .cvs commit. to add this file permanently"
+ dotest basicb-0c "${testcvs} -q ci -m add-it topfile" \
+'RCS file: /tmp/cvs-sanity/cvsroot/./topfile,v
+done
+Checking in topfile;
+/tmp/cvs-sanity/cvsroot/./topfile,v <-- topfile
+initial revision: 1\.1
+done'
+ cd ..
+ rm -rf 1
+ mkdir 2; cd 2
+ dotest basicb-0d "${testcvs} -q co -l ." "U topfile"
+ mkdir first-dir
+ dotest basicb-0e "${testcvs} add first-dir" \
+"Directory /tmp/cvs-sanity/cvsroot/first-dir added to the repository"
+ cd ..
+ rm -rf 2
+
+: mkdir ${CVSROOT_DIRNAME}/first-dir
dotest basicb-1 "${testcvs} -q co first-dir" ''
dotest basicb-1a "test -d CVS" ''
cd first-dir
@@ -714,6 +758,10 @@ T sdir2/sfile2'
/tmp/cvs-sanity/cvsroot/first-dir/sdir2/sfile2,v <-- sfile2
new revision: 1\.2; previous revision: 1\.1
done'
+ # See if CVS can correctly notice when an invalid numeric
+ # revision is specified.
+ # Commented out until we get around to fixing CVS
+: dotest basicb-8a0 "${testcvs} diff -r 1.5 -r 1.7 sfile2" 'error msg'
cd ..
# Test that we recurse into the correct directory when checking
@@ -737,6 +785,7 @@ sfile2 starts"
rm -rf newdir
rm -rf ${CVSROOT_DIRNAME}/first-dir
+ rm -f ${CVSROOT_DIRNAME}/topfile,v
;;
basic1) # first dive - add a files, first singly, then in a group.
@@ -965,7 +1014,27 @@ done'
dotest deep-rm5 "${testcvs} -q update -d -P" ''
dotest_fail deep-rm6 "test -d dir7" ''
- cd ../../../../../../..
+ # Test rm -f -R.
+ cd ../..
+ dotest deep-rm7 "${testcvs} rm -f -R dir5" \
+"${PROG} [a-z]*: Removing dir5
+${PROG} [a-z]*: scheduling .dir5/file1. for removal
+${PROG} [a-z]*: Removing dir5/dir6
+${PROG} [a-z]*: scheduling .dir5/dir6/file1. for removal
+${PROG} [a-z]*: use .${PROG} commit. to remove these files permanently"
+ dotest deep-rm8 "${testcvs} -q ci -m rm-it" \
+'Removing dir5/file1;
+/tmp/cvs-sanity/cvsroot/first-dir/dir1/dir2/dir3/dir4/dir5/file1,v <-- file1
+new revision: delete; previous revision: 1\.1
+done
+Removing dir5/dir6/file1;
+/tmp/cvs-sanity/cvsroot/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/file1,v <-- file1
+new revision: delete; previous revision: 1\.1
+done'
+ dotest deep-rm9 "${testcvs} -q update -d -P" ''
+ dotest_fail deep-rm10 "test -d dir5"
+
+ cd ../../../../..
if echo "yes" | ${testcvs} release -d first-dir >>${LOGFILE}; then
pass deep-5
@@ -1429,10 +1498,10 @@ diff -c trdiff/foo:1\.1\.1\.1 trdiff/foo:1\.2
--- trdiff/foo .*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 1,2 \*\*\*\*
-! \$''Id: foo,v 1\.1\.1\.1 [0-9/]* [0-9:]* [a-zA-Z0-9][a-zA-Z0-9]* Exp \$
+! \$''Id: foo,v 1\.1\.1\.1 [0-9/]* [0-9:]* '"${username}"' Exp \$
! \$''Name: T1 \$
--- 1,3 ----
-! \$''Id: foo,v 1\.2 [0-9/]* [0-9:]* [a-zA-Z0-9][a-zA-Z0-9]* Exp \$
+! \$''Id: foo,v 1\.2 [0-9/]* [0-9:]* '"${username}"' Exp \$
! \$''Name: local-v0 \$
! something
Index: trdiff/new
@@ -1442,7 +1511,7 @@ diff -c /dev/null trdiff/new:1\.1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\*\* 0 \*\*\*\*
--- 1,2 ----
-'"${PLUS}"' #ident "@(#)trdiff:\$''Name: local-v0 \$:\$''Id: new,v 1\.1 [0-9/]* [0-9:]* [a-zA-Z0-9][a-zA-Z0-9]* Exp \$"
+'"${PLUS}"' #ident "@(#)trdiff:\$''Name: local-v0 \$:\$''Id: new,v 1\.1 [0-9/]* [0-9:]* '"${username}"' Exp \$"
'"${PLUS}"' new file'
# FIXME: will this work here?
@@ -1621,10 +1690,7 @@ T file2'
echo "FAIL: test 76" | tee -a ${LOGFILE} ; exit 1
fi
- # Remote CVS outputs nothing for 76a0 and 76a1; until
- # this bug is fixed just skip those tests for remote.
- if test "x$remote" = xno; then
- dotest death-76a0 \
+ dotest death-76a0 \
"${testcvs} -q rdiff -r bp_branch1 -r branch1 first-dir" \
"Index: first-dir/file3
diff -c /dev/null first-dir/file3:1\.1\.2\.1
@@ -1634,7 +1700,7 @@ diff -c /dev/null first-dir/file3:1\.1\.2\.1
\*\*\* 0 \*\*\*\*
--- 1 ----
${PLUS} line1 from branch1"
- dotest death-76a1 \
+ dotest death-76a1 \
"${testcvs} -q rdiff -r branch1 -r bp_branch1 first-dir" \
'Index: first-dir/file3
diff -c first-dir/file3:1\.1\.2\.1 first-dir/file3:removed
@@ -1644,7 +1710,6 @@ diff -c first-dir/file3:1\.1\.2\.1 first-dir/file3:removed
\*\*\* 1 \*\*\*\*
- line1 from branch1
--- 0 ----'
- fi
# remove
rm file3
@@ -2395,16 +2460,16 @@ total revisions: 3; selected revisions: 3
description:
----------------------------
revision 1\.1
-date: [0-9/]* [0-9:]*; author: [0-9a-zA-Z-]*; state: Exp;
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
branches: 1\.1\.2; 1\.1\.4;
add-it
----------------------------
revision 1\.1\.4\.1
-date: [0-9/]* [0-9:]*; author: [0-9a-zA-Z-]*; state: Exp; lines: ${PLUS}1 -0
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0
modify-on-br2
----------------------------
revision 1\.1\.2\.1
-date: [0-9/]* [0-9:]*; author: [0-9a-zA-Z-]*; state: Exp; lines: ${PLUS}1 -1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1
modify-on-br1
============================================================================="
cd ..
@@ -2423,7 +2488,7 @@ modify-on-br1
mkdir import-dir ; cd import-dir
for i in 1 2 3 4 ; do
- echo imported file"$i" > imported-file"$i"
+ echo imported file"$i" > imported-f"$i"
done
# This directory should be on the default ignore list,
@@ -2431,8 +2496,8 @@ modify-on-br1
mkdir RCS
echo ignore.me >RCS/ignore.me
- echo 'import should not expand $''Id$' >>imported-file2
- cp imported-file2 ../imported-file2-orig.tmp
+ echo 'import should not expand $''Id$' >>imported-f2
+ cp imported-f2 ../imported-f2-orig.tmp
if ${CVS} import -m first-import first-dir vendor-branch junk-1_0 ; then
echo "PASS: test 96" >>${LOGFILE}
@@ -2440,7 +2505,7 @@ modify-on-br1
echo "FAIL: test 96" | tee -a ${LOGFILE} ; exit 1
fi
- if cmp ../imported-file2-orig.tmp imported-file2; then
+ if cmp ../imported-f2-orig.tmp imported-f2; then
pass 96.5
else
fail 96.5
@@ -2456,7 +2521,7 @@ modify-on-br1
cd first-dir
for i in 1 2 3 4 ; do
- if test -f imported-file"$i" ; then
+ if test -f imported-f"$i" ; then
echo "PASS: test 98-$i" >>${LOGFILE}
else
echo "FAIL: test 98-$i" | tee -a ${LOGFILE} ; exit 1
@@ -2469,15 +2534,15 @@ modify-on-br1
fi
# remove
- rm imported-file1
- if ${CVS} rm imported-file1 2>> ${LOGFILE}; then
+ rm imported-f1
+ if ${CVS} rm imported-f1 2>> ${LOGFILE}; then
echo "PASS: test 99" >>${LOGFILE}
else
echo "FAIL: test 99" | tee -a ${LOGFILE} ; exit 1
fi
# change
- echo local-change >> imported-file2
+ echo local-change >> imported-f2
# commit
if ${CVS} ci -m local-changes >> ${LOGFILE} 2>&1; then
@@ -2487,7 +2552,7 @@ modify-on-br1
fi
# log
- if ${CVS} log imported-file1 | grep '1.1.1.2 (dead)' ; then
+ if ${CVS} log imported-f1 | grep '1.1.1.2 (dead)' ; then
echo "FAIL: test 101" | tee -a ${LOGFILE} ; exit 1
else
echo "PASS: test 101" >>${LOGFILE}
@@ -2501,16 +2566,16 @@ modify-on-br1
fi
# remove file4 on the vendor branch
- rm imported-file4
+ rm imported-f4
- if ${CVS} rm imported-file4 2>> ${LOGFILE}; then
+ if ${CVS} rm imported-f4 2>> ${LOGFILE}; then
echo "PASS: test 103" >>${LOGFILE}
else
echo "FAIL: test 103" | tee -a ${LOGFILE} ; exit 1
fi
# commit
- if ${CVS} ci -m vendor-removed imported-file4 >>${LOGFILE}; then
+ if ${CVS} ci -m vendor-removed imported-f4 >>${LOGFILE}; then
echo "PASS: test 104" >>${LOGFILE}
else
echo "FAIL: test 104" | tee -a ${LOGFILE} ; exit 1
@@ -2526,16 +2591,16 @@ modify-on-br1
# second import - file4 deliberately unchanged
cd ../import-dir
for i in 1 2 3 ; do
- echo rev 2 of file $i >> imported-file"$i"
+ echo rev 2 of file $i >> imported-f"$i"
done
- cp imported-file2 ../imported-file2-orig.tmp
+ cp imported-f2 ../imported-f2-orig.tmp
if ${CVS} import -m second-import first-dir vendor-branch junk-2_0 ; then
echo "PASS: test 106" >>${LOGFILE}
else
echo "FAIL: test 106" | tee -a ${LOGFILE} ; exit 1
fi
- if cmp ../imported-file2-orig.tmp imported-file2; then
+ if cmp ../imported-f2-orig.tmp imported-f2; then
pass 106.5
else
fail 106.5
@@ -2551,14 +2616,14 @@ modify-on-br1
cd first-dir
- if test -f imported-file1 ; then
+ if test -f imported-f1 ; then
echo "FAIL: test 108" | tee -a ${LOGFILE} ; exit 1
else
echo "PASS: test 108" >>${LOGFILE}
fi
for i in 2 3 ; do
- if test -f imported-file"$i" ; then
+ if test -f imported-f"$i" ; then
echo "PASS: test 109-$i" >>${LOGFILE}
else
echo "FAIL: test 109-$i" | tee -a ${LOGFILE} ; exit 1
@@ -2572,7 +2637,7 @@ modify-on-br1
echo "FAIL: test 110" | tee -a ${LOGFILE} ; exit 1
fi
- if test -f imported-file4 ; then
+ if test -f imported-f4 ; then
echo "PASS: test 111" >>${LOGFILE}
else
echo "FAIL: test 111" | tee -a ${LOGFILE} ; exit 1
@@ -2589,36 +2654,36 @@ modify-on-br1
dotest import-113 \
"${testcvs} -q co -jjunk-1_0 -jjunk-2_0 first-dir" \
-"${PROG}"' [a-z]*: file first-dir/imported-file1 is present in revision junk-2_0
-RCS file: /tmp/cvs-sanity/cvsroot/first-dir/imported-file2,v
+"${PROG}"' [a-z]*: file first-dir/imported-f1 is present in revision junk-2_0
+RCS file: /tmp/cvs-sanity/cvsroot/first-dir/imported-f2,v
retrieving revision 1\.1\.1\.1
retrieving revision 1\.1\.1\.2
-Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into imported-file2
+Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into imported-f2
rcsmerge: warning: conflicts during merge'
cd first-dir
- if test -f imported-file1 ; then
+ if test -f imported-f1 ; then
echo "FAIL: test 114" | tee -a ${LOGFILE} ; exit 1
else
echo "PASS: test 114" >>${LOGFILE}
fi
for i in 2 3 ; do
- if test -f imported-file"$i" ; then
+ if test -f imported-f"$i" ; then
echo "PASS: test 115-$i" >>${LOGFILE}
else
echo "FAIL: test 115-$i" | tee -a ${LOGFILE} ; exit 1
fi
done
- dotest import-116 'cat imported-file2' \
+ dotest import-116 'cat imported-f2' \
'imported file2
-[<]<<<<<< imported-file2
-import should not expand \$''Id: imported-file2,v 1\.2 [0-9/]* [0-9:]* [a-z0-9@][a-z0-9@]* Exp \$
+[<]<<<<<< imported-f2
+import should not expand \$''Id: imported-f2,v 1\.2 [0-9/]* [0-9:]* [a-z0-9@][a-z0-9@]* Exp \$
local-change
[=]======
-import should not expand \$''Id: imported-file2,v 1\.1\.1\.2 [0-9/]* [0-9:]* [a-z0-9@][a-z0-9@]* Exp \$
+import should not expand \$''Id: imported-f2,v 1\.1\.1\.2 [0-9/]* [0-9:]* [a-z0-9@][a-z0-9@]* Exp \$
rev 2 of file 2
[>]>>>>>> 1\.1\.1\.2'
@@ -3189,6 +3254,15 @@ add a line'
'"${PROG}"' \[[a-z]* aborted\]: correct above errors first!'
mkdir dir1
mkdir sdir
+ dotest conflicts-status-0 "${testcvs} status a" \
+"===================================================================
+File: a Status: Needs Merge
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.2 /tmp/cvs-sanity/cvsroot/first-dir/a,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
dotest conflicts-130 "${testcvs} -q update" \
'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/a,v
retrieving revision 1\.1
@@ -3210,22 +3284,58 @@ rcsmerge: warning: conflicts during merge
C a'
rmdir dir1 sdir
+ dotest conflicts-status-1 "${testcvs} status a" \
+"===================================================================
+File: a Status: File had conflicts on merge
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 /tmp/cvs-sanity/cvsroot/first-dir/a,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
dotest_fail conflicts-131 "${testcvs} -q ci -m try" \
"${PROG} [a-z]*: file .a. had a conflict and has not been modified
${PROG} \[[a-z]* aborted\]: correct above errors first!"
echo lame attempt at resolving it >>a
# Try to check in the file with the conflict markers in it.
+ dotest conflicts-status-2 "${testcvs} status a" \
+"===================================================================
+File: a Status: File had conflicts on merge
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 /tmp/cvs-sanity/cvsroot/first-dir/a,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
dotest_fail conflicts-132 "${testcvs} -q ci -m try" \
"${PROG} [a-z]*: file .a. still contains conflict indicators
${PROG} \[[a-z]* aborted\]: correct above errors first!"
echo resolve conflict >a
+ dotest conflicts-status-3 "${testcvs} status a" \
+"===================================================================
+File: a Status: File had conflicts on merge
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 /tmp/cvs-sanity/cvsroot/first-dir/a,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
dotest conflicts-133 "${testcvs} -q ci -m resolved" \
"Checking in a;
/tmp/cvs-sanity/cvsroot/first-dir/a,v <-- a
new revision: 1\.3; previous revision: 1\.2
done"
+ dotest conflicts-status-4 "${testcvs} status a" \
+"===================================================================
+File: a Status: Up-to-date
+
+ Working revision: 1\.3.*
+ Repository revision: 1\.3 /tmp/cvs-sanity/cvsroot/first-dir/a,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
# Now test that we can add a file in one working directory
# and have an update in another get it.
@@ -3777,6 +3887,56 @@ ${PROG} \[[a-z]* aborted\]: cannot expand modules"
rm -rf ${CVSROOT_DIRNAME}/second-dir
;;
+ modules3)
+ # More tests of modules, in particular what happens if several
+ # modules point to the same file.
+
+ # First just set up a directory first-dir and a file file1 in it.
+ mkdir 1; cd 1
+
+ dotest modules3-0 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest modules3-1 "${testcvs} add first-dir" \
+"Directory /tmp/cvs-sanity/cvsroot/first-dir added to the repository"
+
+ cd first-dir
+ echo file1 >file1
+ dotest modules3-2 "${testcvs} add file1" \
+"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
+'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently'
+ dotest modules3-3 "${testcvs} -q ci -m add-it" \
+'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v
+done
+Checking in file1;
+/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done'
+ cd ..
+
+ dotest modules3-4 "${testcvs} -q co CVSROOT/modules" \
+'U CVSROOT/modules'
+ cd CVSROOT
+ cat >modules <<EOF
+mod1 -a first-dir/file1
+bigmod -a mod1 first-dir/file1
+EOF
+ dotest modules3-5 "${testcvs} -q ci -m add-modules" \
+"Checking in modules;
+/tmp/cvs-sanity/cvsroot/CVSROOT/modules,v <-- modules
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+ cd ..
+
+ dotest modules3-6 "${testcvs} -q co bigmod" ''
+ rm -rf first-dir
+ dotest modules3-7 "${testcvs} -q co bigmod" 'U first-dir/file1'
+ cd ..
+
+ rm -r 1
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
mflag)
for message in '' ' ' '
' ' test' ; do
@@ -4179,6 +4339,61 @@ U first-dir/w3'
rm -rf 1 2 ${CVSROOT_DIRNAME}/first-dir
;;
+ devcom3)
+ # More watch tests, most notably handling of features designed
+ # for future expansion.
+ mkdir ${CVSROOT_DIRNAME}/first-dir
+ mkdir 1
+ cd 1
+ dotest devcom3-1 "${testcvs} -q co first-dir" ''
+ cd first-dir
+
+ touch w1 w2
+ dotest devcom3-2 "${testcvs} add w1 w2" "${DOTSTAR}"
+ dotest devcom3-3 "${testcvs} watch on w1 w2" ''
+ dotest devcom3-4 "${testcvs} -q ci -m add-them" "${DOTSTAR}"
+
+ # OK, since we are about to delve into CVS's internals, make
+ # sure that we seem to be correct about how they work.
+ dotest devcom3-5 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \
+"Fw1 _watched=
+Fw2 _watched="
+ # Now write a few more lines, just as if we were a newer version
+ # of CVS implementing some new feature.
+ cat <<EOF >>${CVSROOT_DIRNAME}/first-dir/CVS/fileattr
+Enew line here
+G@#$^!@#=&
+EOF
+ # Now get CVS to write to the fileattr file....
+ dotest devcom3-6 "${testcvs} watch off w1" ''
+ # ...and make sure that it hasn't clobbered our new lines.
+ # Note that writing these lines in another order would be OK
+ # too.
+ dotest devcom3-7 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \
+"Fw2 _watched=
+G@#..!@#=&
+Enew line here"
+
+ # See what CVS does when a file name is duplicated. The
+ # behavior of all versions of CVS since file attributes were
+ # implemented is that it nukes the duplications. This seems
+ # reasonable enough, although it means it isn't clear how
+ # useful duplicates would be for purposes of future
+ # expansion. But in the interests of keeping behaviors
+ # predictable, might as well test for it, I guess.
+ echo 'Fw2 duplicate=' >>${CVSROOT_DIRNAME}/first-dir/CVS/fileattr
+ dotest devcom3-8 "${testcvs} watch on w1" ''
+ dotest devcom3-9 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \
+"Fw2 _watched=
+Fw1 _watched=
+Enew line here
+G@#..!@#=&"
+
+ cd ../..
+
+ rm -rf 1 ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
ignore)
dotest 187a1 "${testcvs} -q co CVSROOT" "U CVSROOT/${DOTSTAR}"
cd CVSROOT
@@ -4547,6 +4762,12 @@ File: nibfile Status: Up-to-date
mkdir dir-to-import
cd dir-to-import
touch foo.c foo.exe
+
+ # While we're here, test for rejection of duplicate tag names.
+ dotest_fail binwrap-0 \
+ "${testcvs} import -m msg -I ! first-dir dup dup" \
+"${PROG} \[[a-z]* aborted\]: tag .dup. was specified more than once"
+
if ${testcvs} import -m message -I ! -W "*.exe -k 'b'" \
first-dir tag1 tag2 >>${LOGFILE}; then
pass binwrap-1
@@ -4854,7 +5075,7 @@ access list:'
log_header2='keyword substitution: kv'
log_dash='----------------------------
revision'
- log_date='date: [0-9/]* [0-9:]*; author: [a-zA-Z0-9@]*; state: Exp;'
+ log_date="date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;"
log_lines=" lines: ${PLUS}1 -1"
log_rev1="${log_dash} 1\.1
${log_date}
@@ -5041,7 +5262,7 @@ description:
file1-is-for-testing
----------------------------
revision 1\.1
-date: [0-9/]* [0-9:]*; author: [a-zA-Z0-9@]*; state: Exp;
+date: [0-9/]* [0-9:]*; author: '"${username}"'; state: Exp;
1
============================================================================='
@@ -5055,7 +5276,9 @@ date: [0-9/]* [0-9:]*; author: [a-zA-Z0-9@]*; state: Exp;
# Various tests relating to creating repositories, operating
# on repositories created with old versions of CVS, etc.
- # At the moment local only but that should be changed.
+ # Because this test is all about -d options and such, it
+ # at least to some extent needs to be different for remote vs.
+ # local.
if test "x$remote" = "xno"; then
# First, if the repository doesn't exist at all...
@@ -5092,17 +5315,53 @@ ${testcvs} -d ${TESTDIR}/crerepos release -d CVSROOT >>${LOGFILE}; then
fi
rm -rf CVS
cd ..
-
# The directory tmp should be empty
dotest crerepos-6 "rmdir tmp" ''
- # CVS better not create a history file--if the administrator
- # doesn't need it and wants to save on disk space, they just
- # delete it.
- dotest_fail crerepos-7 \
-"test -f ${TESTDIR}/crerepos/CVSROOT/history" ''
+ else
+ # For remote, just create the repository. We don't yet do
+ # the various other tests above for remote but that should be
+ # changed.
+ mkdir crerepos
+ mkdir crerepos/CVSROOT
+ fi
+
+ if test "x$remote" = "xno"; then
+ # Test that CVS rejects a relative path in CVSROOT.
+ mkdir 1; cd 1
+ dotest_fail crerepos-6a "${testcvs} -q -d ../crerepos get ." \
+"${PROG} \[[a-z]* aborted\]: CVSROOT ../crerepos must be an absolute pathname"
+ cd ..
+ rm -rf 1
+ mkdir 1; cd 1
+ dotest_fail crerepos-6b "${testcvs} -d crerepos init" \
+"${PROG} \[[a-z]* aborted\]: CVSROOT crerepos must be an absolute pathname"
+ cd ..
+ rm -rf 1
+ else # remote
+ # Test that CVS rejects a relative path in CVSROOT.
+ mkdir 1; cd 1
+ dotest_fail crerepos-6a \
+"${testcvs} -q -d :ext:`hostname`:../crerepos get ." \
+"Root ../crerepos must be an absolute pathname"
+ cd ..
+ rm -rf 1
+
+ mkdir 1; cd 1
+ dotest_fail crerepos-6b \
+"${testcvs} -d :ext:`hostname`:crerepos init" \
+"Root crerepos must be an absolute pathname"
+ cd ..
+ rm -rf 1
fi # end of tests to be skipped for remote
+
+ # CVS better not create a history file--if the administrator
+ # doesn't need it and wants to save on disk space, they just
+ # delete it.
+ dotest_fail crerepos-7 \
+"test -f ${TESTDIR}/crerepos/CVSROOT/history" ''
+
;;
rcs)
@@ -5280,6 +5539,171 @@ add file1
rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir ${TESTDIR}/rcs4.tmp
;;
+ big)
+
+ # Test ability to operate on big files. Intention is to
+ # test various realloc'ing code in RCS_deltas, rcsgetkey,
+ # etc. "big" is currently defined to be 1000 lines (64000
+ # bytes), which in terms of files that users will use is not
+ # large, merely average, but my reasoning is that this
+ # should be big enough to make sure realloc'ing is going on
+ # and that raising it a lot would start to stress resources
+ # on machines which run the tests, without any significant
+ # benefit.
+
+ mkdir ${CVSROOT_DIRNAME}/first-dir
+ dotest big-1 "${testcvs} -q co first-dir" ''
+ cd first-dir
+ for i in 0 1 2 3 4 5 6 7 8 9; do
+ for j in 0 1 2 3 4 5 6 7 8 9; do
+ for k in 0 1 2 3 4 5 6 7 8 9; do
+ echo \
+"This is line ($i,$j,$k) which goes into the file file1 for testing" >>file1
+ done
+ done
+ done
+ dotest big-2 "${testcvs} add file1" \
+"${PROG} [a-z]*: scheduling file .file1. for addition
+${PROG} [a-z]*: use .cvs commit. to add this file permanently"
+ dotest big-3 "${testcvs} -q ci -m add" \
+'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v
+done
+Checking in file1;
+/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done'
+ cd ..
+ rm -rf first-dir
+ dotest big-4 "${testcvs} -q get first-dir" "U first-dir/file1"
+
+ if test "$keep" = yes; then
+ echo Keeping /tmp/cvs-sanity and exiting due to --keep
+ exit 0
+ fi
+
+ rm -rf first-dir
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
+ modes)
+ # Test repository permissions (CVSUMASK and so on).
+ # Although the tests in this section "cheat" by testing
+ # repository permissions, which are sort of not a user-visible
+ # sort of thing, the modes do have user-visible consequences,
+ # such as whether a second user can check out the files. But
+ # it would be awkward to test the consequences, so we don't.
+
+ export -n CVSUMASK # if unset, defaults to 002
+ umask 077
+ mkdir 1; cd 1
+ dotest modes-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest modes-2 "${testcvs} add first-dir" \
+"Directory /tmp/cvs-sanity/cvsroot/first-dir added to the repository"
+ cd first-dir
+ touch aa
+ dotest modes-3 "${testcvs} add aa" \
+"${PROG} [a-z]*: scheduling file .aa. for addition
+${PROG} [a-z]*: use .cvs commit. to add this file permanently"
+ dotest modes-4 "${testcvs} -q ci -m add" \
+'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/aa,v
+done
+Checking in aa;
+/tmp/cvs-sanity/cvsroot/first-dir/aa,v <-- aa
+initial revision: 1\.1
+done'
+ dotest modes-5 "ls -l /tmp/cvs-sanity/cvsroot/first-dir/aa,v" \
+"-r--r--r-- .*"
+
+ # Test for whether we can set the execute bit.
+ chmod +x aa
+ echo change it >>aa
+ dotest modes-6 "${testcvs} -q ci -m set-execute-bit" \
+'Checking in aa;
+/tmp/cvs-sanity/cvsroot/first-dir/aa,v <-- aa
+new revision: 1\.2; previous revision: 1\.1
+done'
+ # If CVS let us update the execute bit, it would be set here.
+ # But it doesn't, and as far as I know that is longstanding
+ # CVS behavior.
+ dotest modes-7 "ls -l /tmp/cvs-sanity/cvsroot/first-dir/aa,v" \
+"-r--r--r-- .*"
+
+ # OK, now manually change the modes and see what happens.
+ chmod g=r,o= /tmp/cvs-sanity/cvsroot/first-dir/aa,v
+ echo second line >>aa
+ dotest modes-7a "${testcvs} -q ci -m set-execute-bit" \
+"Checking in aa;
+${TESTDIR}/cvsroot/first-dir/aa,v <-- aa
+new revision: 1\.3; previous revision: 1\.2
+done"
+ dotest modes-7b "ls -l /tmp/cvs-sanity/cvsroot/first-dir/aa,v" \
+"-r--r----- .*"
+
+ CVSUMASK=007
+ export CVSUMASK
+ touch ab
+ # Might as well test the execute bit too.
+ chmod +x ab
+ dotest modes-8 "${testcvs} add ab" \
+"${PROG} [a-z]*: scheduling file .ab. for addition
+${PROG} [a-z]*: use .cvs commit. to add this file permanently"
+ dotest modes-9 "${testcvs} -q ci -m add" \
+'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/ab,v
+done
+Checking in ab;
+/tmp/cvs-sanity/cvsroot/first-dir/ab,v <-- ab
+initial revision: 1\.1
+done'
+ if test "x$remote" = xyes; then
+ # The problem here is that the CVSUMASK environment variable
+ # needs to be set on the server (e.g. .bashrc). This is, of
+ # course, bogus, but that is the way it is currently.
+ dotest modes-10 "ls -l /tmp/cvs-sanity/cvsroot/first-dir/ab,v" \
+"-r-xr-x---.*" "-r-xr-xr-x.*"
+ else
+ dotest modes-10 "ls -l /tmp/cvs-sanity/cvsroot/first-dir/ab,v" \
+"-r-xr-x---.*"
+ fi
+
+ # OK, now add a file on a branch. Check that the mode gets
+ # set the same way (it is a different code path in CVS).
+ dotest modes-11 "${testcvs} -q tag -b br" 'T aa
+T ab'
+ dotest modes-12 "${testcvs} -q update -r br" ''
+ touch ac
+ dotest modes-13 "${testcvs} add ac" \
+"${PROG} [a-z]*: scheduling file .ac. for addition on branch .br.
+${PROG} [a-z]*: use .cvs commit. to add this file permanently"
+ # Not sure it really makes sense to refer to a "previous revision"
+ # when we are just now adding the file; as far as I know
+ # that is longstanding CVS behavior, for what it's worth.
+ dotest modes-14 "${testcvs} -q ci -m add" \
+'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/Attic/ac,v
+done
+Checking in ac;
+/tmp/cvs-sanity/cvsroot/first-dir/Attic/ac,v <-- ac
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done'
+ if test "x$remote" = xyes; then
+ # The problem here is that the CVSUMASK environment variable
+ # needs to be set on the server (e.g. .bashrc). This is, of
+ # course, bogus, but that is the way it is currently.
+ dotest modes-15 \
+"ls -l /tmp/cvs-sanity/cvsroot/first-dir/Attic/ac,v" \
+"-r--r--r--.*"
+ else
+ dotest modes-15 \
+"ls -l /tmp/cvs-sanity/cvsroot/first-dir/Attic/ac,v" \
+"-r--r-----.*"
+ fi
+
+ cd ../..
+ rm -rf 1 ${TESTDIR}/first-dir
+ # Perhaps should restore the umask and CVSUMASK. But the other
+ # tests "should" not care about them...
+ ;;
+
*)
echo $what is not the name of a test -- ignored
;;
diff --git a/gnu/usr.bin/cvs/src/status.c b/gnu/usr.bin/cvs/src/status.c
index 7254b1cfb2c..b794a2e43ab 100644
--- a/gnu/usr.bin/cvs/src/status.c
+++ b/gnu/usr.bin/cvs/src/status.c
@@ -79,7 +79,7 @@ status (argc, argv)
send_file_names (argc, argv, SEND_EXPAND_WILD);
/* XXX This should only need to send file info; the file
contents themselves will not be examined. */
- send_files (argc, argv, local, 0, 0);
+ send_files (argc, argv, local, 0, 0, 0);
send_to_server ("status\012", 0);
err = get_responses_and_close ();
@@ -127,6 +127,9 @@ status_fileproc (callerdat, finfo)
break;
#endif
case T_CONFLICT:
+ /* I _think_ that "unresolved" is correct; that if it has
+ been resolved then the status will change. But I'm not
+ sure about that. */
sstat = "Unresolved Conflict";
break;
case T_ADDED:
@@ -137,7 +140,7 @@ status_fileproc (callerdat, finfo)
break;
case T_MODIFIED:
if (vers->ts_conflict)
- sstat = "Unresolved Conflict";
+ sstat = "File had conflicts on merge";
else
sstat = "Locally Modified";
break;
diff --git a/gnu/usr.bin/cvs/src/subr.c b/gnu/usr.bin/cvs/src/subr.c
index fbf184deb2e..71d8ef8f3a1 100644
--- a/gnu/usr.bin/cvs/src/subr.c
+++ b/gnu/usr.bin/cvs/src/subr.c
@@ -56,6 +56,43 @@ xrealloc (ptr, bytes)
return (cp);
}
+/* Two constants which tune expand_string. Having MIN_INCR as large
+ as 1024 might waste a bit of memory, but it shouldn't be too bad
+ (CVS used to allocate arrays of, say, 3000, PATH_MAX (8192, often),
+ or other such sizes). Probably anything which is going to allocate
+ memory which is likely to get as big as MAX_INCR shouldn't be doing
+ it in one block which must be contiguous, but since getrcskey does
+ so, we might as well limit the wasted memory to MAX_INCR or so
+ bytes. */
+
+#define MIN_INCR 1024
+#define MAX_INCR (2*1024*1024)
+
+/* *STRPTR is a pointer returned from malloc (or NULL), pointing to *N
+ characters of space. Reallocate it so that points to at least
+ NEWSIZE bytes of space. Gives a fatal error if out of memory;
+ if it returns it was successful. */
+void
+expand_string (strptr, n, newsize)
+ char **strptr;
+ size_t *n;
+ size_t newsize;
+{
+ if (*n < newsize)
+ {
+ while (*n < newsize)
+ {
+ if (*n < MIN_INCR)
+ *n += MIN_INCR;
+ else if (*n > MAX_INCR)
+ *n += MAX_INCR;
+ else
+ *n *= 2;
+ }
+ *strptr = xrealloc (*strptr, *n);
+ }
+}
+
/*
* Duplicate a string, calling xmalloc to allocate some dynamic space
*/
@@ -85,7 +122,7 @@ strip_trailing_newlines (str)
}
/*
- * Recover the space allocated by Find_Names() and line2argv()
+ * Recover the space allocated by line2argv()
*/
void
free_names (pargc, argv)
@@ -98,26 +135,40 @@ free_names (pargc, argv)
{ /* only do through *pargc */
free (argv[i]);
}
+ free (argv);
*pargc = 0; /* and set it to zero when done */
}
-/*
- * Convert a line into argc/argv components and return the result in the
- * arguments as passed. Use free_names() to return the memory allocated here
- * back to the free pool.
- */
+/* Convert LINE into arguments separated by space and tab. Set *ARGC
+ to the number of arguments found, and (*ARGV)[0] to the first argument,
+ (*ARGV)[1] to the second, etc. *ARGV is malloc'd and so are each of
+ (*ARGV)[0], (*ARGV)[1], ... Use free_names() to return the memory
+ allocated here back to the free pool. */
void
line2argv (pargc, argv, line)
int *pargc;
- char **argv;
+ char ***argv;
char *line;
{
char *cp;
+ /* Could make a case for size_t or some other unsigned type, but
+ we'll stick with int to avoid signed/unsigned warnings when
+ comparing with *pargc. */
+ int argv_allocated;
+
+ /* Small for testing. */
+ argv_allocated = 1;
+ *argv = (char **) xmalloc (argv_allocated * sizeof (**argv));
*pargc = 0;
for (cp = strtok (line, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
{
- argv[*pargc] = xstrdup (cp);
+ if (*pargc == argv_allocated)
+ {
+ argv_allocated *= 2;
+ *argv = xrealloc (*argv, argv_allocated * sizeof (**argv));
+ }
+ (*argv)[*pargc] = xstrdup (cp);
(*pargc)++;
}
}
@@ -193,9 +244,10 @@ gca (rev1, rev2)
char *rev2;
{
int dots;
- char gca[PATH_MAX];
+ char *gca;
char *p[2];
int j[2];
+ char *retval;
if (rev1 == NULL || rev2 == NULL)
{
@@ -203,6 +255,11 @@ gca (rev1, rev2)
abort();
}
+ /* The greatest common ancestor will have no more dots, and numbers
+ of digits for each component no greater than the arguments. Therefore
+ this string will be big enough. */
+ gca = xmalloc (strlen (rev1) + strlen (rev2) + 100);
+
/* walk the strings, reading the common parts. */
gca[0] = '\0';
p[0] = rev1;
@@ -290,7 +347,9 @@ gca (rev1, rev2)
*s = '\0';
}
- return (xstrdup (gca));
+ retval = xstrdup (gca);
+ free (gca);
+ return retval;
}
/*
diff --git a/gnu/usr.bin/cvs/src/tag.c b/gnu/usr.bin/cvs/src/tag.c
index b09979e7d00..cee7aecbbe8 100644
--- a/gnu/usr.bin/cvs/src/tag.c
+++ b/gnu/usr.bin/cvs/src/tag.c
@@ -156,6 +156,8 @@ cvstag (argc, argv)
ign_setup ();
+ if (!force_tag_match)
+ send_arg ("-f");
if (local)
send_arg("-l");
if (delete_flag)
@@ -178,7 +180,7 @@ cvstag (argc, argv)
/* FIXME: We shouldn't have to send current files, but I'm not sure
whether it works. So send the files --
it's slower but it works. */
- send_files (argc, argv, local, 0, 0);
+ send_files (argc, argv, local, 0, 0, 0);
send_to_server ("tag\012", 0);
return get_responses_and_close ();
}
diff --git a/gnu/usr.bin/cvs/src/version.c b/gnu/usr.bin/cvs/src/version.c
index 26d1bd05fc0..f09017c3174 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.9.2";
+char *version_string = "\nConcurrent Versions System (CVS) 1.9.4";
#ifdef CLIENT_SUPPORT
#ifdef SERVER_SUPPORT
diff --git a/gnu/usr.bin/cvs/src/watch.c b/gnu/usr.bin/cvs/src/watch.c
index 4fedda29c69..51b50fcd10e 100644
--- a/gnu/usr.bin/cvs/src/watch.c
+++ b/gnu/usr.bin/cvs/src/watch.c
@@ -336,7 +336,7 @@ watch_addremove (argc, argv)
/* FIXME: We shouldn't have to send current files, but I'm not sure
whether it works. So send the files --
it's slower but it works. */
- send_files (argc, argv, local, 0, 0);
+ send_files (argc, argv, local, 0, 0, 0);
send_to_server (the_args.adding ?
"watch-add\012" : "watch-remove\012",
0);
@@ -511,7 +511,7 @@ watchers (argc, argv)
/* FIXME: We shouldn't have to send current files, but I'm not sure
whether it works. So send the files --
it's slower but it works. */
- send_files (argc, argv, local, 0, 0);
+ send_files (argc, argv, local, 0, 0, 0);
send_to_server ("watchers\012", 0);
return get_responses_and_close ();
}
diff --git a/gnu/usr.bin/cvs/src/wrapper.c b/gnu/usr.bin/cvs/src/wrapper.c
index 324f7cc7904..6a7cea4af10 100644
--- a/gnu/usr.bin/cvs/src/wrapper.c
+++ b/gnu/usr.bin/cvs/src/wrapper.c
@@ -1,4 +1,15 @@
+/* This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details. */
+
#include "cvs.h"
+#include "getline.h"
/*
Original Author: athan@morgan.com <Andrew C. Athan> 2/1/94
@@ -68,13 +79,18 @@ void wrap_restore_saved PROTO((void));
void wrap_setup()
{
- char file[PATH_MAX];
struct passwd *pw;
#ifdef CLIENT_SUPPORT
if (!client_active)
#endif
{
+ char *file;
+
+ file = xmalloc (strlen (CVSroot_directory)
+ + sizeof (CVSROOTADM)
+ + sizeof (CVSROOTADM_WRAPPER)
+ + 10);
/* Then add entries found in repository, if it exists. */
(void) sprintf (file, "%s/%s/%s", CVSroot_directory, CVSROOTADM,
CVSROOTADM_WRAPPER);
@@ -82,6 +98,7 @@ void wrap_setup()
{
wrap_add_file(file,0);
}
+ free (file);
}
/* Then add entries found in home dir, (if user has one) and file
@@ -89,11 +106,15 @@ void wrap_setup()
get_homedir, i.e. $HOME). */
if ((pw = (struct passwd *) getpwuid (getuid ())) && pw->pw_dir)
{
+ char *file;
+
+ file = xmalloc (strlen (pw->pw_dir) + sizeof (CVSDOTWRAPPER) + 10);
(void) sprintf (file, "%s/%s", pw->pw_dir, CVSDOTWRAPPER);
if (isfile (file))
{
wrap_add_file (file, 0);
}
+ free (file);
}
/* Then add entries found in CVSWRAPPERS environment variable. */
@@ -144,17 +165,26 @@ wrap_add_file (file, temp)
int temp;
{
FILE *fp;
- char line[1024];
+ char *line = NULL;
+ size_t line_allocated = 0;
- wrap_restore_saved();
- wrap_kill_temp();
+ wrap_restore_saved ();
+ wrap_kill_temp ();
- /* load the file */
- if (!(fp = CVS_FOPEN (file, "r")))
+ /* Load the file. */
+ fp = CVS_FOPEN (file, "r");
+ if (fp == NULL)
+ {
+ if (!existence_error (errno))
+ error (0, errno, "cannot open %s", file);
return;
- while (fgets (line, sizeof (line), fp))
+ }
+ while (getline (&line, &line_allocated, fp) >= 0)
wrap_add (line, temp);
- (void) fclose (fp);
+ if (ferror (fp))
+ error (0, errno, "cannot read %s", file);
+ if (fclose (fp) == EOF)
+ error (0, errno, "cannot close %s", file);
}
void
@@ -449,17 +479,16 @@ wrap_merge_is_copy (fileName)
return 1;
}
-char *
+void
wrap_fromcvs_process_file(fileName)
const char *fileName;
{
WrapperEntry *e=wrap_matching_entry(fileName);
- static char buf[PATH_MAX];
if(e==NULL || e->fromcvsFilter==NULL)
- return NULL;
+ return;
run_setup(e->fromcvsFilter,fileName);
run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL );
- return buf;
+ return;
}