diff options
Diffstat (limited to 'gnu')
28 files changed, 1701 insertions, 271 deletions
diff --git a/gnu/usr.bin/cvs/doc/ChangeLog b/gnu/usr.bin/cvs/doc/ChangeLog index 27314bed625..182ac42030d 100644 --- a/gnu/usr.bin/cvs/doc/ChangeLog +++ b/gnu/usr.bin/cvs/doc/ChangeLog @@ -1,3 +1,164 @@ +Fri Apr 18 12:05:48 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Assigning revisions): Say that -r implies -f. + +Thu Apr 17 16:34:14 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (From other version control systems): Add comment + about CMZ and PATCHY. + +Wed Apr 16 12:35:25 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Responses): Add paragraph describing how + Copy-file relates to Merged. + (Responses): Add paragraph about how it is the server which + worries about not clobbering the user's file. + +Tue Apr 15 00:57:31 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * RCSFILES: Add notes on keyword expansion. + + * cvs.texinfo (Rename by copying): Comment out seemingly erroneous + text regarding the revision number that the new file starts with. + +Mon Apr 14 12:37:35 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Requests): Clients should try to send + notifications right away. + + * cvsclient.texi (Requests): For Notify request, clarify a few + future expansion situations. Specify the format of the time. + + * cvsclient.texi (Requests): Clarify that arguments to co, rdiff, + and rtag are module names (and how that differs from file/directory + names). + + * cvsclient.texi (Responses): Say that servers need to create + directories one at a time. + +Sat Apr 12 09:32:58 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Committing your changes): Say that editor default + is notepad (not vi) for Windows NT/95. Be more clear about what + "cvs commit" does. Add paragraph about timestamps. + (Environment variables, Global options, editinfo): + Add xrefs to that node. + +Thu Apr 10 15:48:39 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Error messages): Add "could not patch; will refetch". + +Wed Apr 9 15:21:11 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Working directory storage): New node. + + * cvs.texinfo (Error messages): Add comment about "cvs co ." on + NT. + +Tue Apr 8 14:44:26 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Error messages): Add diff3 usage message. + +Sun Apr 6 19:03:01 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Removing files): Add comment about undoing a "cvs + remove". + + * cvsclient.texi (Requests): Explicitly mention the idea of + deferring "Notify" requests. + +Tue Apr 1 07:51:38 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Responses): Add paragraph about directory + creation and empty directories. + + * cvs.texinfo (Binary files): Add comment about binary files and + merges. + + * cvsclient.texi (Requests): Add discussion of when to send + Is-modified. + + * cvsclient.texi (Requests): Sending Is-modified is enough to + prevent the file from being considered "lost". + +Sun Mar 30 00:31:47 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Requests): Add Is-modified request. Clarify + order of Entry relative to Unchanged or Is-modified (might as well + specify the same thing vis-a-vis Modified while we are at it). + +Sat Mar 29 12:32:40 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi: Change "newline" to "linefeed". Most of the + document already reads "linefeed" and that is what is intended. + (File transmissions): New node, moved here from Requests. + (Goals, Filenames, File transmissions, new node Strings): Add + discussion of character sets and what we expect from the transport + protocol we run on. + + * cvsclient.texi (Requests): Add paragraph about each Directory + request specifying a new local-directory and repository. + + * cvsclient.texi (Requests): Add paragraph about renaming + local-directory in Directory request. Use "local-directory" + consistently instead of "working directory", for clarity. + +Fri Mar 28 13:59:59 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Requests): Make it clear that there is no + guarantee that one will get Clear-sticky instead of another + response. Also clarify that clients will tend to store the + repository in a long-term way. + + * cvsclient.texi (Requests): Further clarify Directory example. + + * cvsclient.texi (Requests): Add example and further explanation + of what expand-modules is for. + + * cvsclient.texi (Requests): Add example, hopefully making it + clearer what REPOSITORY and LOCAL-DIRECTORY mean to Directory. + + * cvs.texinfo (Attic): New node. + (rtag options): Adjust discussion of -a accordingly. + (Repository files): Adjust accordingly. + +Thu Mar 27 09:57:05 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Error messages): Give exact wording of broken pipe + error message. + + * cvs.texinfo (history database): Add comment about various + problems with the history file. + + * cvs.texinfo (Common options): The ISO8601 web page we had + mentioned in a comment is no more. Replace it with a new one. + + * cvs.texinfo (Common options): "cvs history" also outputs dates. + +Wed Mar 26 10:54:21 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Common options): "cvs editors" also outputs dates. + + * cvs.texinfo (Outside): Fix paragraph which said that revision + numbers start at 1.0. First of all, it is 1.1. Second of all, it + is sometimes 2.1, 3.1, etc. Third of all, the xref should be to + Assigning revisions not commit options. + + * cvs.texinfo (Outside): Comment out sentence which incorrectly + stated that "cvs add" can operate on "foo/bar.c". + +Tue Mar 25 22:21:29 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Error messages): New node. + (Magic branch numbers): Move from Troubleshooting to Revisions and + branches. The former placement never made any sense to me. + (Revision numbers): Remove "Main trunk (intro)" index entry now + that this node is right next to the other "main trunk" index + entry. + (BUGS): Very briefly mention reporting bugs in CVS. + + * cvs.texinfo (Compatibility): Add comment about "Nfoo" in CVS/Tag. + Mon Mar 24 13:50:24 1997 Jim Kingdon <kingdon@harvey.cyclic.com> * cvs.texinfo (Creating a branch): Add comment about -r in branch diff --git a/gnu/usr.bin/cvs/doc/RCSFILES b/gnu/usr.bin/cvs/doc/RCSFILES index 0ac61aa1d42..f437cfe6118 100644 --- a/gnu/usr.bin/cvs/doc/RCSFILES +++ b/gnu/usr.bin/cvs/doc/RCSFILES @@ -37,6 +37,24 @@ for more information on them. CVS also sets the RCS state to "dead" to indicate that a file does not exist in a given revision (this is stored just as any other RCS state is). +The rules regarding keyword expansion are not documented along with +the rest of the RCS file format; they are documented in the co(1) +manpage in the RCS 5.7 distribution. See also the "Keyword +substitution" chapter of cvs.texinfo. The co(1) manpage refers to +special behavior if the log prefix for the $Log keyword is /* or (*. +RCS 5.7 produces a warning whenever it behaves that way, and current +versions of CVS do not handle this case in a special way (CVS 1.9 and +earlier invoke RCS to perform keyword expansion). + +Note that the "comment {string};" syntax from rcsfile.5 specifies a +comment leader, which affects expansion of the $Log keyword for old +versions of RCS. The comment leader is not used by RCS 5.7 or current +versions of CVS. + +Both RCS 5.7 and current versions of CVS handle the $Log keyword in a +different way if the log message starts with "checked in with -k by ". +I don't think this behavior is documented anywhere. + Diff follows: (Note that in the following diff the old value for the Id keyword was: diff --git a/gnu/usr.bin/cvs/doc/cvsclient.texi b/gnu/usr.bin/cvs/doc/cvsclient.texi index 7feee6c6a90..a95dc68c04e 100644 --- a/gnu/usr.bin/cvs/doc/cvsclient.texi +++ b/gnu/usr.bin/cvs/doc/cvsclient.texi @@ -74,8 +74,16 @@ Do not assume any access to the repository other than via this protocol. It does not depend on NFS, rdist, etc. @item -Providing a reliable transport is outside this protocol. It is expected -that it runs over TCP, UUCP, etc. +Providing a reliable transport is outside this protocol. The protocol +expects a reliable transport that is transparent (that is, there is no +translation of characters, including characters such as such as +linefeeds or carriage returns), and can transmit all 256 octets (for +example for proper handling of binary files, compression, and +encryption). The encoding of characters specified by the protocol (the +names of requests and so on) is the invariant ISO 646 character set (a +subset of most popular character sets including ASCII and others). For +more details on running the protocol over the TCP reliable transport, +see @ref{Connection and Authentication}. @item Security and authentication are handled outside this protocol (but see @@ -202,6 +210,8 @@ to a horizontal tab. * Entries Lines:: * Modes:: * Filenames:: Conventions regarding filenames +* File transmissions:: How file contents are transmitted +* Strings:: Strings in various requests and responses * Requests:: * Responses:: * Example:: @@ -282,18 +292,21 @@ the same answer (and what to do if future server ports are operating on a repository like e:/foo or CVS_ROOT:[FOO.BAR] has not been carefully thought out). -@node Requests -@section Requests +Characters outside the invariant ISO 646 character set should be avoided +in filenames. This restriction may need to be relaxed to allow for +characters such as @samp{[} and @samp{]} (see above about non-unix +servers); this has not been carefully considered (and currently +implementations probably use whatever character sets that the operating +systems they are running on allow, and/or that users specify). Of +course the most portable practice is to restrict oneself further, to the +POSIX portable filename character set as specified in POSIX.1. -By convention, requests which begin with a capital letter do not elicit -a response from the server, while all others do -- save one. The -exception is @samp{gzip-file-contents}. Unrecognized requests will -always elicit a response from the server, even if that request begins -with a capital letter. +@node File transmissions +@section File transmissions File contents (noted below as @var{file transmission}) can be sent in one of two forms. The simpler form is a number of bytes, followed by a -newline, followed by the specified number of bytes of file contents. +linefeed, followed by the specified number of bytes of file contents. These are the entire contents of the specified file. Second, if both client and server support @samp{gzip-file-contents}, a @samp{z} may precede the length, and the `file contents' sent are actually compressed @@ -301,8 +314,42 @@ with @samp{gzip} (RFC1952/1951) compression. The length specified is that of the compressed version of the file. In neither case are the file content followed by any additional data. -The transmission of a file will end with a newline iff that file (or its -compressed form) ends with a newline. +The transmission of a file will end with a linefeed iff that file (or its +compressed form) ends with a linefeed. + +The encoding of file contents depends on the value for the @samp{-k} +option. If the file is binary (as specified by the @samp{-kb} option in +the appropriate place), then it is just a certain number of octets, and +the protocol contributes nothing towards determining the encoding (using +the file name is one widespread, if not universally popular, mechanism). +If the file is text (not binary), then the file is sent as a series of +lines, separated by linefeeds. If the keyword expansion is set to +something other than @samp{-ko}, then it is expected that the file +conform to the RCS expectations regarding keyword expansion---in +particular, that it is in a character set such as ASCII in which 0x24 is +a dollar sign (@samp{$}). + +@node Strings +@section Strings + +In various contexts, for example the @code{Argument} request and the +@code{M} response, one transmits what is essentially an arbitrary +string. Often this will have been supplied by the user (for example, +the @samp{-m} option to the @code{ci} request). The protocol has no +mechanism to specify the character set of such strings; it would be +fairly safe to stick to the invariant ISO 646 character set but the +existing practice is probably to just transmit whatever the user +specifies, and hope that everyone involved agrees which character set is +in use, or sticks to a common subset. + +@node Requests +@section Requests + +By convention, requests which begin with a capital letter do not elicit +a response from the server, while all others do -- save one. The +exception is @samp{gzip-file-contents}. Unrecognized requests will +always elicit a response from the server, even if that request begins +with a capital letter. @table @code @item Root @var{pathname} \n @@ -339,6 +386,65 @@ the top level at which the command is occurring (i.e. the last to indicate that top level, @samp{.} should be send for @var{local-directory}. +Here is an example of where a client gets @var{repository} and +@var{local-directory}. Suppose that there is a module defined by + +@example +moddir 1dir +@end example + +That is, one can check out @code{moddir} and it will take @code{1dir} in +the repository and check it out to @code{moddir} in the working +directory. Then an initial check out could proceed like this: + +@example +C: Root /home/kingdon/zwork/cvsroot +. . . +C: Argument moddir +C: Directory . +C: /home/kingdon/zwork/cvsroot +C: co +S: Clear-sticky moddir/ +S: /home/kingdon/zwork/cvsroot/1dir/ +. . . +S: ok +@end example + +In this example the response shown is @code{Clear-sticky}, but it could +be another response instead. Note that it returns two pathnames. +The first one, @file{moddir/}, indicates the working +directory to check out into. The second one, ending in @file{1dir/}, +indicates the directory to pass back to the server in a subsequent +@code{Directory} request. For example, a subsequent @code{update} +request might look like: + +@example +C: Directory moddir +C: /home/kingdon/zwork/cvsroot/1dir +. . . +C: update +@end example + +For a given @var{local-directory}, the repository will be the same for +each of the responses, so one can use the repository from whichever +response is most convenient. Typically a client will store the +repository along with the sources for each @var{local-directory}, use +that same setting whenever operating on that @var{local-directory}, and +not update the setting as long as the @var{local-directory} exists. + +A client is free to rename a @var{local-directory} at any time (for +example, in response to an explicit user request). While it is true +that the server supplies a @var{local-directory} to the client, as noted +above, this is only the default place to put the directory. Of course, +the various @code{Directory} requests for a single command (for example, +@code{update} or @code{ci} request) should name a particular directory +with the same @var{local-directory}. + +Each @code{Directory} request specifies a brand-new +@var{local-directory} and @var{repository}; that is, +@var{local-directory} and @var{repository} are never relative to paths +specified in any previous @code{Directory} request. + @item Max-dotdot @var{level} \n Response expected: no. Tell the server that @var{level} levels of directories above the @@ -382,8 +488,13 @@ local machine. The name in @var{entry-line} is a name relative to the directory most recently specified with @code{Directory}. If the user is operating on only some files in a directory, @code{Entry} requests for only those files need be included. If an @code{Entry} request is -sent without @code{Modified} or @code{Unchanged}, it means the file is -lost (does not exist in the working directory). +sent without @code{Modified}, @code{Is-modified}, or @code{Unchanged}, +it means the file is +lost (does not exist in the working directory). If both @code{Entry} +and one of @code{Modified}, @code{Is-modified}, or @code{Unchanged} are +sent for the same file, @code{Entry} must be sent first. For a +given file, one can send @code{Modified}, @code{Is-modified}, or +@code{Unchanged}, but not more than one of these three. @item Modified @var{filename} \n Response expected: no. Additional data: mode, \n, file transmission. @@ -393,6 +504,41 @@ the user is operating on only some files in a directory, only those files need to be included. This can also be sent without @code{Entry}, if there is no entry for the file. +@item Is-modified @var{filename} \n +Response expected: no. Additional data: none. Like @code{Modified}, +but used if the server only needs +to know whether the file is modified, not the contents. + +The commands which can take @code{Is-modified} instead of +@code{Modified} with no known change in behavior are: @code{admin}, +@code{diff} (if and only if two @samp{-r} or @samp{-D} options are +specified), @code{watch-on}, @code{watch-off}, @code{watch-add}, +@code{watch-remove}, @code{watchers}, @code{editors}, +@code{log}, and @code{annotate}. + +For the @code{status} command, one can send @code{Is-modified} but if +the client is using imperfect mechanisms such a timestamps to determine +whether to consider a file modified, then the behavior will be +different. That is, if one sends @code{Modified}, then the server will +actually compare the contents of the file sent and the one it derives +from to determine whether the file is genuinely modified. But if one +sends @code{Is-modified}, then the server takes the client's word for +it. A similar situation exists for @code{tag}, if the @samp{-c} option +is specified. + +Commands for which @code{Modified} is necessary are @code{co}, +@code{ci}, @code{update}, and @code{import}. + +Commands which do not need to inform the server about a working +directory, and thus should not be sending either @code{Modified} or +@code{Is-modified}: @code{rdiff}, @code{rtag}, @code{history}, +@code{init}, and @code{release}. + +Commands for which further investigation is warranted are: +@code{remove}, @code{add}, and @code{export}. Pending such +investigation, the more conservative course of action is to stick to +@code{Modified}. + @item Unchanged @var{filename} \n Response expected: no. Tell the server that @var{filename} has not been modified in the checked out directory. The name is relative to the most @@ -413,13 +559,30 @@ responses. Response expected: no. Additional data: @var{notification-type} \t @var{time} \t @var{clienthost} \t @var{working-dir} \t @var{watches} \n @end example -where @var{notification-type} is @samp{E} for edit or @samp{U} for -unedit, @var{time} is the time at which the edit or unedit took place, +where @var{notification-type} is @samp{E} for edit, @samp{U} for +unedit, undefined behavior if @samp{C}, and all other letters should be +silently ignored for future expansion. +@var{time} is the time at which the edit or unedit took place, in a +user-readable format of the client's choice (the server should treat the +time as an opaque string rather than interpreting it). +@c Might be useful to specify a format, but I don't know if we want to +@c specify the status quo (ISO C asctime() format plus timezone) without +@c offering the option of ISO8601 and/or RFC822/1123 (see cvs.texinfo +@c for much much more on date formats). @var{clienthost} is the name of the host on which the edit or unedit took place, and @var{working-dir} is the pathname of the working directory where the edit or unedit took place. @var{watches} are the -temporary watches to set; if it is followed by \t then the tab and the -rest of the line are ignored. +temporary watches to set. If @var{watches} is followed by \t then the +\t and the rest of the line should be ignored, for future expansion. + +Note that a client may be capable of performing an @code{edit} or +@code{unedit} operation without connecting to the server at that time, +and instead connecting to the server when it is convenient (for example, +when a laptop is on the net again) to send the @code{Notify} requests. +Even if a client is capable of deferring notifications, it should +attempt to send them immediately (one can send @code{Notify} requests +together with a @code{noop} request, for example), unless perhaps if +it can know that a connection would be impossible. @item Questionable @var{filename} \n Response expected: no. Additional data: no. Tell the server to check @@ -498,16 +661,58 @@ that the server can assume that this is checkout or export, not rtag or rdiff; the latter do not access the working directory and thus have no need to expand modules on the client side. -@item co \n -@itemx ci \n +Expand may not be the best word for what this request does. It does not +necessarily tell you all the files contained in a module, for example. +Basically it is a way of telling you which working directories the +server needs to know about in order to handle a checkout of the +specified modules. + +For example, suppose that the server has a module defined by + +@example +aliasmodule -a 1dir +@end example + +That is, one can check out @code{aliasmodule} and it will take +@code{1dir} in the repository and check it out to @code{1dir} in the +working directory. Now suppose the client already has this module +checked out and is planning on using the @code{co} request to update it. +Without using @code{expand-modules}, the client would have two bad +choices: it could either send information about @emph{all} working +directories under the current directory, which could be unnecessarily +slow, or it could be ignorant of the fact that @code{aliasmodule} stands +for @code{1dir}, and neglect to send information for @code{1dir}, which +would lead to incorrect operation. +@c Those don't really seem like the only two options. I mean, what +@c about keeping track of the correspondence from when we first checked +@c out a fresh directory? Not that the CVS client does this, or that +@c I've really thought about whether it would be a good idea... + +With @code{expand-modules}, the client would first ask for the module to +be expanded: + +@example +C: Root /home/kingdon/zwork/cvsroot +. . . +C: Argument aliasmodule +C: Directory . +C: /home/kingdon/zwork/cvsroot +C: expand-modules +S: Module-expansion 1dir +S: ok +@end example + +and then it knows to check the @file{1dir} directory and send +requests such as @code{Entry} and @code{Modified} for the files in that +directory. + +@item ci \n @itemx diff \n @itemx tag \n @itemx status \n @itemx log \n @itemx add \n @itemx remove \n -@itemx rdiff \n -@itemx rtag \n @itemx admin \n @itemx export \n @itemx history \n @@ -522,13 +727,30 @@ of the operation. No provision is made for any input from the user. This means that @code{ci} must use a @code{-m} argument if it wants to specify a log message. -@itemx init @var{root-name} \n +@item co \n +Response expected: yes. Get files from the repository. This uses any +previous @code{Argument}, @code{Directory}, @code{Entry}, or +@code{Modified} requests, if they have been sent. Arguments to this +command are module names; the client cannot know what directories they +correspond to except by (1) just sending the @code{co} request, and then +seeing what directory names the server sends back in its responses, and +(2) the @code{expand-modules} request. + +@item rdiff \n +@itemx rtag \n +Response expected: yes. Actually do a cvs command. This uses any +previous @code{Argument} requests, if they have been sent. The client +should not send @code{Directory}, @code{Entry}, or @code{Modified} +requests for this command; they are not used. Arguments to these +commands are module names, as described for @code{co}. + +@item init @var{root-name} \n Response expected: yes. If it doesn't already exist, create a @sc{cvs} repository @var{root-name}. Note that @var{root-name} is a local directory and @emph{not} a fully qualified @code{CVSROOT} variable. The @code{Root} request need not have been previously sent. -@itemx update \n +@item update \n Response expected: yes. Actually do a @code{cvs update} command. This uses any previous @code{Argument}, @code{Directory}, @code{Entry}, or @code{Modified} requests, if they have been sent. The @@ -619,7 +841,7 @@ message and exiting---this should be investigated further). In the following, @var{pathname} actually indicates a pair of pathnames. First, a local directory name relative to the directory in which the command was given (i.e. the last -@code{Directory} before the command). Then a newline and a repository +@code{Directory} before the command). Then a linefeed and a repository name. Then a slash and the filename (without a @samp{,v} ending). For example, for a file @file{i386.mh} @@ -631,6 +853,30 @@ gas.clean/config/ /rel/cvsfiles/devo/gas/config/i386.mh @end example +If the server wants to tell the client to create a directory, then it +merely uses the directory in any response, as described above, and the +client should create the directory if it does not exist. Note that this +should only be done one directory at a time, in order to permit the +client to correctly store the repository for each directory. Servers +can use requests such as @code{Clear-sticky}, +@code{Clear-static-directory}, or any other requests, to create +directories. +@c FIXME: Need example here of how "repository" needs to be sent for +@c each directory, and cannot be correctly deduced from, say, the most +@c deeply nested directory. + +Some server +implementations may poorly distinguish between a directory which should +not exist and a directory which contains no files; in order to refrain +from creating empty directories a client should both send the @samp{-P} +option to @code{update} or @code{co}, and should also detect the case in +which the server asks to create a directory but not any files within it +(in that case the client should remove the directory or refrain from +creating it in the first place). Note that servers could clean this up +greatly by only telling the client to create directories if the +directory in question should exist, but until servers do this, clients +will need to offer the @samp{-P} behavior described above. + Any response always ends with @samp{error} or @samp{ok}. This indicates that the response is over. @@ -678,12 +924,29 @@ This is just like @code{Updated} and takes the same additional data, but is used only if a @code{Entry}, @code{Modified}, or @code{Unchanged} request has been sent for the file in question. +This response, or @code{Merged}, indicates that the server has +determined that it is OK to overwrite the previous contents of the file +specified by @var{pathname}. Provided that the client has correctly +sent @code{Modified} or @code{Is-modified} requests for a modified file, +and the file was not modified while CVS was running, the server can +ensure that a user's modifications are not lost. + @item Merged @var{pathname} \n This is just like @code{Updated} and takes the same additional data, with the one difference that after the new copy of the file is enclosed, it will still not be up to date. Used for the results of a merge, with or without conflicts. +It is useful to preserve an copy of what the file looked like before the +merge. This is basically handled by the server; before sending +@code{Merged} it will send a @code{Copy-file} response. For example, if +the file is @file{aa} and it derives from revision 1.3, the +@code{Copy-file} response will tell the client to copy @file{aa} to +@file{.#aa.1.3}. It is up to the client to decide how long to keep this +file around; traditionally clients have left it around forever, thus +letting the user clean it up as desired. But another answer, such as +until the next commit, might be preferable. + @item Patched @var{pathname} \n This is just like @code{Updated} and takes the same additional data, with the one difference that instead of sending a new copy of the file, diff --git a/gnu/usr.bin/cvs/src/ChangeLog b/gnu/usr.bin/cvs/src/ChangeLog index 42a631ef2be..6fe1e91c768 100644 --- a/gnu/usr.bin/cvs/src/ChangeLog +++ b/gnu/usr.bin/cvs/src/ChangeLog @@ -1,5 +1,276 @@ +Fri Apr 18 11:24:26 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * version.c: Version 1.9.8. + + * commit.c (struct find_data): Add field force. + (find_fileproc, commit): Use it instead of force_ci to decide + whether to send files to server. + (commit): Set it if either -f or -r is specified. + * sanity.sh (basica): Add tests basica-8a0, basica-8a1, and + basica-8a2; tests for above fix. + +Wed Apr 16 11:50:59 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * zlib.c: Remove paragraph with Free Software Foundation address. + See 2 Jan 1997 entry in ../ChangeLog for rationale. + +Tue Apr 15 00:36:23 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * update.c (patch_file_write): Always assign to final_nl, so that + it ends up reflecting whether the data from the last call had a + newline, not whether the data from any of the calls ended in a + newline. Doesn't matter with the current RCS_checkout + implementation, but it will if RCS_checkout is changed to pass + less than the entire file. + + * rcs.c (RCS_cmp_file): Change NULL to RUN_TTY in passing sout to + RCS_checkout, for clarity. + + * import.c (update_rcs_file): Remove unused variable ierrno. + + * add.c, checkout.c, commit.c, diff.c, edit.c, import.c, + history.c, log.c, main.c, patch.c, release.c, remove.c, rtag.c, + status.c, tag.c, update.c, watch.c: Pass "+" to all calls to + getopt. This ensures that we maintain existing behavior even with + glibc2. + + * filesubr.c (fopen_case): Don't set *PATHP if we return an + error. Since the 9 Apr 1997 change, the behavior has been to + sometimes set it and sometimes not. + * rcs.c (RCS_parse): Adjust callers to not free it. Without this + change, they could call free() on an uninitialized variable. + + * checkout.c (checkout): Add comment about export -k. + + * root.c (check_root_consistent): Add comment about wording of + message. + +Mon Apr 14 11:51:49 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (call_in_directory): If rdirp reaches the end of + reposdirname, then just set it to NULL. If server does not create + directories one at a time, give a warning. + * sanity.sh (modules3): Enable tests modules3-8 through + modules3-11 for remote; tests for above fix. + + * client.c (call_in_directory): Don't set short_pathname to + pathname for a while; just use pathname itself (cleans up a relic + of the old "Repository" (not "Directory") code). Add comment + explaining short_pathname. + +Sun Apr 13 18:07:50 1997 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_checkout): Add pfn and callerdat parameters. Change + all callers. Move setting of expand after retrieval of file + data. + (struct cmp_file_data): Define. + (RCS_cmp_file): New function. + (cmp_file_buffer): New static function. + * rcs.h (RCSCHECKOUTPROC): Define type. + (RCS_checkout): Update declaration. + (RCS_cmp_file): Define. + * diff.c (diff_file_nodiff): Call RCS_cmp_file rather than + RCS_checkout and xcmp. + * import.c (update_rcs_file): Likewise. + * no_diff.c (No_Difference): Likewise. + * update.c (struct patch_file_data): Define. + (patch_file): Just return if noexec, or if binary file. Pass + patch_file_write to RCS_checkout. Don't check for newlines or + compute checksums here. Stat RCS file to set modes. + (patch_file_write): New static function. + + * update.c (patch_file): Checkout directly to file2, rather than + to finfo->file followed by rename. Remove check for whether + result of checkout is readable; that was for an old, obsolete, + form of death support. + +Sun Apr 13 13:16:40 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * checkout.c (build_one_dir): New function. + (struct dir_to_build): New structure. + (build_dirs_and_chir): Rewritten to accept a linked list of struct + dir_to_build rather than the silly string processing we had been + doing before. + (checkout_proc): Rewrite code that calls build_dirs_and_chdir + accordingly. + * sanity.sh: Enable tests modules3-10 and modules3-11 for local CVS; + tests for above fix. + + * rcs.h (RCS_CO): Removed; no longer used. + +Sun Apr 13 00:04:34 1997 Ian Lance Taylor <ian@cygnus.com> + + Expand RCS keywords internally; never call co: + * rcs.h (struct rcsversnode): Add state field. + * rcs.c (kflags): Move out of RCS_check_kflag, and make file + static. + (enum kflag): Define. + (RCS_reparsercsfile): Always save lock information. Save state in + new state field, rather than other field. + (struct rcs_keyword): Define. + (keywords): New static variable. + (enum keyword): Define. + (printable_date, escape_keyword_value): New static functions. + (expand_keywords): New static function. + (RCS_checkout): Call expand_keywords. Don't call + RCS_exec_checkout. + (RCS_deltas): Add log and loglen parameters. Change all callers. + * log.c (log_version_requested): Use new state field. + (log_version): Likewise. + * cvs.h (RCS_exec_checkout): Don't declare. + * rcscmds.c (RCS_exec_checkout): Remove. + +Sat Apr 12 17:32:59 1997 Ian Lance Taylor <ian@cygnus.com> + + * sanity.sh (modules3): Remove second-dir at end of tests. + (sticky): Correct removal of directories at end of tests. + + * sanity.sh (keyword): New tests for RCS keyword expansion. + +Sat Apr 12 16:47:13 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (basicb): New tests basicb-1b, basicb-1c, basicb-9b, + basic-9c test current build_dirs_and_chdir behavior. + +Fri Apr 11 23:54:56 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (modules3): New tests modules3-7* test for ability to + supply a path in -d in modules. Similar to modules3-8 through + modules3-11 except because the nesting is different, these ones + work. + +Thu Apr 10 00:14:47 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (modules3): New tests modules3-12 through modules3-15 + test use of a module name which contains a slash. + + * sanity.sh (basicb): New tests basicb-14 to basicb-20 test use of + co -d with two or more arguments. + + * rcscmds.c: Refer to doc/RCSFILES in comment. + +Wed Apr 9 09:49:17 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (basicb): New tests basicb-11 through basicb-13 test + ability to specify several directory levels in co -d (commented + out). + + * filesubr.c (fopen_case): If CVS_OPENDIR gives an + existence_error, return it to the caller instead of giving a fatal + error. + + * client.c (update_entries): Fix typo in call to error (1 -> errno). + +Tue Apr 8 23:02:22 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * error.h, error.c: Test for #ifdef __STDC__, not #if __STDC__. + This is consistent with other parts of CVS; it means that the + declaration for fperror will match the definition even if __STDC__ + is defined to 0 as the SunPro 4.0 compiler does. Reported by + Richard Smith <rjsmith@cisco.com>. + +2 Apr 1997 Jim Kingdon + + * entries.c (ParseTag): Add "break;" after "default:" to avoid + error from Visual C++. + +Wed Apr 2 12:06:44 1997 Vince Del Vecchio <vdelvecc@spd.analog.com> + and Jim Kingdon + + * client.c: In reporting errors from socket calls, use + SOCK_STRERROR and SOCK_ERRNO since strerror(errno) doesn't work + for Win32. + +Tue Apr 8 10:45:32 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (modules3): Add tests modules3-8 to modules3-11, to + test for ability to supply a path to -d in modules. Mostly + commented out as CVS is buggy in this area. + +Mon Apr 7 12:41:44 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * add.c (add): Add comment about SEND_NO_CONTENTS. + +Sun Apr 6 21:46:32 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * update.c (update): Add comment about noexec and SEND_NO_CONTENTS. + +Sun Apr 6 17:34:08 1997 Robert Bihlmeyer <robbe@orcus.priv.at> + + * Pass +f not f to getopt_long to prevent options from being + permuted with glibc 2.0.1. + +Sun Mar 30 00:07:05 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.h (struct vers_ts): Adjust comment regarding ts_user. + * server.c (serve_is_modified): New function. Set entries to show + that the file is modified but we don't know the contents. + * server.c (requests): Add "Is-modified" request. + * vers_ts.c (time_stamp_server): If the timestamp in entdata is + "M" or "D", just copy that over into ts_user. + * vers_ts.c (Version_TS): If timestamp is "D", use the entries + line for the sole purpose of passing it to time_stamp_server. + * no_diff.c (No_Difference): If ts_user is "M", conclude the files + are different. + * client.h, client.c (send_files): Replace arguments build_dirs + and force with argument flags. Add flag SEND_NO_CONTENTS and add + to struct send_data. + (send_fileproc): If no_contents, then send Is-modified instead of + Modified. + * add.c, admin.c, client.c, commit.c, diff.c, edit.c, log.c, + rcs.c, remove.c, status.c, tag.c, update.c, watch.c: Change all + send_files callers. + +Fri Mar 28 22:32:25 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * server.c (requests): Change "Repository" to rq_optional. I'm + not sure whether I overlooked this when I removed support for + Repository, or whether I was thinking that servers would need to + support it anyway, for CVS 1.5 to 1.9 clients, but making it + optional doesn't prevent the server from supporting it and it + seems silly for the client to complain about absence of a request + that it never will use. + +Fri Mar 28 10:06:59 1997 Steven Miller <Miller@wingra.com> + + * entries.c (Subdirs_Known): Don't create Entries.Log if noexec. + +Thu Mar 27 18:14:12 1997 Ian Lance Taylor <ian@cygnus.com> + + * sanity.sh (death2): Remove commented out test death2-21. It + would now pass, but it duplicates the new test sticky-11. + +Thu Mar 27 10:21:19 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (dotest_internal): Write test output to logfile even + if test succeeds. This was the behavior prior to 30 Sep 1996. + See the comment for rationale. + Tue Mar 25 13:26:52 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + * cvs.h, entries.c (WriteTag): Add arguments nonbranch, + update_dir, and repository. Move the server_set_sticky call from + callers to here. + * cvs.h, create_adm.c (Create_Admin): New argument nonbranch. + * cvs.h, entries.c (ParseTag): Add argument nonbranchp. + * cvs.h (struct stickydirtag): Add field nonbranch. + * entries.c (Entries_Open): Set it. + * cvs.h (Vers_TS): Add field nonbranch. + * vers_ts.c (Version_TS): Copy it from struct stickydirtag. + * server.c, server.h (server_set_sticky): Add argument nonbranch. + * add.c, client.c, checkout.c, modules.c, update.c, create_adm.c, + commit.c: Update callers. + * add.c (add): If nonbranch, don't add the file on that "branch". + * commit.c (write_dirnonbranch): New variable. + (commit_fileproc, commit): Set it. + (commit_dirleaveproc): Pass it to WriteTag. + * update.c (rewrite_tag, nonbranch): New variables. + (update, update_dirent_proc, update_fileproc): Set them. + (update_filesdoneproc): If rewrite_tag, call WriteTag. + * sanity.sh (sticky): New tests, test for above fix. + + * version.c: Change version number to 1.9.7. + * version.c: Version 1.9.6. Mon Mar 24 13:02:04 1997 Jim Kingdon <kingdon@harvey.cyclic.com> diff --git a/gnu/usr.bin/cvs/src/add.c b/gnu/usr.bin/cvs/src/add.c index 28faecc7839..8bba5bb62a1 100644 --- a/gnu/usr.bin/cvs/src/add.c +++ b/gnu/usr.bin/cvs/src/add.c @@ -103,7 +103,7 @@ add (argc, argv) /* parse args */ optind = 1; - while ((c = getopt (argc, argv, "k:m:")) != -1) + while ((c = getopt (argc, argv, "+k:m:")) != -1) { switch (c) { @@ -147,17 +147,18 @@ add (argc, argv) { char *tag; char *date; + int nonbranch; char *rcsdir; /* before we do anything else, see if we have any per-directory tags */ - ParseTag (&tag, &date); + ParseTag (&tag, &date, &nonbranch); rcsdir = combine_dir (repository, argv[i]); strip_trailing_slashes (argv[i]); - Create_Admin (argv[i], argv[i], rcsdir, tag, date); + Create_Admin (argv[i], argv[i], rcsdir, tag, date, nonbranch); if (tag) free (tag); @@ -179,7 +180,8 @@ add (argc, argv) } } send_file_names (argc, argv, SEND_EXPAND_WILD); - send_files (argc, argv, 0, 0, 1, 0); + /* FIXME: should be able to pass SEND_NO_CONTENTS, I think. */ + send_files (argc, argv, 0, 0, SEND_BUILD_DIRS); send_to_server ("add\012", 0); return get_responses_and_close (); } @@ -265,28 +267,39 @@ add (argc, argv) } } - /* There is a user file, so build the entry for it */ - if (build_entry (repository, user, vers->options, - message, entries, vers->tag) != 0) - err++; + if (vers->nonbranch) + { + error (0, 0, + "cannot add file on non-branch tag %s", + vers->tag); + ++err; + } else { - added_files++; - if (!quiet) + /* There is a user file, so build the entry for it */ + if (build_entry (repository, user, vers->options, + message, entries, vers->tag) != 0) + err++; + else { - if (vers->tag) - error (0, 0, "\ + added_files++; + if (!quiet) + { + if (vers->tag) + error (0, 0, "\ scheduling %s `%s' for addition on branch `%s'", - (wrap_name_has (user, WRAP_TOCVS) - ? "wrapper" - : "file"), - user, vers->tag); - else - error (0, 0, "scheduling %s `%s' for addition", - (wrap_name_has (user, WRAP_TOCVS) - ? "wrapper" - : "file"), - user); + (wrap_name_has (user, WRAP_TOCVS) + ? "wrapper" + : "file"), + user, vers->tag); + else + error (0, 0, + "scheduling %s `%s' for addition", + (wrap_name_has (user, WRAP_TOCVS) + ? "wrapper" + : "file"), + user); + } } } } @@ -302,20 +315,31 @@ same name already exists in the repository."); } else { - if (vers->tag) - error (0, 0, "\ -file `%s' will be added on branch `%s' from version %s", - user, vers->tag, vers->vn_rcs); + if (vers->nonbranch) + { + error (0, 0, + "cannot add file on non-branch tag %s", + vers->tag); + ++err; + } else - /* I'm not sure that mentioning vers->vn_rcs makes - any sense here; I can't think of a way to word the - message which is not confusing. */ - error (0, 0, "\ + { + if (vers->tag) + error (0, 0, "\ +file `%s' will be added on branch `%s' from version %s", + user, vers->tag, vers->vn_rcs); + else + /* I'm not sure that mentioning + vers->vn_rcs makes any sense here; I + can't think of a way to word the + message which is not confusing. */ + error (0, 0, "\ re-adding file %s (in place of dead revision %s)", - user, vers->vn_rcs); - Register (entries, user, "0", vers->ts_user, NULL, - vers->tag, NULL, NULL); - ++added_files; + user, vers->vn_rcs); + Register (entries, user, "0", vers->ts_user, NULL, + vers->tag, NULL, NULL); + ++added_files; + } } } else @@ -446,6 +470,7 @@ add_directory (repository, entries, dir) struct saved_cwd cwd; char *message = NULL; char *tag, *date; + int nonbranch; if (strchr (dir, '/') != NULL) { @@ -460,7 +485,7 @@ add_directory (repository, entries, dir) } /* before we do anything else, see if we have any per-directory tags */ - ParseTag (&tag, &date); + ParseTag (&tag, &date, &nonbranch); /* now, remember where we were, so we can get back */ if (save_cwd (&cwd)) @@ -550,9 +575,9 @@ add_directory (repository, entries, dir) #ifdef SERVER_SUPPORT if (!server_active) - Create_Admin (".", dir, rcsdir, tag, date); + Create_Admin (".", dir, rcsdir, tag, date, nonbranch); #else - Create_Admin (".", dir, rcsdir, tag, date); + Create_Admin (".", dir, rcsdir, tag, date, nonbranch); #endif if (tag) free (tag); diff --git a/gnu/usr.bin/cvs/src/checkin.c b/gnu/usr.bin/cvs/src/checkin.c index c5b5d073f16..3c6a3b2cd98 100644 --- a/gnu/usr.bin/cvs/src/checkin.c +++ b/gnu/usr.bin/cvs/src/checkin.c @@ -93,7 +93,8 @@ Checkin (type, finfo, rcs, rev, tag, options, message) /* FIXME: should be checking for errors. */ (void) RCS_checkout (finfo->rcs, finfo->file, rev, - (char *) NULL, options, RUN_TTY); + (char *) NULL, options, RUN_TTY, + (RCSCHECKOUTPROC) NULL, (void *) NULL); xchmod (finfo->file, 1); if (xcmp (finfo->file, fname) == 0) diff --git a/gnu/usr.bin/cvs/src/client.h b/gnu/usr.bin/cvs/src/client.h index d313c965e6e..6d92da51149 100644 --- a/gnu/usr.bin/cvs/src/client.h +++ b/gnu/usr.bin/cvs/src/client.h @@ -83,7 +83,12 @@ 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 force)); + unsigned int flags)); + +/* Flags for send_files. */ +#define SEND_BUILD_DIRS 1 +#define SEND_FORCE 2 +#define SEND_NO_CONTENTS 4 /* Send an argument to the remote server. */ void diff --git a/gnu/usr.bin/cvs/src/create_adm.c b/gnu/usr.bin/cvs/src/create_adm.c index e1f7773d3b8..0ef6e57fc5e 100644 --- a/gnu/usr.bin/cvs/src/create_adm.c +++ b/gnu/usr.bin/cvs/src/create_adm.c @@ -16,12 +16,13 @@ /* update_dir includes dir as its last component. */ void -Create_Admin (dir, update_dir, repository, tag, date) +Create_Admin (dir, update_dir, repository, tag, date, nonbranch) char *dir; char *update_dir; char *repository; char *tag; char *date; + int nonbranch; { FILE *fout; char *cp; @@ -123,12 +124,11 @@ Create_Admin (dir, update_dir, repository, tag, date) } /* Create a new CVS/Tag file */ - WriteTag (dir, tag, date); + WriteTag (dir, tag, date, nonbranch, update_dir, repository); #ifdef SERVER_SUPPORT if (server_active) { - server_set_sticky (update_dir, repository, tag, date); server_template (update_dir, repository); } diff --git a/gnu/usr.bin/cvs/src/error.c b/gnu/usr.bin/cvs/src/error.c index 0ed7eb24d37..5c7eef500ae 100644 --- a/gnu/usr.bin/cvs/src/error.c +++ b/gnu/usr.bin/cvs/src/error.c @@ -26,7 +26,7 @@ int error_use_protocol; #ifdef HAVE_VPRINTF -#if __STDC__ +#ifdef __STDC__ #include <stdarg.h> #define VA_START(args, lastarg) va_start(args, lastarg) #else /* ! __STDC__ */ @@ -50,7 +50,7 @@ int error_use_protocol; #include <stdlib.h> #include <string.h> #else /* ! STDC_HEADERS */ -#if __STDC__ +#ifdef __STDC__ void exit(int status); #else /* ! __STDC__ */ void exit (); @@ -86,7 +86,7 @@ error_exit PROTO ((void)) no need to print a message. */ /* VARARGS */ void -#if defined (HAVE_VPRINTF) && __STDC__ +#if defined (HAVE_VPRINTF) && defined (__STDC__) error (int status, int errnum, const char *message, ...) #else error (status, errnum, message, va_alist) @@ -213,7 +213,7 @@ error (status, errnum, message, va_alist) Exit with status EXIT_FAILURE if STATUS is nonzero. */ /* VARARGS */ void -#if defined (HAVE_VPRINTF) && ((__STDC__ - 0) > 0) +#if defined (HAVE_VPRINTF) && defined (__STDC__) fperror (FILE *fp, int status, int errnum, char *message, ...) #else fperror (fp, status, errnum, message, va_alist) diff --git a/gnu/usr.bin/cvs/src/error.h b/gnu/usr.bin/cvs/src/error.h index 5d37bb44d75..e0fde4a5bec 100644 --- a/gnu/usr.bin/cvs/src/error.h +++ b/gnu/usr.bin/cvs/src/error.h @@ -37,7 +37,7 @@ # endif #endif -#if __STDC__ +#ifdef __STDC__ void error (int, int, const char *, ...) \ __attribute__ ((__format__ (__printf__, 3, 4))); #else diff --git a/gnu/usr.bin/cvs/src/no_diff.c b/gnu/usr.bin/cvs/src/no_diff.c index 31ef057417f..384800fda6b 100644 --- a/gnu/usr.bin/cvs/src/no_diff.c +++ b/gnu/usr.bin/cvs/src/no_diff.c @@ -22,12 +22,17 @@ No_Difference (finfo, vers) Vers_TS *vers; { Node *p; - char *tmp; int ret; char *ts, *options; int retcode = 0; char *tocvsPath; + /* If ts_user is "Is-modified", we can only conclude the files are + different (since we don't have the file's contents). */ + if (vers->ts_user != NULL + && strcmp (vers->ts_user, "Is-modified") == 0) + return -1; + if (!vers->srcfile || !vers->srcfile->path) return (-1); /* different since we couldn't tell */ @@ -36,88 +41,51 @@ No_Difference (finfo, vers) else options = xstrdup (""); - tmp = cvs_temp_name (); - retcode = RCS_checkout (vers->srcfile, (char *) NULL, vers->vn_user, - (char *) NULL, options, tmp); + tocvsPath = wrap_tocvs_process_file (finfo->file); + retcode = RCS_cmp_file (vers->srcfile, vers->vn_user, options, + tocvsPath == NULL ? finfo->file : tocvsPath); if (retcode == 0) { -#if 0 - /* Why would we want to munge the modes? And only if the timestamps - are different? And even for commands like "cvs status"???? */ - if (!iswritable (finfo->file)) /* fix the modes as a side effect */ - xchmod (finfo->file, 1); -#endif - - tocvsPath = wrap_tocvs_process_file (finfo->file); - - /* do the byte by byte compare */ - if (xcmp (tocvsPath == NULL ? finfo->file : tocvsPath, tmp) == 0) - { -#if 0 - /* Why would we want to munge the modes? And only if the - timestamps are different? And even for commands like - "cvs status"???? */ - if (cvswrite == FALSE) /* fix the modes as a side effect */ - xchmod (finfo->file, 0); -#endif - - /* no difference was found, so fix the entries file */ - ts = time_stamp (finfo->file); - Register (finfo->entries, finfo->file, - vers->vn_user ? vers->vn_user : vers->vn_rcs, ts, - options, vers->tag, vers->date, (char *) 0); + /* no difference was found, so fix the entries file */ + ts = time_stamp (finfo->file); + Register (finfo->entries, finfo->file, + vers->vn_user ? vers->vn_user : vers->vn_rcs, ts, + options, vers->tag, vers->date, (char *) 0); #ifdef SERVER_SUPPORT - if (server_active) - { - /* We need to update the entries line on the client side. */ - server_update_entries - (finfo->file, finfo->update_dir, finfo->repository, SERVER_UPDATED); - } + if (server_active) + { + /* We need to update the entries line on the client side. */ + server_update_entries + (finfo->file, finfo->update_dir, finfo->repository, SERVER_UPDATED); + } #endif - free (ts); + free (ts); - /* update the entdata pointer in the vers_ts structure */ - p = findnode (finfo->entries, finfo->file); - vers->entdata = (Entnode *) p->data; + /* update the entdata pointer in the vers_ts structure */ + p = findnode (finfo->entries, finfo->file); + vers->entdata = (Entnode *) p->data; - ret = 0; - } - else - ret = 1; /* files were really different */ - if (tocvsPath) - { - /* Need to call unlink myself because the noexec variable - * has been set to 1. */ - if (trace) - (void) fprintf (stderr, "%c-> unlink (%s)\n", -#ifdef SERVER_SUPPORT - (server_active) ? 'S' : ' ', -#else - ' ', -#endif - tocvsPath); - if ( CVS_UNLINK (tocvsPath) < 0) - error (0, errno, "could not remove %s", tocvsPath); - } + ret = 0; } else - { - error (0, retcode == -1 ? errno : 0, - "could not check out revision %s of %s", - vers->vn_user, finfo->fullname); - ret = -1; /* different since we couldn't tell */ - } + ret = 1; /* files were really different */ - if (trace) + if (tocvsPath) + { + /* Need to call unlink myself because the noexec variable + * has been set to 1. */ + if (trace) + (void) fprintf (stderr, "%c-> unlink (%s)\n", #ifdef SERVER_SUPPORT - (void) fprintf (stderr, "%c-> unlink2 (%s)\n", - (server_active) ? 'S' : ' ', tmp); + (server_active) ? 'S' : ' ', #else - (void) fprintf (stderr, "-> unlink (%s)\n", tmp); + ' ', #endif - if (CVS_UNLINK (tmp) < 0) - error (0, errno, "could not remove %s", tmp); - free (tmp); + tocvsPath); + if ( CVS_UNLINK (tocvsPath) < 0) + error (0, errno, "could not remove %s", tocvsPath); + } + free (options); return (ret); } diff --git a/gnu/usr.bin/cvs/src/rcs.h b/gnu/usr.bin/cvs/src/rcs.h index 1305b8c754c..699280a79ad 100644 --- a/gnu/usr.bin/cvs/src/rcs.h +++ b/gnu/usr.bin/cvs/src/rcs.h @@ -10,7 +10,6 @@ #define RCS "rcs" #define RCS_CI "ci" -#define RCS_CO "co" #define RCS_DIFF "rcsdiff" #define RCS_RCSMERGE "rcsmerge" @@ -71,6 +70,7 @@ struct rcsversnode char *version; char *date; char *author; + char *state; char *next; int dead; List *branches; @@ -87,6 +87,9 @@ typedef struct rcsversnode RCSVers; */ #define RCS_MAGIC_BRANCH 0 +/* The type of a function passed to RCS_checkout. */ +typedef void (*RCSCHECKOUTPROC) PROTO ((void *, const char *, size_t)); + /* * exported interfaces */ @@ -113,7 +116,9 @@ char *RCS_getbranch PROTO((RCSNode * rcs, char *tag, int force_tag_match)); int RCS_isdead PROTO((RCSNode *, const char *)); char *RCS_getexpand PROTO ((RCSNode *)); -int RCS_checkout PROTO ((RCSNode *, char *, char *, char *, char *, char *)); +int RCS_checkout PROTO ((RCSNode *, char *, char *, char *, char *, char *, + RCSCHECKOUTPROC, void *)); +int RCS_cmp_file PROTO ((RCSNode *, char *, char *, const char *)); int RCS_settag PROTO ((RCSNode *, const char *, const char *)); int RCS_deltag PROTO ((RCSNode *, const char *, int)); int RCS_setbranch PROTO((RCSNode *, const char *)); diff --git a/gnu/usr.bin/cvs/src/remove.c b/gnu/usr.bin/cvs/src/remove.c index 6f31e0acb55..157125068fe 100644 --- a/gnu/usr.bin/cvs/src/remove.c +++ b/gnu/usr.bin/cvs/src/remove.c @@ -51,7 +51,7 @@ cvsremove (argc, argv) usage (remove_usage); optind = 1; - while ((c = getopt (argc, argv, "flR")) != -1) + while ((c = getopt (argc, argv, "+flR")) != -1) { switch (c) { @@ -100,7 +100,8 @@ cvsremove (argc, argv) if (local) send_arg("-l"); send_file_names (argc, argv, 0); - send_files (argc, argv, local, 0, 0, 0); + /* FIXME: Can't we set SEND_NO_CONTENTS here? Needs investigation. */ + send_files (argc, argv, local, 0, 0); send_to_server ("remove\012", 0); return get_responses_and_close (); } diff --git a/gnu/usr.bin/cvs/src/sanity.sh b/gnu/usr.bin/cvs/src/sanity.sh index 7906ec804c4..9f556209329 100644 --- a/gnu/usr.bin/cvs/src/sanity.sh +++ b/gnu/usr.bin/cvs/src/sanity.sh @@ -251,11 +251,24 @@ dotest_internal () else if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : \ "$3"${ENDANCHOR} >/dev/null; then + # See below about writing this to the logfile. + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} pass "$1" else if test x"$4" != x; then if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : \ "$4"${ENDANCHOR} >/dev/null; then + # Why, I hear you ask, do we write this to the logfile + # even when the test passes? The reason is that the test + # may give us the regexp which we were supposed to match, + # but sometimes it may be useful to look at the exact + # text which was output. For example, suppose one wants + # to grep for a particular warning, and make _sure_ that + # CVS never hits it (even in cases where the tests might + # match it with .*). Or suppose one wants to see the exact + # date format output in a certain case (where the test will + # surely use a somewhat non-specific pattern). + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} pass "$1" else echo "** expected: " >>${LOGFILE} @@ -466,6 +479,7 @@ RCSINIT=; export RCSINIT if test x"$*" = x; then 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" + tests="${tests} sticky keyword" else tests="$*" fi @@ -642,11 +656,24 @@ done' # Test the -f option to ci cd sdir/ssdir + dotest basica-8a0 "${testcvs} -q ci -m not-modified ssfile" '' 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' + dotest basica-8a1 "${testcvs} -q ci -m bump-it -r 2.0" \ +'Checking in ssfile; +/tmp/cvs-sanity/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.0; previous revision: 1\.3 +done' + # -f should not be necessary, but it should be harmless. + # Also test the "-r 3" (rather than "-r 3.0") usage. + dotest basica-8a2 "${testcvs} -q ci -m bump-it -f -r 3" \ +'Checking in ssfile; +/tmp/cvs-sanity/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 3\.1; previous revision: 2\.0 +done' cd ../.. dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" \ 'Index: sdir/ssdir/ssfile @@ -704,6 +731,12 @@ done' : mkdir ${CVSROOT_DIRNAME}/first-dir dotest basicb-1 "${testcvs} -q co first-dir" '' dotest basicb-1a "test -d CVS" '' + # See comment at modules3-7f for more on this behavior. + dotest basicb-1b "cat CVS/Repository" \ +"${TESTDIR}/cvsroot/first-dir" "${TESTDIR}/cvsroot/\." + dotest basicb-1c "cat first-dir/CVS/Repository" \ +"${TESTDIR}/cvsroot/first-dir" + cd first-dir mkdir sdir1 sdir2 dotest basicb-2 "${testcvs} add sdir1 sdir2" \ @@ -790,13 +823,84 @@ U first-dir1/sdir2/sfile2' 'U newdir/sdir1/sfile1 U newdir/sdir2/sfile2' dotest basicb-9a "test -d CVS" '' + # See comment at modules3-7f for more on this behavior. + dotest basicb-9b "cat CVS/Repository" \ +"${TESTDIR}/cvsroot/first-dir" "${TESTDIR}/cvsroot/\." + dotest basicb-9c "cat newdir/CVS/Repository" \ +"${TESTDIR}/cvsroot/CVSROOT/Emptydir" dotest basicb-10 "cat newdir/sdir1/sfile1 newdir/sdir2/sfile2" \ "sfile1 develops sfile2 starts" rm -rf newdir + # Hmm, this might be a case for CVSNULLREPOS, but CVS doesn't + # seem to deal with it... + if false; then + dotest basicb-11 "${testcvs} -q co -d sub1/sub2 first-dir" \ +"U sub1/sub2/sdir1/sfile1 +U sub1/sub2/sdir2/sfile2" + cd sub1 + dotest basicb-12 "${testcvs} -q update" '' + touch xx + dotest basicb-13 "${testcvs} add xx" fixme + cd .. + rm -r sub1 + # to test: sub1/sub2/sub3 + fi # end of tests commented out. + + # Create a second directory. + mkdir 1 + cd 1 + dotest basicb-14 "${testcvs} -q co -l ." 'U topfile' + mkdir second-dir + dotest basicb-15 "${testcvs} add second-dir" \ +"Directory ${TESTDIR}/cvsroot/second-dir added to the repository" + cd second-dir + touch aa + dotest basicb-16 "${testcvs} add aa" \ +"${PROG} [a-z]*: scheduling file .aa. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + dotest basicb-17 "${testcvs} -q ci -m add" \ +'RCS file: /tmp/cvs-sanity/cvsroot/second-dir/aa,v +done +Checking in aa; +/tmp/cvs-sanity/cvsroot/second-dir/aa,v <-- aa +initial revision: 1\.1 +done' + cd ../.. + rm -rf 1 + # Now here is the kicker: note that the semantics of -d + # are fundamentally different if we specify two or more directories + # rather than one! I consider this to be seriously bogus, + # but for the moment I am just trying to figure out what + # CVS's current behaviors are. + dotest basicb-18 "${testcvs} -q co -d test2 first-dir second-dir" \ +"U test2/first-dir/sdir1/sfile1 +U test2/first-dir/sdir2/sfile2 +U test2/second-dir/aa" + cd test2 + touch emptyfile + # The fact that CVS lets us add a file here is a CVS bug, right? + # I can just make this an error message (on the add and/or the + # commit) without getting flamed, right? + # Right? + # Right? + dotest basicb-19 "${testcvs} add emptyfile" \ +"${PROG} [a-z]*: scheduling file .emptyfile. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + dotest basicb-20 "${testcvs} -q ci -m add" \ +'RCS file: /tmp/cvs-sanity/cvsroot/CVSROOT/Emptydir/emptyfile,v +done +Checking in emptyfile; +/tmp/cvs-sanity/cvsroot/CVSROOT/Emptydir/emptyfile,v <-- emptyfile +initial revision: 1\.1 +done' + cd .. + rm -rf test2 + rm -rf ${CVSROOT_DIRNAME}/first-dir + rm -rf ${CVSROOT_DIRNAME}/second-dir rm -f ${CVSROOT_DIRNAME}/topfile,v ;; @@ -2176,12 +2280,6 @@ ${PROG} [a-z]*: file3 is no longer in the repository" dotest_fail death2-20 "test -f file2" - # Make sure we can't add a file on this nonbranch tag. - # FIXME: Right now CVS will let you add a file on a - # nonbranch tag, so this test is commented out. - # echo "bad revision" > file2 - # dotest death2-21 "${testcvs} add file2" "some error message" - # Make sure diff only reports appropriate files. dotest_fail death2-diff-13 "${testcvs} -q diff -r rdiff-tag" \ "${PROG} [a-z]*: file1 is a new entry, no comparison available" @@ -3931,6 +4029,10 @@ done' cat >modules <<EOF mod1 -a first-dir/file1 bigmod -a mod1 first-dir/file1 +namednest -d src/sub/dir first-dir +nestdeeper -d src/sub1/sub2/sub3/dir first-dir +nestshallow -d src/dir second-dir/suba/subb +path/in/modules &mod1 EOF dotest modules3-5 "${testcvs} -q ci -m add-modules" \ "Checking in modules; @@ -3944,9 +4046,128 @@ ${PROG} [a-z]*: Rebuilding administrative file database" rm -rf first-dir dotest modules3-7 "${testcvs} -q co bigmod" 'U first-dir/file1' cd .. + rm -r 1 + + mkdir 1; cd 1 + mkdir suba + mkdir suba/subb + # This fails to work remote (it doesn't notice the directories, + # I suppose because they contain no files). Bummer, especially + # considering this is a documented technique and everything. + dotest modules3-7a \ +"${testcvs} import -m add-dirs second-dir tag1 tag2" \ +"${PROG} [a-z]*: Importing /tmp/cvs-sanity/cvsroot/second-dir/suba +${PROG} [a-z]*: Importing /tmp/cvs-sanity/cvsroot/second-dir/suba/subb + +No conflicts created by this import" " +No conflicts created by this import" + cd ..; rm -r 1 + mkdir 1; cd 1 + dotest modules3-7b "${testcvs} co second-dir" \ +"${PROG} [a-z]*: Updating second-dir +${PROG} [a-z]*: Updating second-dir/suba +${PROG} [a-z]*: Updating second-dir/suba/subb" \ +"${PROG} server: Updating second-dir" + + if test "x$remote" = xyes; then + cd second-dir + mkdir suba + dotest modules3-7-workaround1 "${testcvs} add suba" \ +"Directory ${TESTDIR}/cvsroot/second-dir/suba added to the repository" + cd suba + mkdir subb + dotest modules3-7-workaround2 "${testcvs} add subb" \ +"Directory ${TESTDIR}/cvsroot/second-dir/suba/subb added to the repository" + cd ../.. + fi + + cd second-dir/suba/subb + touch fileb + dotest modules3-7c "${testcvs} add fileb" \ +"${PROG} [a-z]*: scheduling file .fileb. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + dotest modules3-7d "${testcvs} -q ci -m add-it" \ +'RCS file: /tmp/cvs-sanity/cvsroot/second-dir/suba/subb/fileb,v +done +Checking in fileb; +/tmp/cvs-sanity/cvsroot/second-dir/suba/subb/fileb,v <-- fileb +initial revision: 1\.1 +done' + cd ../../.. + cd ..; rm -r 1 + + mkdir 1; cd 1 + dotest modules3-7e "${testcvs} -q co nestshallow" \ +"U src/dir/fileb" + + # Using ${TESTDIR}/cvsroot/second-dir/suba instead of + # ${TESTDIR}/cvsroot/second-dir seems wrong, it seems like the + # 30 Dec 1996 change to build_dirs_and_chdir simply failed + # to consider what to put in CVS/Repository. + # Remote does "${TESTDIR}/cvsroot/\." which seems equally wrong, + # if in a different way, but variety is the spice of life, + # eh? + dotest modules3-7f "cat CVS/Repository" \ +"${TESTDIR}/cvsroot/second-dir/suba" "${TESTDIR}/cvsroot/\." + + dotest modules3-7g "cat src/CVS/Repository" \ +"${TESTDIR}/cvsroot/second-dir/suba" + dotest modules3-7h "cat src/dir/CVS/Repository" \ +"${TESTDIR}/cvsroot/second-dir/suba/subb" + cd ..; rm -r 1 + mkdir 1 + cd 1 + dotest modules3-8 "${testcvs} -q co namednest" \ +'U src/sub/dir/file1' + dotest modules3-9 "test -f src/sub/dir/file1" '' + cd .. + rm -r 1 + + # Try the same thing, but with the directories nested even + # deeper (deeply enough so they are nested more deeply than + # the number of directories from / to ${TESTDIR}). + mkdir 1 + cd 1 + dotest modules3-10 "${testcvs} -q co nestdeeper" \ +'U src/sub1/sub2/sub3/dir/file1' + dotest modules3-11 "test -f src/sub1/sub2/sub3/dir/file1" '' + cd .. rm -r 1 + + # This one is almost too twisted for words. The pathname output + # in the message from "co" doesn't include the "path/in/modules", + # but those directories do get created (with no CVSADM except + # in "modules" which has a CVSNULLREPOS). + # I'm not sure anyone is relying on this nonsense or whether we + # need to keep doing it, but it is what CVS currently does... + # Skip it for remote; the remote code has the good sense to + # not deal with it (on the minus side it gives + # "internal error: repository string too short." instead of a + # real error). + # I kind of suspect that it would be OK to just make it a fatal + # error to have '/' in a module name. + if test "x$remote" = xno; then + mkdir 1; cd 1 + dotest modules3-12 "${testcvs} -q co path/in/modules" \ +"U first-dir/file1" + dotest modules3-13 "test -f path/in/modules/first-dir/file1" '' + cd ..; rm -r 1 + + # Now here is where it gets seriously bogus. + mkdir 1; cd 1 + dotest modules3-14 \ +"${testcvs} -q rtag tag1 path/in/modules" '' + # CVS creates this even though rtag should *never* affect + # the directory current when it is called! + dotest modules3-15 "test -d path/in/modules" '' + # Just for trivia's sake, rdiff is not similarly vulnerable + # because it passes 0 for run_module_prog to do_module. + cd ..; rm -r 1 + fi # end of tests skipped for remote + rm -rf ${CVSROOT_DIRNAME}/first-dir + rm -rf ${CVSROOT_DIRNAME}/second-dir ;; mflag) @@ -5715,11 +5936,293 @@ done' fi cd ../.. - rm -rf 1 ${TESTDIR}/first-dir + rm -rf 1 ${CVSROOT_DIRNAME}/first-dir # Perhaps should restore the umask and CVSUMASK. But the other # tests "should" not care about them... ;; + sticky) + # More tests of sticky tags, particularly non-branch sticky tags. + mkdir 1; cd 1 + dotest sticky-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest sticky-2 "${testcvs} add first-dir" \ +"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" + cd first-dir + + touch file1 + dotest sticky-3 "${testcvs} add file1" \ +"${PROG} [a-z]*: scheduling file .file1. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + dotest sticky-4 "${testcvs} -q ci -m add" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +done +Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done" + dotest sticky-5 "${testcvs} -q tag tag1" "T file1" + echo add a line >>file1 + dotest sticky-6 "${testcvs} -q ci -m modify" \ +"Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +done" + dotest sticky-7 "${testcvs} -q update -r tag1" "[UP] file1" + dotest sticky-8 "cat file1" '' + dotest sticky-9 "${testcvs} -q update" '' + dotest sticky-10 "cat file1" '' + touch file2 + dotest_fail sticky-11 "${testcvs} add file2" \ +"${PROG} [a-z]*: cannot add file on non-branch tag tag1" + dotest sticky-12 "${testcvs} -q update -A" "[UP] file1 +${QUESTION} file2" "${QUESTION} file2 +[UP] file1" + dotest sticky-13 "${testcvs} add file2" \ +"${PROG} [a-z]*: scheduling file .file2. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + + cd ../.. + rm -rf 1 ${CVSROOT_DIRNAME}/first-dir + ;; + + keyword) + # Test keyword expansion. + mkdir 1; cd 1 + dotest keyword-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest keyword-2 "${testcvs} add first-dir" \ +"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" + cd first-dir + + echo '$''Author$' > file1 + echo '$''Date$' >> file1 + echo '$''Header$' >> file1 + echo '$''Id$' >> file1 + echo '$''Locker$' >> file1 + echo '$''Name$' >> file1 + echo '$''RCSfile$' >> file1 + echo '$''Revision$' >> file1 + echo '$''Source$' >> file1 + echo '$''State$' >> file1 + echo '$''Nonkey$' >> file1 + # Omit the trailing dollar sign + echo '$''Date' >> file1 + # Put two keywords on one line + echo '$''State$' '$''State$' >> file1 + # Use a header for Log + echo 'xx $''Log$' >> file1 + + dotest keyword-3 "${testcvs} add file1" \ +"${PROG} [a-z]*: scheduling file .file1. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + dotest keyword-4 "${testcvs} -q ci -m add" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +done +Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done" + dotest keyword-5 "cat file1" \ +'\$'"Author: ${username} "'\$'" +"'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" +"'\$'"Header: ${TESTDIR}/cvsroot/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" +"'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" +"'\$'"Locker: "'\$'" +"'\$'"Name: "'\$'" +"'\$'"RCSfile: file1,v "'\$'" +"'\$'"Revision: 1\.1 "'\$'" +"'\$'"Source: ${TESTDIR}/cvsroot/first-dir/file1,v "'\$'" +"'\$'"State: Exp "'\$'" +"'\$'"Nonkey"'\$'" +"'\$'"Date +"'\$'"State: Exp "'\$'" "'\$'"State: Exp "'\$'" +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.1 [0-9/]* [0-9:]* ${username} +xx add +xx" + + # Use cvs admin to lock the RCS file in order to check -kkvl + # vs. -kkv. CVS does not normally lock RCS files, but some + # people use cvs admin to enforce reserved checkouts. + dotest keyword-6 "${testcvs} admin -l file1" \ +"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v +1\.1 locked +done" + + dotest keyword-7 "${testcvs} update -kkv file1" "U file1" + dotest keyword-8 "cat file1" \ +'\$'"Author: ${username} "'\$'" +"'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" +"'\$'"Header: ${TESTDIR}/cvsroot/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" +"'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" +"'\$'"Locker: "'\$'" +"'\$'"Name: "'\$'" +"'\$'"RCSfile: file1,v "'\$'" +"'\$'"Revision: 1\.1 "'\$'" +"'\$'"Source: ${TESTDIR}/cvsroot/first-dir/file1,v "'\$'" +"'\$'"State: Exp "'\$'" +"'\$'"Nonkey"'\$'" +"'\$'"Date +"'\$'"State: Exp "'\$'" "'\$'"State: Exp "'\$'" +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.1 [0-9/]* [0-9:]* ${username} +xx add +xx" + + dotest keyword-9 "${testcvs} update -kkvl file1" "U file1" + dotest keyword-10 "cat file1" \ +'\$'"Author: ${username} "'\$'" +"'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" +"'\$'"Header: ${TESTDIR}/cvsroot/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp ${username} "'\$'" +"'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp ${username} "'\$'" +"'\$'"Locker: ${username} "'\$'" +"'\$'"Name: "'\$'" +"'\$'"RCSfile: file1,v "'\$'" +"'\$'"Revision: 1\.1 "'\$'" +"'\$'"Source: ${TESTDIR}/cvsroot/first-dir/file1,v "'\$'" +"'\$'"State: Exp "'\$'" +"'\$'"Nonkey"'\$'" +"'\$'"Date +"'\$'"State: Exp "'\$'" "'\$'"State: Exp "'\$'" +xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.1 [0-9/]* [0-9:]* ${username} +xx add +xx" + + dotest keyword-11 "${testcvs} update -kk file1" "U file1" + dotest keyword-12 "cat file1" \ +'\$'"Author"'\$'" +"'\$'"Date"'\$'" +"'\$'"Header"'\$'" +"'\$'"Id"'\$'" +"'\$'"Locker"'\$'" +"'\$'"Name"'\$'" +"'\$'"RCSfile"'\$'" +"'\$'"Revision"'\$'" +"'\$'"Source"'\$'" +"'\$'"State"'\$'" +"'\$'"Nonkey"'\$'" +"'\$'"Date +"'\$'"State"'\$'" "'\$'"State"'\$'" +xx "'\$'"Log"'\$'" +xx Revision 1\.1 [0-9/]* [0-9:]* ${username} +xx add +xx" + + dotest keyword-13 "${testcvs} update -kv file1" "U file1" + dotest keyword-14 "cat file1" \ +"${username} +[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] +${TESTDIR}/cvsroot/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp +file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp + + +file1,v +1\.1 +${TESTDIR}/cvsroot/first-dir/file1,v +Exp +"'\$'"Nonkey"'\$'" +"'\$'"Date +Exp Exp +xx file1,v +xx Revision 1\.1 [0-9/]* [0-9:]* ${username} +xx add +xx" + + dotest keyword-15 "${testcvs} update -ko file1" "U file1" + dotest keyword-16 "cat file1" \ +'\$'"Author"'\$'" +"'\$'"Date"'\$'" +"'\$'"Header"'\$'" +"'\$'"Id"'\$'" +"'\$'"Locker"'\$'" +"'\$'"Name"'\$'" +"'\$'"RCSfile"'\$'" +"'\$'"Revision"'\$'" +"'\$'"Source"'\$'" +"'\$'"State"'\$'" +"'\$'"Nonkey"'\$'" +"'\$'"Date +"'\$'"State"'\$'" "'\$'"State"'\$'" +xx "'\$'"Log"'\$' + + # Test the Name keyword. First go back to normal expansion. + + # FIXME: When using remote, update -A does not revert the + # keyword expansion mode. We work around that bug here. + # This workaround should be removed when the bug is fixed. + if test "x$remote" = "xyes"; then + cd .. + rm -rf first-dir + dotest keyword-17 "${testcvs} -q co first-dir" "U first-dir/file1" + cd first-dir + else + dotest keyword-17 "${testcvs} update -A file1" "U file1" + fi + + echo '$''Name$' > file1 + dotest keyword-18 "${testcvs} ci -m modify file1" \ +"Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +done" + dotest keyword-19 "${testcvs} -q tag tag1" "T file1" + echo "change" >> file1 + dotest keyword-20 "${testcvs} -q ci -m mod2 file1" \ +"Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2 +done" + dotest keyword-21 "${testcvs} -q update -r tag1" "[UP] file1" + + # FIXME: This test fails when remote. The second expect + # string below should be removed when this is fixed. + dotest keyword-22 "cat file1" '\$'"Name: tag1 "'\$' \ +'\$'"Name: "'\$' + + dotest keyword-23 "${testcvs} update -A file1" "[UP] file1" + + # Test the Log keyword. + echo 'xx $''Log$' > file1 + cat >${TESTDIR}/comment.tmp <<EOF +First log line +Second log line +EOF + dotest keyword-24 "${testcvs} ci -F ${TESTDIR}/comment.tmp file1" \ +"Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.4; previous revision: 1\.3 +done" + rm -f ${TESTDIR}/comment.tmp + dotest keyword-25 "cat file1" \ +"xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.4 [0-9/]* [0-9:]* ${username} +xx First log line +xx Second log line +xx" + + echo "change" >> file1 + dotest keyword-26 "${testcvs} ci -m modify file1" \ +"Checking in file1; +${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.5; previous revision: 1\.4 +done" + dotest keyword-27 "cat file1" \ +"xx "'\$'"Log: file1,v "'\$'" +xx Revision 1\.5 [0-9/]* [0-9:]* ${username} +xx modify +xx +xx Revision 1\.4 [0-9/]* [0-9:]* ${username} +xx First log line +xx Second log line +xx +change" + + cd ../.. + rm -rf 1 ${CVSROOT_DIRNAME}/first-dir + ;; + *) 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 b794a2e43ab..67b71beb565 100644 --- a/gnu/usr.bin/cvs/src/status.c +++ b/gnu/usr.bin/cvs/src/status.c @@ -41,7 +41,7 @@ status (argc, argv) usage (status_usage); optind = 1; - while ((c = getopt (argc, argv, "vlR")) != -1) + while ((c = getopt (argc, argv, "+vlR")) != -1) { switch (c) { @@ -77,9 +77,13 @@ status (argc, argv) send_arg("-l"); 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, 0); + /* Note that by setting SEND_NO_CONTENTS, we do prevent the + server from updating our timestamp if the timestamp is + unchanged and the file is unmodified. And I think it is a + user-visible thing in that case (shows "locally modified" + instead of "up to date" I would think). But the speed seems + to be worth it. */ + send_files (argc, argv, local, 0, SEND_NO_CONTENTS); send_to_server ("status\012", 0); err = get_responses_and_close (); diff --git a/gnu/usr.bin/cvs/src/tag.c b/gnu/usr.bin/cvs/src/tag.c index cee7aecbbe8..9c49da562bb 100644 --- a/gnu/usr.bin/cvs/src/tag.c +++ b/gnu/usr.bin/cvs/src/tag.c @@ -83,7 +83,7 @@ cvstag (argc, argv) usage (tag_usage); optind = 1; - while ((c = getopt (argc, argv, "FQqlRcdr:D:bf")) != -1) + while ((c = getopt (argc, argv, "+FQqlRcdr:D:bf")) != -1) { switch (c) { @@ -177,10 +177,14 @@ cvstag (argc, argv) send_arg (symtag); send_file_names (argc, argv, SEND_EXPAND_WILD); - /* 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, 0); + + /* SEND_NO_CONTENTS has a mildly bizarre interaction with + check_uptodate; if the timestamp is modified but the file + is unmodified, the check will fail, only to have "cvs diff" + show no differences (and one must do "update" or something to + reset the client's notion of the timestamp). */ + + send_files (argc, argv, local, 0, SEND_NO_CONTENTS); send_to_server ("tag\012", 0); return get_responses_and_close (); } diff --git a/gnu/usr.bin/cvs/src/vers_ts.c b/gnu/usr.bin/cvs/src/vers_ts.c index d7420e7160d..03a0036202c 100644 --- a/gnu/usr.bin/cvs/src/vers_ts.c +++ b/gnu/usr.bin/cvs/src/vers_ts.c @@ -9,7 +9,7 @@ #include "cvs.h" #ifdef SERVER_SUPPORT -static void time_stamp_server PROTO((char *, Vers_TS *)); +static void time_stamp_server PROTO((char *, Vers_TS *, Entnode *)); #endif /* @@ -30,6 +30,7 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time) RCSNode *rcsdata; Vers_TS *vers_ts; struct stickydirtag *sdtp; + Entnode *entdata; /* get a new Vers_TS struct */ vers_ts = (Vers_TS *) xmalloc (sizeof (Vers_TS)); @@ -51,29 +52,40 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time) sdtp = (struct stickydirtag *) finfo->entries->list->data; /* list-private */ } + entdata = NULL; if (p != NULL) { - Entnode *entdata = (Entnode *) p->data; + entdata = (Entnode *) p->data; - vers_ts->vn_user = xstrdup (entdata->version); - vers_ts->ts_rcs = xstrdup (entdata->timestamp); - vers_ts->ts_conflict = xstrdup (entdata->conflict); - if (!tag) - { - if (!(sdtp && sdtp->aflag)) - vers_ts->tag = xstrdup (entdata->tag); - } - if (!date) - { - if (!(sdtp && sdtp->aflag)) - vers_ts->date = xstrdup (entdata->date); - } - if (!options || (options && *options == '\0')) +#ifdef SERVER_SUPPORT + /* An entries line with "D" in the timestamp indicates that the + client sent Is-modified without sending Entry. So we want to + use the entries line for the sole purpose of telling + time_stamp_server what is up; we don't want the rest of CVS + to think there is an entries line. */ + if (strcmp (entdata->timestamp, "D") != 0) +#endif { - if (!(sdtp && sdtp->aflag)) - vers_ts->options = xstrdup (entdata->options); + vers_ts->vn_user = xstrdup (entdata->version); + vers_ts->ts_rcs = xstrdup (entdata->timestamp); + vers_ts->ts_conflict = xstrdup (entdata->conflict); + if (!tag) + { + if (!(sdtp && sdtp->aflag)) + vers_ts->tag = xstrdup (entdata->tag); + } + if (!date) + { + if (!(sdtp && sdtp->aflag)) + vers_ts->date = xstrdup (entdata->date); + } + if (!options || (options && *options == '\0')) + { + if (!(sdtp && sdtp->aflag)) + vers_ts->options = xstrdup (entdata->options); + } + vers_ts->entdata = entdata; } - vers_ts->entdata = entdata; } /* @@ -114,7 +126,10 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time) else if (!vers_ts->entdata && (sdtp && sdtp->aflag == 0)) { if (!vers_ts->tag) + { vers_ts->tag = xstrdup (sdtp->tag); + vers_ts->nonbranch = sdtp->nonbranch; + } if (!vers_ts->date) vers_ts->date = xstrdup (sdtp->date); } @@ -177,7 +192,7 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time) { #ifdef SERVER_SUPPORT if (server_active) - time_stamp_server (finfo->file, vers_ts); + time_stamp_server (finfo->file, vers_ts, entdata); else #endif vers_ts->ts_user = time_stamp (finfo->file); @@ -195,9 +210,10 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time) #define mark_unchanged(V) ((V)->ts_user = xstrdup ((V)->ts_rcs)) static void -time_stamp_server (file, vers_ts) +time_stamp_server (file, vers_ts, entdata) char *file; Vers_TS *vers_ts; + Entnode *entdata; { struct stat sb; char *cp; @@ -215,11 +231,16 @@ time_stamp_server (file, vers_ts) lost. I don't know that that's right, but it's not clear to me that either choice is. Besides, would we have an RCS string in that case anyways? */ - if (vers_ts->entdata == NULL) + if (entdata == NULL) mark_lost (vers_ts); - else if (vers_ts->entdata->timestamp - && vers_ts->entdata->timestamp[0] == '=') + else if (entdata->timestamp + && entdata->timestamp[0] == '=') mark_unchanged (vers_ts); + else if (entdata->timestamp != NULL + && (entdata->timestamp[0] == 'M' + || entdata->timestamp[0] == 'D') + && entdata->timestamp[1] == '\0') + vers_ts->ts_user = xstrdup ("Is-modified"); else mark_lost (vers_ts); } diff --git a/gnu/usr.bin/cvs/src/version.c b/gnu/usr.bin/cvs/src/version.c index 8921e787a76..8e19b26bf35 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.6"; +char *version_string = "\nConcurrent Versions System (CVS) 1.9.8"; #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 51b50fcd10e..70deb7c3477 100644 --- a/gnu/usr.bin/cvs/src/watch.c +++ b/gnu/usr.bin/cvs/src/watch.c @@ -256,7 +256,7 @@ watch_addremove (argc, argv) the_args.edit = 0; the_args.unedit = 0; optind = 1; - while ((c = getopt (argc, argv, "la:")) != -1) + while ((c = getopt (argc, argv, "+la:")) != -1) { switch (c) { @@ -333,10 +333,7 @@ watch_addremove (argc, argv) send_arg ("none"); } send_file_names (argc, argv, SEND_EXPAND_WILD); - /* 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, 0); + send_files (argc, argv, local, 0, SEND_NO_CONTENTS); send_to_server (the_args.adding ? "watch-add\012" : "watch-remove\012", 0); @@ -483,7 +480,7 @@ watchers (argc, argv) usage (watchers_usage); optind = 1; - while ((c = getopt (argc, argv, "l")) != -1) + while ((c = getopt (argc, argv, "+l")) != -1) { switch (c) { @@ -508,10 +505,7 @@ watchers (argc, argv) if (local) send_arg ("-l"); send_file_names (argc, argv, SEND_EXPAND_WILD); - /* 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, 0); + send_files (argc, argv, local, 0, SEND_NO_CONTENTS); send_to_server ("watchers\012", 0); return get_responses_and_close (); } diff --git a/gnu/usr.bin/cvs/windows-NT/ChangeLog b/gnu/usr.bin/cvs/windows-NT/ChangeLog index 3ec249be90d..9db56c70e32 100644 --- a/gnu/usr.bin/cvs/windows-NT/ChangeLog +++ b/gnu/usr.bin/cvs/windows-NT/ChangeLog @@ -1,3 +1,46 @@ +Thu Apr 17 00:15:36 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in: Add sockerror.c. + +Wed Apr 9 15:29:45 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (expand_wild): Add comments about "." and comparing + NULL pointers. + +8 Apr 1997 Jim Kingdon + + * rcmd.c: Instead of returning -1 and passing that back to + startserver.c which will print a very vague error message, call + error() right away with a specific message. This also fixes + some places where we had bogusly called GetLastError instead of + WSAGetLastError. + (init_winsock): Remove call to setsockopt. It was an artifact + from before the time that we defined NO_SOCKET_TO_FD, doesn't + seem to be needed any more, and fails with some non-Microsoft + winsock implementations. + +Wed Apr 2 14:08:10 1997 Vince Del Vecchio <vdelvecc@spd.analog.com> + and Jim Kingdon + + * sockerror.c: New file. + * config.h (SOCK_STRERROR, SOCK_ERRNO): New macros. + * startserver.c: In reporting errors from socket calls, use + SOCK_STRERROR and SOCK_ERRNO since strerror(errno) doesn't work + for Win32. + * rcmd.c (rcmd_authenticate): Use WSASetLastError instead of + assigning to errno, since that is where the caller will look. + +Sun Apr 6 17:22:19 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (copy_file): Add comment about CopyFile. + +Wed Mar 26 13:13:41 1997 Jim Kingdon <kingdon@harvey.cyclic.com> + + * README: Also mention tar and gzip. + + * README: Binaries are now under 1.9, not 1.8.3, on + ftp.cyclic.com. Also mention http URL. + 13 Mar 1997 Jim Kingdon <kingdon@harvey.cyclic.com> * filesubr.c (get_homedir): Allocate pathbuf; removes arbitrary diff --git a/gnu/usr.bin/cvs/windows-NT/Makefile.in b/gnu/usr.bin/cvs/windows-NT/Makefile.in index 1798db912ee..f901edfe4e4 100644 --- a/gnu/usr.bin/cvs/windows-NT/Makefile.in +++ b/gnu/usr.bin/cvs/windows-NT/Makefile.in @@ -26,6 +26,7 @@ SOURCES = \ pwd.c \ rcmd.c \ run.c \ + sockerror.c \ startserver.c \ stripslash.c \ waitpid.c \ diff --git a/gnu/usr.bin/cvs/windows-NT/README b/gnu/usr.bin/cvs/windows-NT/README index f4115e9f7d2..2a821746b4b 100644 --- a/gnu/usr.bin/cvs/windows-NT/README +++ b/gnu/usr.bin/cvs/windows-NT/README @@ -50,9 +50,12 @@ following packages: ftp://ftp.netcom.com/pub/al/alexande/rcs57nt.zip ftp://ftp.netcom.com/pub/al/alexande/diff57nt.zip -Copies of these zip files can be also be found at: +Copies of these zip files can be also be found in the windows-nt +directory for the latest CVS release (cvs-1.9/windows-nt, for example) +under: - ftp://ftp.cyclic.com/pub/cvs/cvs-1.8.3/windows-nt + ftp://ftp.cyclic.com/pub/cvs/ or + http://www.cyclic.com/archive/pub/cvs/ If you want to try other versions of these utilities, you might have luck with the Congruent ports of these packages to Windows NT, binary @@ -60,6 +63,10 @@ and source: ftp://microlib.cc.utexas.edu/microlib/nt/gnu/ +In particular, microlib seems to have versions of GNU tar and gzip +which support long file names, which you will need to unpack the CVS +source distribution. + The CYGWIN32 package is a port of various GNU tools for NT, providing bash as the shell and gcc as the compiler. The tools are still in development, but they are useful for running a modified version of diff --git a/gnu/usr.bin/cvs/windows-NT/SCC/.cvsignore b/gnu/usr.bin/cvs/windows-NT/SCC/.cvsignore index fa65c0961ea..be11970367c 100644 --- a/gnu/usr.bin/cvs/windows-NT/SCC/.cvsignore +++ b/gnu/usr.bin/cvs/windows-NT/SCC/.cvsignore @@ -1,3 +1,4 @@ SCC.mdp SCC.ncb Debug +Makefile diff --git a/gnu/usr.bin/cvs/windows-NT/config.h b/gnu/usr.bin/cvs/windows-NT/config.h index abcf0189597..0fb42bf9d3b 100644 --- a/gnu/usr.bin/cvs/windows-NT/config.h +++ b/gnu/usr.bin/cvs/windows-NT/config.h @@ -314,6 +314,19 @@ extern void init_winsock(); it because _open_osfhandle doesn't work. */ #define NO_SOCKET_TO_FD 1 +/* This tells the client that, in addition to needing to use + send()/recv() to do socket I/O, the error codes for send()/recv() + and other socket operations are not available through errno. + Instead, this macro should be used to obtain an error code. */ +#define SOCK_ERRNO (WSAGetLastError ()) + +/* This tells the client that, in addition to needing to use + send()/recv() to do socket I/O, the error codes for send()/recv() + and other socket operations are not known to strerror. Instead, + this macro should be used to convert the error codes to strings. */ +#define SOCK_STRERROR sock_strerror +extern char *sock_strerror (int errnum); + /* The internal rsh client uses sockets not file descriptors. Note that as the code stands now, it often takes values from a SOCKET and puts them in an int. This is ugly but it seems like sizeof diff --git a/gnu/usr.bin/cvs/windows-NT/filesubr.c b/gnu/usr.bin/cvs/windows-NT/filesubr.c index da5a3c86230..6ad8d76359f 100644 --- a/gnu/usr.bin/cvs/windows-NT/filesubr.c +++ b/gnu/usr.bin/cvs/windows-NT/filesubr.c @@ -24,9 +24,13 @@ static int deep_remove_dir PROTO((const char *path)); -/* - * Copies "from" to "to". - */ +/* Copies "from" to "to". Note that the functionality here is similar + to the win32 function CopyFile, but (1) we copy LastAccessTime and + CopyFile doesn't, (2) we set file attributes to the default set by + the C library and CopyFile copies them. Neither #1 nor #2 was intentional + as far as I know, but changing them could be confusing, unless there + is some reason they should be changed (this would need more + investigation). */ void copy_file (from, to) const char *from; @@ -905,6 +909,14 @@ expand_wild (argc, argv, pargc, pargv) char *last_forw_slash, *last_back_slash, *end_of_dirname; int dirname_length = 0; + /* FIXME: If argv[i] is ".", this code will expand it to the + name of the current directory in its parent directory which + will cause start_recursion to do all manner of strange things + with it (culminating in an error). This breaks "cvs co .". + As nearly as I can guess, this bug has existed since + expand_wild was first created. At least, it is in CVS 1.9 (I + just tried it). */ + /* FindFirstFile doesn't return pathnames, so we have to do this ourselves. Luckily, it's no big deal, since globbing characters under Win32s can only occur in the last segment @@ -920,6 +932,9 @@ expand_wild (argc, argv, pargc, pargv) #define cvs_max(x,y) ((x >= y) ? (x) : (y)) + /* FIXME: this comparing a NULL pointer to a non-NULL one is + extremely ugly, and I strongly suspect *NOT* sanctioned by + ANSI C. The code should just use last_component instead. */ end_of_dirname = cvs_max (last_forw_slash, last_back_slash); if (end_of_dirname == NULL) diff --git a/gnu/usr.bin/cvs/windows-NT/rcmd.c b/gnu/usr.bin/cvs/windows-NT/rcmd.c index e0f3619ae45..d31cba2c04b 100644 --- a/gnu/usr.bin/cvs/windows-NT/rcmd.c +++ b/gnu/usr.bin/cvs/windows-NT/rcmd.c @@ -16,23 +16,21 @@ void init_winsock () { WSADATA data; - int optionValue = SO_SYNCHRONOUS_NONALERT; if (WSAStartup (MAKEWORD (1, 1), &data)) { fprintf (stderr, "cvs: unable to initialize winsock\n"); exit (1); } - - if (setsockopt(INVALID_SOCKET, SOL_SOCKET, - SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue)) - == SOCKET_ERROR) - { - fprintf (stderr, "cvs: unable to setup winsock\n"); - exit (1); - } } +/* The rest of this file contains the rcmd() code, which is used + only by START_SERVER. The idea for a long-term direction is + that this code can be made portable (by using SOCK_ERRNO and + so on), and then moved to client.c or someplace it can be + shared with the VMS port and any other ports which may want it. */ + + static int resolve_address (const char **ahost, struct sockaddr_in *sai) { @@ -61,34 +59,9 @@ resolve_address (const char **ahost, struct sockaddr_in *sai) } } - return -1; + error (1, 0, "no such host %s", *ahost); } -#if 0 -static int -bind_local_end (SOCKET s) -{ - struct sockaddr_in sai; - int result; - u_short port; - - sai.sin_family = AF_INET; - sai.sin_addr.s_addr = htonl (INADDR_ANY); - - for (port = IPPORT_RESERVED - 2; port >= IPPORT_RESERVED/2; port--) - { - int error; - sai.sin_port = htons (port); - result = bind (s, (struct sockaddr *) &sai, sizeof (sai)); - error = GetLastError (); - if (result != SOCKET_ERROR || error != WSAEADDRINUSE) - break; - } - - return result; -} -#endif - static SOCKET bind_and_connect (struct sockaddr_in *server_sai) { @@ -103,41 +76,43 @@ bind_and_connect (struct sockaddr_in *server_sai) client_port >= IPPORT_RESERVED/2; client_port--) { - int result, error; + int result, errcode; client_sai.sin_port = htons (client_port); if ((s = socket (PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) - return INVALID_SOCKET; + error (1, 0, "cannot create socket: %s", + SOCK_STRERROR (SOCK_ERRNO)); result = bind (s, (struct sockaddr *) &client_sai, sizeof (client_sai)); - error = GetLastError (); + errcode = SOCK_ERRNO; if (result == SOCKET_ERROR) { closesocket (s); - if (error == WSAEADDRINUSE) + if (errcode == WSAEADDRINUSE) continue; else - return INVALID_SOCKET; + error (1, 0, "cannot bind to socket: %s", + SOCK_STRERROR (errcode)); } result = connect (s, (struct sockaddr *) server_sai, sizeof (*server_sai)); - error = GetLastError (); + errcode = SOCK_ERRNO; if (result == SOCKET_ERROR) { closesocket (s); - if (error == WSAEADDRINUSE) + if (errcode == WSAEADDRINUSE) continue; else - return INVALID_SOCKET; + error (1, 0, "cannot connect to socket: %s", + SOCK_STRERROR (errcode)); } return s; } - /* We couldn't find a free port. */ - return INVALID_SOCKET; + error (1, 0, "cannot find free port"); } static int @@ -156,17 +131,21 @@ rcmd_authenticate (int fd, char *locuser, char *remuser, char *command) || (send (fd, locuser, strlen (locuser) + 1, 0) == SOCKET_ERROR) || (send (fd, remuser, strlen (remuser) + 1, 0) == SOCKET_ERROR) || (send (fd, command, strlen (command) + 1, 0) == SOCKET_ERROR)) - return -1; + error (1, 0, "cannot send authentication info to rshd: %s", + SOCK_STRERROR (SOCK_ERRNO)); /* They sniff our butt, and send us a '\0' character if they like us. */ { char c; - if (recv (fd, &c, 1, 0) == SOCKET_ERROR - || c != '\0') + if (recv (fd, &c, 1, 0) == SOCKET_ERROR) { - errno = EPERM; - return -1; + error (1, 0, "cannot receive authentication info from rshd: %s", + SOCK_STRERROR (SOCK_ERRNO)); + } + if (c != '\0') + { + error (1, 0, "Permission denied by rshd"); } } @@ -187,27 +166,15 @@ rcmd (const char **ahost, assert (fd2p == 0); if (resolve_address (ahost, &sai) < 0) - return -1; + error (1, 0, "internal error: resolve_address < 0"); sai.sin_port = htons (inport); -#if 0 - if ((s = socket (PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) - return -1; - - if (bind_local_end (s) < 0) - return -1; - - if (connect (s, (struct sockaddr *) &sai, sizeof (sai)) - == SOCKET_ERROR) - return -1; -#else if ((s = bind_and_connect (&sai)) == INVALID_SOCKET) - return -1; -#endif + error (1, 0, "internal error: bind_and_connect < 0"); if (rcmd_authenticate (s, locuser, remuser, cmd) < 0) - return -1; + error (1, 0, "internal error: rcmd_authenticate < 0"); return s; } diff --git a/gnu/usr.bin/cvs/windows-NT/sockerror.c b/gnu/usr.bin/cvs/windows-NT/sockerror.c new file mode 100644 index 00000000000..ebc1a17e9e5 --- /dev/null +++ b/gnu/usr.bin/cvs/windows-NT/sockerror.c @@ -0,0 +1,136 @@ +/* sockerror.c --- convert WinSock error number to string + Vince Del Vecchio <vdelvecc@spd.analog.com> + + This file is part of GNU CVS. + + GNU CVS 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 <stdio.h> +#include <winsock.h> + +struct err_strs { + char **strs; + int first; + int last; +}; + +static char *errs1[] = { + /* EINTR */ "Interrupted system call" +}; + +static char *errs2[] = { + /* EBADF */ "Bad file descriptor" +}; + +static char *errs3[] = { + /* EACCES */ "Permission denied", + /* EFAULT */ "Bad address" +}; + +static char *errs4[] = { + /* EINVAL */ "Invalid argument" +}; + +static char *errs5[] = { + /* EMFILE */ "Too many open files", +}; + +static char *errs6[] = { + /* EWOULDBLOCK */ "Resource temporarily unavailable", + /* EINPROGRESS */ "Operation now in progress", + /* EALREADY */ "Operation already in progress", + /* ENOTSOCK */ "Socket operation on non-socket", + /* EDESTADDRREQ */ "Destination address required", + /* EMSGSIZE */ "Message too long", + /* EPROTOTYPE */ "Protocol wrong type for socket", + /* ENOPROTOOPT */ "Protocol not available", + /* EPROTONOSUPPORT */ "Protocol not supported", + /* ESOCKTNOSUPPORT */ "Socket type not supported", + /* EOPNOTSUPP */ "Operation not supported on socket", + /* EPFNOSUPPORT */ "Protocol family not supported", + /* EAFNOSUPPORT */ "Address family not supported by protocol", + /* EADDRINUSE */ "Address already in use", + /* EADDRNOTAVAIL */ "Can't assign requested address", + /* ENETDOWN */ "Network is down", + /* ENETUNREACH */ "Network is unreachable", + /* ENETRESET */ "Network connection dropped on reset", + /* ECONNABORTED */ "Software caused connection abort", + /* ECONNRESET */ "Connection reset by peer", + /* ENOBUFS */ "No buffer space available", + /* EISCONN */ "Socket is already connected", + /* ENOTCONN */ "Socket is not connected", + /* ESHUTDOWN */ "Can't send after socket shutdown", + /* ETOOMANYREFS */ "Too many references: can't splice", + /* ETIMEDOUT */ "Connection timed out", + /* ECONNREFUSED */ "Connection refused", + /* ELOOP */ "Too many levels of symbolic links", + /* ENAMETOOLONG */ "File name too long", + /* EHOSTDOWN */ "Host is down", + /* EHOSTUNREACH */ "No route to host", + /* ENOTEMPTY */ "Directory not empty", + /* EPROCLIM */ "Too many processes", + /* EUSERS */ "Too many users", + /* EDQUOT */ "Disc quota exceeded", + /* ESTALE */ "Stale NFS file handle", + /* EREMOTE */ "Object is remote" +}; + +static char *errs7[] = { + /* SYSNOTREADY */ "Network subsystem unavailable", + /* VERNOTSUPPORTED */ "Requested WinSock version not supported", + /* NOTINITIALISED */ "WinSock was not initialized" +}; + +#ifdef WSAEDISCON +static char *errs8[] = { + /* EDISCON */ "Graceful shutdown in progress" +}; +#endif + +static char *errs9[] = { + /* HOST_NOT_FOUND */ "Unknown host", + /* TRY_AGAIN */ "Host name lookup failure", + /* NO_RECOVERY */ "Unknown server error", + /* NO_DATA */ "No address associated with name", +}; + +/* Some of these errors are defined in the winsock.h header file I have, + but not in the Winsock 1.1 spec. I include them some of them anyway, + where it is not too hard to avoid referencing the symbolic constant. */ + +static struct err_strs sock_errlist[] = { + { errs1, WSAEINTR, WSAEINTR }, + { errs2, WSAEBADF, WSAEBADF }, + { errs3, WSAEACCES, WSAEFAULT }, + { errs4, WSAEINVAL, WSAEINVAL }, + { errs5, WSAEMFILE, WSAEMFILE }, + { errs6, WSAEWOULDBLOCK, WSAEHOSTUNREACH + 6 }, + { errs7, WSASYSNOTREADY, WSANOTINITIALISED }, +#ifdef WSAEDISCON + { errs8, WSAEDISCON, WSAEDISCON }, +#endif + { errs9, WSAHOST_NOT_FOUND, WSANO_DATA } +}; + +char * +sock_strerror (int errnum) +{ + static char buf[40]; + int i; + + for (i = 0; i < (sizeof sock_errlist / sizeof *sock_errlist); i++) + { + if (errnum >= sock_errlist[i].first && errnum <= sock_errlist[i].last) + return sock_errlist[i].strs[errnum - sock_errlist[i].first]; + } + sprintf(buf, "Unknown socket error: %d", errnum); + return buf; +} diff --git a/gnu/usr.bin/cvs/windows-NT/startserver.c b/gnu/usr.bin/cvs/windows-NT/startserver.c index 3de8cca6a7b..0856d972b20 100644 --- a/gnu/usr.bin/cvs/windows-NT/startserver.c +++ b/gnu/usr.bin/cvs/windows-NT/startserver.c @@ -46,7 +46,8 @@ wnt_start_server (int *tofd, int *fromfd, command, 0); if (read_fd < 0) - error (1, errno, "cannot start server via rcmd"); + error (1, 0, "cannot start server via rcmd: %s", + SOCK_STRERROR (SOCK_ERRNO)); *tofd = read_fd; *fromfd = read_fd; @@ -61,7 +62,9 @@ wnt_shutdown_server (int fd) s = fd; if (shutdown (s, 2) == SOCKET_ERROR) - error (1, 0, "couldn't shutdown server connection"); + error (1, 0, "couldn't shutdown server connection: %s", + SOCK_STRERROR (SOCK_ERRNO)); if (closesocket (s) == SOCKET_ERROR) - error (1, 0, "couldn't close server connection"); + error (1, 0, "couldn't close server connection: %s", + SOCK_STRERROR (SOCK_ERRNO)); } |