diff options
Diffstat (limited to 'gnu')
161 files changed, 26423 insertions, 1344 deletions
diff --git a/gnu/usr.bin/cvs/BUGS b/gnu/usr.bin/cvs/BUGS index fc6af32f227..89a37b69946 100644 --- a/gnu/usr.bin/cvs/BUGS +++ b/gnu/usr.bin/cvs/BUGS @@ -1,15 +1,38 @@ -To report bugs send mail to bug-cvs@prep.ai.mit.edu, or run the "cvsbug" -program and fill out the template: +See the README file for information on how to report bugs (and what +will happen to your bug reports if you do). - $ cvsbug +The following is a list of some of the known bugs. It may or may not +be comprehensive. We would dearly love for people to volunteer to +help us keep it up to date (for starters, if you notice any +inaccuracies, please let bug-cvs know as described in README). There +are some other reported bugs in MINOR-BUGS; the difference, at least +in theory, is that those bugs are less serious. -The "cvsbug" program is installed in the same location as the "cvs" -program. If your installation failed, you may need to run "cvsbug" -directly out of the "src" directory as "src/cvsbug.sh". This is also -the procedure for submitting suggested changes to CVS--note that all -submitted changes may be distributed under the terms of the GNU Public -License, so if you don't like this, don't submit them. +* For platform-specific information (in some cases including known +bugs), see README.VMS, windows-NT/README, or os2/README. There is no +similar file for the unix-like operating systems (not yet, at least). +This file also might contain some platform-specific bugs. + + +* The "&" feature of the modules file does not work correctly with +client/server CVS. The documented behavior (which is implemented by +non-client/server CVS) is the correct one. + + +* The -m option to "cvs add" does not work with client/server CVS. +CVS will accept the option, but it won't actually set the +file's description. + + +* cvs update walks into a user's work directory if there's a directory + of the same name in the repository even if the user's directory + doesn't yet have a CVS admin sub-directory. This can greatly confuse + users who try to add the same directory at nearly the same time. + + +* 'cvs admin' dumped core when files were missing from working directory + (and from the repository)? * `cvs checkout -d nested/dir/path <module>' just doesn't work. The @@ -17,16 +40,41 @@ License, so if you don't like this, don't submit them. however. -* CVS leaves .#mumble files around when a conflict occurs. (Note: - this is intentional and is documented in doc/cvs.texinfo. Of course - whether it is a good idea is a separate question). - - * pcl-cvs doesn't like it when you try to check in a file which isn't up-to-date. The messages produced by the server perhaps don't match what pcl-cvs is looking for. +* From: billr@mpd.tandem.com (Bill Robertson) + Subject: Problem with rtag and the -D option + Date: Fri, 17 Mar 1995 10:53:29 -0600 (CST) + + I have been trying to use the -D option to specify a date for tagging, but + rtag does not recognize the -D option. It is documented to do so and I've + tested the use of -D with cvs update and cvs diff and it works fine there. + +* Defining RELATIVE_REPOS is said to not work with client/server CVS. + +* From: "Charles M. Hannum" <mycroft@ai.mit.edu> + To: info-cvs@prep.ai.mit.edu + Subject: Still one more bug + Date: Sat, 25 Feb 1995 17:01:15 -0500 + + mycroft@duality [1]; cd /usr/src/lib/libc + mycroft@duality [1]; cvs diff -c2 '-D1 day ago' -Dnow + cvs server: Diffing . + cvs server: Diffing DB + cvs [server aborted]: could not chdir to DB: No such file or directory + mycroft@duality [1]; + + `DB' is an old directory, which no longer has files in it, and is + removed automatically when I use the `-P' option to checkout. + + This error doesn't occur when run locally. + + P.S. Is anyone working on fixing these bugs? + + * From: Roland McGrath <roland@gnu.ai.mit.edu> To: Cyclic CVS Hackers <info-cvs@prep.ai.mit.edu> Subject: weird bug @@ -119,125 +167,6 @@ License, so if you don't like this, don't submit them. ls: cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt/cvs-serv28978/csu/cvs-serv28978/ctype/cvs-serv28978/dirent/cvs-serv28978/elf/cvs-serv28978/gnu/cvs-serv28978/gnulib/cvs-serv28978/grp/cvs-serv28978/hurd/cvs-serv28978/hurd/hurd/cvs-serv28978/inet/cvs-serv28978/inet/arpa/cvs-serv28978/inet/netinet[...]/cvs-serv28978/posix/cvs-serv28978/posix/glob/cvs-serv28978/posix/gnu/cvs-serv28978/posix/sys/cvs-serv28978/protocols/cvs-serv28978/pwd/cvs-serv28978/resolv/cvs-serv28978/resolv/arpa/cvs-serv28978/resolv/sys/cvs-serv28978/resource/cvs-serv28978/resource/sys/cvs-serv28978/rpc/cvs-serv28978/setjmp/cvs-serv28978/signal/cvs-serv28978/signal/sys/cvs-serv28978/socket/cvs-serv28978/socket: File name too long cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt/cvs-serv28978/csu/cvs-serv28978/ctype/cvs-serv28978/dirent/cvs-serv28978/elf/cvs-serv28978/gnu/cvs-serv28978/gnulib/cvs-serv28978/grp/cvs-serv28978/hurd/cvs-serv28978/hurd/hurd/cvs-serv28978/inet/cvs-serv28978/inet/arpa/cvs-serv28978/inet/netinet[...]/cvs-serv28978/posix/glob/cvs-serv28978/posix/gnu/cvs-serv28978/posix/sys/cvs-serv28978/protocols/cvs-serv28978/pwd/cvs-serv28978/resolv/cvs-serv28978/resolv/arpa/cvs-serv28978/resolv/sys/cvs-serv28978/resource/cvs-serv28978/resource/sys/cvs-serv28978/rpc/cvs-serv28978/setjmp/cvs-serv28978/signal/cvs-serv28978/signal/sys/cvs-serv28978/socket/cvs-serv28978: - -* From: billr@mpd.tandem.com (Bill Robertson) - Subject: Problem with rtag and the -D option - Date: Fri, 17 Mar 1995 10:53:29 -0600 (CST) - - I have been trying to use the -D option to specify a date for tagging, but - rtag does not recognize the -D option. It is documented to do so and I've - tested the use of -D with cvs update and cvs diff and it works fine there. - - -* We need some version numbers really badly. Are there some - (and Charles Hannum is just not including them in his reports), or do - we simply have no reliable way to distinguish between the various - versions of rCVS people on the list are running? - - Now that I think of it, version numbers present a problem when - people can update their sources anytime and rebuild. I think the - solution is to increment a minor version number *every* time a bug is - fixed, so we can identify uniquely what someone is running when they - submit a report. This implies recording the version increments in the - ChangeLog; that way we can just look to see where a particular version - lies in relation to the flow of changing code. - - Should we be doing same with Guppy? I guess not -- it's only - important when you have people who are updating directly from your - development tree, which is the case with the remote-cvs folks. - - Thoughts? - - -* (Charles Hannum <mycroft@ai.mit.edu>) has these bugs: - - I just tossed remote CVS at a fairly large source tree that I already - had, and noticed a few problems: - - 1) server.c assumes that /usr/tmp is a valid default for the place to - store files uploaded from the client. There are a number of systems - that now use /var/tmp. These should probably be detected by autoconf. - - 2) The server deals rather ungracefully with the tmp directory - becoming full. - - 3) There's some oddness with relative paths in Repository files that - causes the directory prefix to be added twice; e.g. if I have CVSROOT - set to `machine:/this/dir', and I try to update in a directory whose - Repository file says `src/bin', the server looks in - `/this/dir/machine:/this/dir/src/bin'. - -* From: "Charles M. Hannum" <mycroft@ai.mit.edu> - To: jimb@duality.gnu.ai.mit.edu, roland@duality.gnu.ai.mit.edu - Subject: Serious flaw in remote CVS - Date: Wed, 22 Feb 1995 20:54:36 -0500 - - I just found a major flaw in the current implementation. Because the - sockets are not changed to non-blocking mode, write(2)s can hang. In - some cases, this happens on both sides at the same time, with the - socket buffers full in both directions. This causes a deadlock, - because both processes are stuck in I/O wait and thus never drain - their input queues. - - Until this is fixed, I can't use it. I'll look at the problem myself - at some point, but I don't know when. - - - From: "Charles M. Hannum" <mycroft@ai.mit.edu> - To: info-cvs@prep.ai.mit.edu - Cc: jimb@totoro.bio.indiana.edu - Subject: Re: forwarded message from Charles M. Hannum - Date: Wed, 22 Feb 1995 22:07:07 -0500 - - FYI, this happened because the tmp directory on the server became - full. Somehow the server started interpreting the files the client - was sending as commands, and started spewing tons of errors. - Apparently the errors are sent with blocking I/O, or something, and - thus allowed the deadlock to happen. - - -* From: "Charles M. Hannum" <mycroft@ai.mit.edu> - To: info-cvs@prep.ai.mit.edu - Subject: Regarding that relative path problem - Date: Thu, 23 Feb 1995 02:41:51 -0500 - - This is actually more serious. If you have `bar.com:/foo' as your CVS - root directory, then: - - 1) When you check things out, the Repository files will contain - `/foo/...' (i.e. without the machine name), which makes little sense. - - 2) If you instead have a relative path, when the Repository file is - read, `bar.com:/foo' is prepended. This is sent to the server, but - confuses it, because it's not expecting the machine name to be - prepended. - - A slightly klugy fix would be to have the client prepend the machine - name when writing a new Repository file, and strip it off before - sending one to the server. This would be backward-compatible with the - current arrangement. - - -* From: "Charles M. Hannum" <mycroft@ai.mit.edu> - To: info-cvs@prep.ai.mit.edu - Subject: Still one more bug - Date: Sat, 25 Feb 1995 17:01:15 -0500 - - mycroft@duality [1]; cd /usr/src/lib/libc - mycroft@duality [1]; cvs diff -c2 '-D1 day ago' -Dnow - cvs server: Diffing . - cvs server: Diffing DB - cvs [server aborted]: could not chdir to DB: No such file or directory - mycroft@duality [1]; - - `DB' is an old directory, which no longer has files in it, and is - removed automatically when I use the `-P' option to checkout. - - This error doesn't occur when run locally. - - P.S. Is anyone working on fixing these bugs? - - * From: Roland McGrath <roland@gnu.ai.mit.edu> To: Cyclic CVS Hackers <info-cvs@prep.ai.mit.edu> Subject: bizarre failure mode diff --git a/gnu/usr.bin/cvs/ChangeLog b/gnu/usr.bin/cvs/ChangeLog index ad187ad5188..ab94ab490cc 100644 --- a/gnu/usr.bin/cvs/ChangeLog +++ b/gnu/usr.bin/cvs/ChangeLog @@ -1,3 +1,444 @@ +Tue Oct 1 14:32:44 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS, README: Revert changes regarding -D, -g, and A4. They + are for new features which are not appropriate at this stage of + the release process. + +Mon Sep 30 14:51:36 1996 Greg A. Woods <woods@most.weird.com> + + * INSTALL (sun3): 1.8.86+ builds and runs make check. + + * NEWS: describe -D and -g; DIFFBIN and GREPBIN + + * MINOR-BUGS: yet another couple of annoyances... + +Mon Sep 30 08:33:51 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * BUGS: Mention "cvs add -m" client/server bug. + + * NEWS: Document change from A4 to US letter. It may seem minor, + but it affects a *lot* of people. + + * README: Revise discussion of US letter vs. A4 to reflect recent + change to cvs.texinfo. + +Sun Sep 29 16:32:47 1996 Greg A. Woods <woods@most.weird.com> + + * MINOR-BUGS: describe a minor annoyance or two + + * BUGS: describe a couple of new bugs + +Sun Sep 29 14:09:49 1996 Noel Cragg <noel@gargle.rain.org> + + * configure.in: check for shadow password files as well as for + getspnam. Some systems (like Linux) have getspnam in the C + library, but aren't necessarily using shadow passwords. + * configure, config.h.in: Regenerate. + +Fri Sep 27 16:49:53 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (TSUBDIRS): Remove comment about order of + directories mattering. That was only for an old set of hacks, + since gone, which tried to combine several tag files into one + (before emacs could use several tag files at once). + +Wed Sep 25 10:35:06 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Add note about "cvs log -d" date formats changing. See + comment I added to cvs.texinfo for more whining about this situation. + + * BUGS: Remove item about ~/.cvsignore on NT; it is fixed. + +Wed Sep 25 10:22:00 1996 Larry Jones <larry.jones@sdrc.com> + + * configure.in: Add hack for ISC crypt (the version in the posix C + library doesn't work -- why am I not surprised). Add check for + libsec.a for shadow password functions. + + * Makefile.in: Make zlib along with lib in the check targets. + +Wed Sep 25 08:34:01 1996 Jim Blandy <jimb@floss.cyclic.com> + + Fix from Mark A. Solinski <markso@mcs.com>: + * cvsnt.mak: The debug configuration adds the zlib directory to + the include path but it is missing from the release configuration. + Add it to the "ADD CPP" and "CPP_PROJ" lines. + +Tue Sep 24 11:32:20 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * INSTALL: Add VMS entry. Clarify what "tested" means. + + * README: Replace section about what CVS is with the blurb from + cvs.spec (which is also the paragraph we use in the release + announcements). + Change location of pcl-cvs from contrib/pcl-cvs to tools/pcl-cvs. + + * BUGS: Remove item about version numbers; we now have version + numbers. Remove item about server using /usr/tmp; this has been + changed. Remove item about deadlocks between server and client + and file contents being interpreted as commands; I believe this + refers to the case which was fixed by Ian's 7 Aug 96 change to + receive_partial_file. Remove item about server temp directory + becoming full; I'm not sure all bugs related to that have been + fixed, but I think the ones mentioned have been. Remove item + about .# files; this is a documented behavior. Refer to + platform-specific documentation. Add bug with & in modules file + and client/server CVS. Move bug about weird use of long file + names to end; the bug report is so long people won't want to read + past it. Refer to README concerning reporting bugs. Add + introduction. Reword some bug descriptions. Add bug concerning + ~/.cvsignore on NT. + * MINOR-BUGS: Add introduction. Reword some bug descriptions. + Remove item about "premature end of file"--we've improved that + error message as much as we can figure out how. Remove item about + filenames getting truncated (with rcs2log?)--I think this is a fixed + bug although I couldn't quickly find a ChangeLog entry for the fix. + +Tue Sep 17 12:46:37 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * .cvsignore: Add cvs-*.spec. + +Mon Sep 16 17:42:30 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * TODO: In 180, mention issue of network being down. Add item + 182, about inclusiveness of "cvs log -r foo -r bar". + + * HACKING: Also mention arbitrary limits and reentrancy. + User-visible changes should be documented in cvs.texinfo as well + as NEWS. + +Thu Sep 12 16:06:33 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * README.VMS: Put authorship info at end. Add disclaimer. Say + that patch is mandatory not optional. Don't mention gzip; we + don't require it any more. Remove section on filename case; the + bugs described there are fixed. Miscellaneous tweaks and updates. + +Wed Sep 11 11:08:39 1996 Jim Blandy <jimb@totoro.cyclic.com> + + * configure.in (AC_OUTPUT): Don't forget to create vms/Makefile. + +Tue Sep 10 19:55:07 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (DISTFILES): Add build.com and README.VMS. + (SUBDIRS): Add vms. + * build.com: Also recurse into zlib directory. + + * NEWS: Mention Win95. + +Fri Sep 6 11:43:26 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Add AC_ARG_ENABLE for encryption. + * acconfig.h: Add ENCRYPTION. + * configure, config.h.in: Regenerate. + * NEWS: Modify the entry on encryption to mention that you must + configure with --enable-encryption. + * INSTALL: Mention the --with-krb4 and --enable-encryption + configure options. + +Thu Sep 5 11:30:45 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Revise access method item to mention both :ext: and + :server:. + + * README.VMS: Change bug reporting address to bug-cvs. In + discussing filenames, don't mention a hypothetical behavior + involving folding to lowercase (I'm not sure what is meant, and it + doesn't sound right to me) and do mention that things might be + different now (as a result of recent changes to case sensitivity + code). + +Wed Sep 4 1996 Jim Kingdon <kingdon@cyclic.com> + + * cvsnt.mak: Add windows-NT/ChangeLog. + +Wed Sep 4 13:55:11 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (DISTFILES): Add cvs.spec. + +Mon Aug 26 15:30:13 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * TODO: Add item suggesting "cvs message" command. + +Tue Aug 20 12:22:53 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * configure.in (AC_C_INLINE): Removed; see src/ChangeLog. + * config.h.in, configure: Regenerated. + * os2/config.h, windows-NT/config.h: Remove #define of inline. + + * configure.in (AC_C_CHAR_UNSIGNED): Removed; it is not used + anywhere. + * config.h.in, configure: Regenerated. + * os2/config.h, vms/config.h, windows-NT/config.h: Likewise, + remove __CHAR_UNSIGNED__. + +Fri Aug 16 13:37:19 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.spec (%description): Replace description with one that + resembles the release announcements we have been sending out. The + previous one was out of date and not really focused on describing + what CVS does. + (%build): Don't define SERVER_FLOWCONTROL; if we are ready to make + this is the default it should be for all kinds of builds, not just + those via RPM. + +Fri Aug 16 16:09:59 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * cvs.spec: new file. This is a template for a RPM specification + file (which is used by 'make spec'). + + * Makefile.in (installdirs-local): new (empty) target + (all install uninstall installdirs): add installdirs to list of + targets which are done for all subdirs + (spec): new target to create a rpm specification file (which can + be used to create RPM source and binary packages) + (dist): depend on spec (which now also creates .fname) + +Wed Aug 14 13:59:11 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * configure.in (AC_REPLACE_FUNCS): add getspnam for reading shadow + password entries + * configure: regenerated + * config.h.in: regenerated + +Mon Aug 12 14:15:31 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (config.status): When running config.status + --recheck, preserve the value of CFLAGS. + +Fri Aug 9 14:11:31 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * TESTS: Also mention dejagnu advantages. + +Thu Aug 8 16:00:55 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * TESTS (ABOUT STDOUT AND STDERR): New section. + (ABOUT TEST FRAMEWORKS): Add sed/cmp/diff (a la C News) as an option. + + * NEWS: Change entry regarding "cvs log" not invoking "rlog" so + that it emphasizes user-visible behaviors. + +Tue Aug 6 17:01:23 1996 Ian Lance Taylor <ian@cygnus.com> + + * TODO: Remove item #167 (cvs log doesn't understand symbolic + branch names). It works now. + + * NEWS: Mention that "cvs log" no longer invokes "rlog". + +Wed Jul 31 16:06:03 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * HACKING: Mention rule about _ vs - in file names. + +Wed Jul 24 19:10:38 1996 Ian Lance Taylor <ian@cygnus.com> + + * NEWS: Mention that Kerberos encryption is now supported. + +Mon Jul 22 23:48:39 1996 Ian Lance Taylor <ian@cygnus.com> + + * NEWS: Mention that the commit message has changed slightly when + committing changes on a branch. + +Fri Jul 19 16:10:04 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * TESTS: Say that GNU expr is part of sh-utils. + +Thu Jul 18 18:16:33 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Mention -k wrappers option. + + * TESTS: In list of what we would like in a test framework, only + mention portable once, and other wording cleanups. + +Mon Jul 15 1996 Jim Kingdon <kingdon@cyclic.com> + + * cvsnt.mak: Add src/ChangeLog (lets us edit it from within + the integrated development environment). + +Sun Jul 14 1996 Jim Kingdon <kingdon@cyclic.com> + + * cvsnt.mak: Add src/zlib.c. Add zlib group containing the .c + files in zlib. Add /I "zlib" compiler options. + +Sun Jul 14 10:26:21 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Expand zlib item to emphasize user-visible (and + CVS-installer-visible) consequences. + +Sat Jul 13 21:11:50 1996 Ian Lance Taylor <ian@cygnus.com> + + * NEWS: Mention that -z now uses zlib. + +Fri Jul 12 18:54:21 1996 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (USOURCE_SUBDIRS): Add zlib. + * configure.in (AC_OUTPUT): Add zlib/Makefile. + * configure: Regenerate. + + * zlib/*: Import zlib 1.0.3. Remove zlib/Makefile. Modify + zlib/Makefile.in for use with CVS. + +Fri Jul 12 1996 Jim Kingdon <kingdon@cyclic.com> + + * cvsnt.mak: Add src/buffer.c + +Wed Jul 10 18:44:58 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Say that rlog is deprecated. + +Tue Jul 9 14:37:41 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * PROJECTS: Refer to comment in rcscmds.c regarding RCS library. + + * HACKING: Expand comments on portability. + +Sun Jul 7 23:21:02 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * configure.in (AC_REPLACE_FUNCS): Remove memmove; it was used by + a very old version of the CVS server for nefarious purposes and it + has been long gone. + * configure: Regenerated. + +Tue Jul 2 22:36:31 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * TESTS: Add discussion of test frameworks. + +Fri Jun 28 20:27:56 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Describe "cvs diff -q" removal and new diff options. + +Thu Jun 13 17:29:30 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * TODO: Remove item #67 about having cvs import create CVS + directories; I don't think it is wise to have cvs import mess with + the directory it is working in at all. Remove item #69 about + having import edit modules--in many cases there is no need for an + entry in modules. Remove item #76 about running on top of SCCS; + we are clearly not evolving in that direction. Remove item #91 + about documenting how to import sources from SCCS or RCS; this is + now documented in cvs.texinfo. Remove item #129 about "U CFTS/"; + without more information it is impossible to know what behavior is + being discussed. Remove item #157 concerning module names in cvs + release; cvs release takes a directory name, not a module name. + Remove item #159 about checking access times; this is as likely to + be an annoyance as a help, and people who are into that can just + look at the result from "cvs update" (directly or with a script). + Remove item #164 concerning variables in *info files; it is done. + Remove item #35 (it just says "cvs admin" is cheesy, which isn't + specific enough to be useful). Rewrite #39 to be specific about + what would be nice in having branches track each other. Remove + item #46--I'm not sure what it means and if it means that one + should check in with "cci" or some such instead of "cvs ci" then + that is an installation hassle and a minimal convenience. Add + item #180. + + * config.h.in: Regenerated. + +Thu Jun 13 1996 Ian Lance Taylor <ian@cygnus.com> + and Jim Kingdon <kingdon@cyclic.com> + + * configure.in: Put -L${krb_libdir} in LDFLAGS temporarily when + looking for -ldes. + * configure: Regenerated. + +Mon Jun 10 13:13:35 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Mention NT local. + +Fri Jun 7 18:02:36 1996 Ian Lance Taylor <ian@cygnus.com> + and Jim Kingdon <kingdon@cyclic.com> + + * NEWS: Mention new annotate options. + +Thu Jun 6 14:08:31 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * lib/savecwd.c: Revert CVS_* patch. The include files where + CVS_* is defined were not included, and the code in question was + inside HAVE_FCHDIR which isn't defined on the Mac anyway. + + * src/filesubr.c: Revert CVS_* patch in this one file. The mac + port should have its own copy of filesubr.c instead. + +Wed Jun 05 10:03:10 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * lib/{system.h,savecwd.c}, src/{add.c,checkout.c,client.c, + commit.c,create_adm.c,diff.c,edit.c,entries.c,fileattr.c, + filesubr.c,find_names.c,history.c,ignore.c,import.c,lock.c, + login.c,logmsg.c,mkmodules.c,modules.c,myndbm.c,no_diff.c, + parseinfo.c,patch.c,rcs.c,recurse.c,release.c,remove.c,root.c, + rtag.c,server.c,tag.c,update.c,vers_ts.c,wrapper.c}: + Under non-UNIX operating systems (MS-DOS, WinNT, MacOS), many + filesystem calls take only one argument; permission is handled + very differently on those systems than in UNIX. On MacOS, + the naming scheme for volumes and subdirectories is quite + different. This patch leaves hooks in the form of CVS_ACCESS, + CVS_CHDIR, CVS_CREAT, CVS_FOPEN, CVS_MKDIR, CVS_OPEN, CVS_OPENDIR, + CVS_RENAME, CVS_RMDIR, CVS_STAT, and CVS_UNLINK to accomodate + these differences. + +Thu Jun 6 11:11:53 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Say "changes from 1.7 to 1.8" not "changes since 1.7". + +Wed Jun 5 1996 Jim Kingdon <kingdon@cyclic.com> + + * cvsnt.mak: Visual C++ 2.1 seems to want to reformat the line + breaks. No substantive changes, I think. + +Thu May 30 15:35:57 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (DISTFILES): add TESTS. + +Tue May 28 13:10:42 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * src/server.c: Add comment regarding out-of-order bug. + * TESTS: Explain out-of-order bug. + + * INSTALL: Remove $CVSId$. More strongly encourage people to skip + the tests if they don't have the time to look at the results. + Move most of the discussion of tests to new file TESTS, and add + some information on interpreting check.log output. + * README: In brief summary of install, don't spell out details of + "make check" or "cvs init" steps. + +Sun May 26 17:59:46 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Change "up-to-date" to "not locally modified"; the file + need not match the head revision it only need match some revision. + +Sun May 26 17:02:49 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * NEWS: document new option "-c" for tag + +Thu May 23 21:49:33 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * INSTALL: Remove footnote 10. The only kind of change suitable + for listing here is fairly easy portability stuff. + +Fri May 17 11:49:11 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Refer to cvs.texinfo and say "filesystem" not "fs". + +Thu May 16 17:13:56 1996 Noel Cragg <noel@gargle.rain.org> + + * NEWS: Mention all access methods. + +Wed May 15 23:38:15 1996 Noel Cragg <noel@gargle.rain.org> + + * NEWS: add info about access methods and document behavior change + for "cvs login." + +Mon May 13 10:37:09 1996 Greg A. Woods <woods@most.weird.com> + + * INSTALL: updated for Sun-3 SunOS 4.1.1_U1 (1.8.2) + +Fri May 10 09:39:49 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Document that -d overrides CVS/Root. + +Mon May 6 06:00:10 1996 Benjamin J. Lee <benjamin@cyclic.com> + + * Version 1.8.1 + Sun May 5 17:38:21 1996 Benjamin J. Lee <benjamin@cyclic.com> Integrated changes submitted by Ian Taylor <ian@cygnus.com> @@ -46,6 +487,15 @@ Wed May 1 15:38:56 1996 Jim Kingdon <kingdon@harvey.cyclic.com> * NEWS: Remove item about reserving all-uppercase tag names. +Wed May 01 00:18:01 1996 noel <noel@BOAT_ANCHOR> + + * cvsnt.mak: remove all of those unnecessary libraries! We only + need advapi32.lib and wsock32.lib. + +Wed Apr 24 16:48:35 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * NEWS: Document that -d overrides CVS/Root. + Fri Apr 19 11:22:35 1996 Benjamin J. Lee <benjamin@cyclic.com> * Version 1.7.86 diff --git a/gnu/usr.bin/cvs/HACKING b/gnu/usr.bin/cvs/HACKING index ac4cdd194be..ce65cffdfbc 100644 --- a/gnu/usr.bin/cvs/HACKING +++ b/gnu/usr.bin/cvs/HACKING @@ -43,11 +43,17 @@ the person checking in such a patch should reindent it. * Portability -If it is in ANSI C and it is in SunOS4 (using /bin/cc), generally it -is OK to use it without ifdefs (for example, assert() and void * as -long as you add more casts to and from void * than ANSI requires. But -not function prototypes). Such constructs are generally portable -enough, including to NT, OS/2, VMS, etc. +The general rule for portability is that it is only worth including +portability cruft for systems on which people are actually testing and +using new CVS releases. Without testing, CVS will fail to be portable +for any number of unanticipated reasons. + +The current consequence of that general rule seems to be that if it +is in ANSI C and it is in SunOS4 (using /bin/cc), generally it is OK +to use it without ifdefs (for example, assert() and void * as long as +you add more casts to and from void * than ANSI requires. But not +function prototypes). Such constructs are generally portable enough, +including to NT, OS/2, VMS, etc. * Run-time behaviors @@ -58,6 +64,22 @@ but we want to fix that code. Of course, bad input data, a corrupt repository, bad options, etc., should always print a real error message instead. +We realize that CVS contains many arbitrary limits (such as PATH_MAX). +Do not do this in new code; we are trying to *fix* those arbitrary +limits. In particular, it should be possible to pass very long +arguments (e.g. from a WWW cgi script) to CVS without having it +overrun any buffers (which might create a security hole in the WWW +example). + +Although this is a long-term goal, it also would be nice to move CVS +in the direction of reentrancy. This reduces the size of the data +segment and will allow a multi-threaded server if that is desirable. +It is also useful to write the code so that it can be easily be made +reentrant later. For example, if you need to pass data from a +Parse_Info caller to its callproc, you need a static variable. But +use a single pointer so that when Parse_Info is fixed to pass along a +void * argument, then the code can easily use that argument. + * Coding standards in general Generally speaking the GNU coding standards are mostly used by CVS @@ -65,6 +87,10 @@ Generally speaking the GNU coding standards are mostly used by CVS and perhaps an exception or two we haven't mentioned). This is the file standards.text at the GNU FTP sites. +Filenames for .c and .h files may contain _ but should not contain - +(the latter causes Visual C++ 2.1 to create makefiles which Visual C++ +4.0 cannot use). + * Submitting patches Please include a ChangeLog entry (see the GNU coding standards for @@ -74,7 +100,7 @@ the code are appropriate for this, but not always)--patches should not be checked in unless there is some reason for them, and the description may be helpful if there is a better way to solve the problem. In addition to the ChangeLog entry, there should be a change -to the NEWS file in the case of a new feature. +to the NEWS file and cvs.texinfo in the case of a user-visible change. If you solve several unrelated problems, submit a separate patch for each one. Patches should be tested before submission. Use diff --git a/gnu/usr.bin/cvs/INSTALL b/gnu/usr.bin/cvs/INSTALL index 4907134c6c5..1df53ecd04e 100644 --- a/gnu/usr.bin/cvs/INSTALL +++ b/gnu/usr.bin/cvs/INSTALL @@ -1,45 +1,48 @@ -#ident "$CVSid$" - First, read the README file. If you're still happy... CVS has been tested on the following platforms. The most recent version of CVS reported to have been tested is indicated, but more recent versions of CVS probably will work too. Please send updates to this list to bug-cvs@prep.ai.mit.edu (doing so in the form of a diff -to this file is encouraged). +to this file is encouraged). "tested" means, at a minimum, that CVS +compiles and appears to work on simple (manual) testing. In many +cases it also means "make check" and/or "make remotecheck" passes, but +we don't try to list the platforms for which that is true. Alpha: DEC Alpha running OSF/1 version 1.3 using cc (about 1.4A2) - DEC Alpha running OSF/1 version 2.0 (1.4.90) + DEC Alpha running OSF/1 version 2.0 (1.8) DEC Alpha running OSF/1 version 2.1 (about 1.4A2) DEC Alpha running OSF/1 version 3.0 (1.5.95) (footnote 7) DEC Alpha running OSF/1 version 3.2 (1.7+obvious patch) + DEC Alpha running VMS 6.2 (1.8.85 client-only) HPPA: HP 9000/710 running HP-UX 8.07A using gcc (about 1.4A2) - HP 9000/715 running HP-UX 9.01 (1.6) + HPPA running HP-UX 9 (1.8) HPPA running HP-UX 10.01 (1.7) HPPA 1.1 running HP-UX A.09.03 (1.5.95) (footnote 8) HPPA 1.1 running HP-UX A.09.04 (1.7.1) - NextSTEP 3.3 (1.6.86) + HPPA 9000/735 running HP-UX A.09.05 (1.8.87) + NextSTEP 3.3 (1.7) i386 family: Solaris 2.4 using gcc (about 1.4A2) UnixWare v1.1.1 using gcc (about 1.4A2) - ISC 4.0.1 (1.5.94) - Linux (kernel 1.2.x) (1.7.1) + Unixware 2.1 (1.8.86) + ISC 4.0.1 (1.8.87) + Linux (kernel 1.2.x) (1.8.86) BSDI 2.0 (1.4.93) (footnote 5) FreeBSD 2.0.5, i486, gcc (1.5.95) - NextSTEP 3.3 (1.6.86) - NeXTSTEP 3.3 (1.7), (footnote 10) - SCO Unix 3.2.4.2 (1.4.93) (footnote 4) - SCO OpenServer 5.0.0, "CC='cc -b elf' configure" + NextSTEP 3.3 (1.7) + SCO Unix 3.2.4.2, gcc 2.7.2 (1.8.87) (footnote 4) + SCO OpenServer 5 (1.8.86) Lynx 2.3.0 080695 (1.6.86) (footnote 9) - Windows NT 3.51 (1.7.87 client-only) + Windows NT 3.51 (1.8.86 client; 1.8.3 local) + Windows 95 (1.8.86 client and local) QNX 4 (1.7 + obvious patches) - OS/2 Version 3 using IBM C/C++ Tools 2.01 (1.7.86 with patches) + OS/2 Version 3 using IBM C/C++ Tools 2.01 (1.8.86 + patches) m68k: - Sun 3 running SunOS 4.1.1_U1 w/ bundled K&R /usr/5bin/cc (1.6) - NextSTEP 3.3 (1.6.86) - NeXTSTEP 3.3 (1.7), (footnote 10) + Sun 3 running SunOS 4.1.1_U1 w/ bundled K&R /usr/5bin/cc (1.8.86+) + NextSTEP 3.3 (1.7) Lynx 2.3.0 062695 (1.6.86) (footnote 9) m88k: Data General AViiON running dgux 5.4R2.10 (1.5) @@ -47,23 +50,23 @@ m88k: Harris Nighthawk 5800 running CX/UX 7.1 (1.5) (footnote 6) MIPS: DECstation running Ultrix 4.2a (1.4.90) - DECstation running Ultrix 4.3 (1.6.86) + DECstation running Ultrix 4.3 (1.8.85) SGI running Irix 4.0.5H using gcc and cc (about 1.4A2) (footnote 2) - SGI running Irix 5.3 (1.7) + SGI running Irix 5.3 using gcc 2.7.2 (1.8.87) SGI running Irix-6 (about 1.4.90) (footnote 3) Siemens-Nixdorf RM600 running SINIX-Y (1.6) PowerPC or RS/6000: IBM RS/6000 running AIX 3.1 using gcc and cc (1.6.86) - IBM RS/6000 running AIX 3.2.5 (1.7.87) + IBM RS/6000 running AIX 3.2.5 (1.8) IBM RS/6000 running AIX 4.1 using gcc and cc (about 1.4A2) (footnote 1) Lynx 2.3.1 120495 (1.6.86) (footnote 9) SPARC: - Sun SPARC running SunOS 4.1.x (1.6.86) + Sun SPARC running SunOS 4.1.x (1.8.87) Sun SPARCstation 10 running Solaris 2.3 using gcc and cc (about 1.4A2) Sun SPARCstation running Solaris 2.4 using gcc and cc (about 1.5.91) - Sun SPARC running Solaris 2.5 (2.5 beta?) (1.6.4) - NextSTEP 3.3 (1.6.86) - NeXTSTEP 3.3 (1.7), (footnote 10) + Sun SPARC running Solaris 2.5 (1.8.87) + NextSTEP 3.3 (1.7) + Sun SparcClassing running Linux 2.0.17, gcc 2.7.2 (1.8.87) (footnote 1) AIX 4.1 systems fail to run "configure" due to bugs in their @@ -108,12 +111,6 @@ SPARC: So after running configure I had to undef HAVE_DIRENT_H and define HAVE_SYS_DIR_H. -(footnote 10) Ralf E. Stranzenbach <ralf@reswi.ruhr.de> - I've made some modifications to "filesubr.c" to deal with NFS - mounted directories (and those funny .nfs* files). This patch - should be used whenever the programmers "sandbox" is located on - a NFS mounted device --- at least on NeXTSTEP. - ------------------------------------------------------------------------------- Installation under Unix: @@ -152,6 +149,16 @@ Installation under Unix: If you are using gcc and are planning to modify CVS, you may want to configure with -Wall; see the file HACKING for details. + If you have Kerberos 4 installed, you can specify the location of + the header files and libraries using the --with-krb4=DIR option. + DIR should be a directory with subdirectories include and lib + holding the Kerberos 4 header files and libraries, respectively. + The default value is /usr/kerberos. + + If you want to enable support for encryption over Kerberos, use + the --enable-encryption option. This option is disabled by + default. + Try './configure --help' for further information on its usage. NOTE ON CVS's USE OF NDBM: @@ -209,27 +216,14 @@ Installation under Unix: 3a) Run the regression tests (optional). You may also wish to validate the correctness of the new binary by - running the regression tests: - - $ make check - - Note that if your /bin/sh doesn't support shell functions, you'll - have to try something like this, where "/bin/sh5" is replaced by the - pathname of a shell which handles normal shell functions: - - $ make SHELL=/bin/sh5 check - - WARNING: This test can take quite a while to run, esp. if your - disks are slow or over-loaded. - - If you receive any un-expected output from the regression tests, - it may indicate a bug in CVS (or might just indicate a problem - running the tests). If you choose to submit a bug report, - be aware that, as with all bug reports, you may or may not get a - response, and your odds might be better if you include enough information - to reproduce the bug, an analysis of what is going wrong (if you have - the time and ability to provide one), etc. The check.log file is the - first place to look. + running the regression tests. If they succeed, that is nice to + know. However, if they fail, it doesn't tell you much. Often it + will just be a problem with running the tests on your machine, + rather than a problem with CVS. Unless you will have the time to + determine which of the two it is in case of failure, you might + want to save yourself the time and just not run the tests. + + If you want to run the tests, see the file TESTS for more information. 4) Install the binaries/documentation: diff --git a/gnu/usr.bin/cvs/MINOR-BUGS b/gnu/usr.bin/cvs/MINOR-BUGS index 7b857193f86..ba6fb182111 100644 --- a/gnu/usr.bin/cvs/MINOR-BUGS +++ b/gnu/usr.bin/cvs/MINOR-BUGS @@ -1,26 +1,37 @@ -Low-priority bugs go here. We don't have many yet -- everything is -high-priority at the moment. :-) - - -* From: Jeff Johnson <jbj@brewster.JBJ.ORG> - To: cyclic-cvs@cyclic.com - Subject: Named_Root assumes . on server - Date: Wed, 17 May 1995 11:04:53 -0400 (EDT) - - Problem: - On server, Name_Root() attempts (aggressively) to set CVSADM_Root. - If ~/CVS/Root exists (wrto rsh login), then CVSADM_Root will be - initialized from that file. The sanity check between the root - repository and the invocation will fail if the two values are not - coincidentally the same. - - Workaround: - There's a zillion ways to fix this bugture/featurelet. My current - workaround is to remove ~/CVS/Root on the server. I shall attempt - a better fix as soon as I can determine what appears politically - correct. IMHO, the CVS/Root stuff (and getenv("CVSROOT") also) is - a bit fragile and tedious in an rcmd() driven CCVS environment. - +Low-priority bugs go here. Actually, most every documented bug is +"low-priority"--in the sense that if it is documented it means noone +has gotten around to fixing it. + + +* "cvs update -ko -p -r REV file" doesn't seem to pay attention to the + '-ko', at least in client/server mode. A simple work around is to + temporarily change the db file with "cvs admin -ko file", then switch + it back to the original modes after the checkout (probably '-kkv'). + +* "cvs status" has a difference in its output between local and + client/server mode. Namely there's a tab character followed by a + ctime(3)-style date string at the end of the "Working revision:" + field. + +* commands which don't work in a local working directory should probably + ignore any CVS/Root values and revert to using CVSROOT alone. The + current use of CVS/Root can be very confusing if you forget you're in + a working directory for a remote module -- something that's very easy + to do since CVS hides the client operation very well, esp. for + commands which fail for this reason. The only clue might be the word + "server" in a message such as this: + cvs server: cannot find module `patch' - ignored + +* cvs init may gave a strange error at times: + ttyp4:<woods@clapton> $ cvs -d /local/src-CVS init + cvs [init aborted]: cannot open CVS/Root: No such file or directory + but it seemed to work just the same.... Note that at the time CVSROOT + was set to point to a CVS server using the ":server:" option. + +* If a ~/CVS/Root file exists on the server and you are using rsh to +connect to the server, CVS may loose its mind (this was reported in +May 1995 and I suspect the symptoms have changed, but I have no +particular reason to think the bug is fixed -kingdon, Sep 96). * (Jeff Johnson <jbj@jbj.org>) I tried a "cvs status -v" and received the following: @@ -34,18 +45,8 @@ high-priority at the moment. :-) ... I claim that CVS dirs should be ignored. - - -* I sometimes get this message: - - Could not look up address for your host. Permission denied. - cvs [update aborted]: premature end of file from server - - The client's response should be cleaned up. - -* In the gb-grep module, update-ChangeLog (and therefore, I assume, - rcs2log) truncates file names --- I get entries for things called - ring/lenstring.h instead of lenstring/lenstring.h. + (I don't *think* this always happens; is "-I !" getting picked up somewhere + something like that? -kingdon, Sep 96) * On remote checkout, files don't have the right time/date stamps in the CVS/Entries files. Doesn't look like the C/S protocol has any diff --git a/gnu/usr.bin/cvs/NEWS b/gnu/usr.bin/cvs/NEWS index 81d82acf4dc..4e3bf64977b 100644 --- a/gnu/usr.bin/cvs/NEWS +++ b/gnu/usr.bin/cvs/NEWS @@ -1,4 +1,81 @@ -Changes since 1.7: +Changes since 1.8: + +* Windows NT client should now work on Windows 95 as well. + +* New option "--help-synonyms" prints a list of all recognized command +synonyms. + +* The "log" command is now implemented internally rather than via the +RCS "rlog" program. The main user-visible consequence is that +symbolic branch names now work (for example "cvs log -rbranch1"). +Also, the date formats accepted by -d have changed. They previously +had been a bewildering variety of poorly-documented date formats. Now +they are the same as the date formats accepted by the -D options to +the other CVS commands, which is also a (different) bewildering +variety of poorly-documented date formats, but at least we are +consistently bewildering :-). + +* Encryption is now supported over a Kerberos client/server +connection. The new "-x" global option requests it. You must +configure with the --enable-encryption option in order to enable +encryption. + +* The format of the CVS commit message has changed slightly when +committing changes on a branch. The tag on which the commit is +ocurring is now reported correctly in all cases. + +* New flag -k in wrappers allows you to specify the keyword expansion +mode for added files based on their name. For example, you can +specify that files whose name matches *.exe are binary by default. +See the Wrappers section of cvs.texinfo for more details. + +* Remote CVS with the "-z" option now uses the zlib library (included +with CVS) to compress all communication between the client and the +server, rather than invoking gzip on each file separately. This means +that compression is better and there is no need for an external gzip +program (except to interoperate with older version of CVS). + +* The "cvs rlog" command is deprecated and running it will print a +warning; use the synonymous "cvs log" command instead. It is +confusing for rlog to mean the same as log because some other CVS +commands are in pairs consisting of a plain command which operates on +a working directory and an "r" command which does not (diff/rdiff; +tag/rtag). + +* "cvs diff" has a bunch of new options, mostly long options. Most of +these work only if rcsdiff and diff support them, and are named the +same as the corresponding options to diff. + +* The -q and -Q command options to "cvs diff" were removed (use the +global options instead). This brings "cvs diff" into line with the +rest of the CVS commands. + +* The "annotate" command can now be used to annotate a revision other +than the head revision on the trunk (see the -r, -D, and -f options in +the annotate node of cvs.texinfo for details). + +* The "tag" command has a new option "-c" which checks that all files + are not locally modified before tagging. + +* The -d command line option now overrides the cvsroot setting stored +in the CVS/Root file in each working directory, and specifying -d will +cause CVS/Root to be updated. + +* Local (non-client/server) CVS now runs on Windows NT. See +windows-NT/README for details. + +* The CVSROOT variable specification has changed to support more +access methods. In addition to "pserver," "server" (internal rsh +client), "ext" (external rsh client), "kserver" (kerberos), and +"local" (local filesystem access) can now be specified. For more +details on each method, see cvs.texinfo (there is an index entry for +:local: and each of the other access methods). + +* The "login" command no longer prompts the user for username and +hostname, since one will have to provide that information via the `-d' +flag or by setting CVSROOT. + +Changes from 1.7 to 1.8: * New "cvs annotate" command to display the last modification for each line of a file, with the revision number, user checking in the diff --git a/gnu/usr.bin/cvs/PROJECTS b/gnu/usr.bin/cvs/PROJECTS index de765760631..4e20f8b883a 100644 --- a/gnu/usr.bin/cvs/PROJECTS +++ b/gnu/usr.bin/cvs/PROJECTS @@ -51,9 +51,10 @@ are actually more appropriate for this list. CVS parses RCS files in order to determine if work needs to be done, and then RCS parses the files again when it is performing the work. This would be much faster if CVS could do whatever is necessary - by itself. + by itself. (see comment at start of rcscmds.c for a few notes on this). 1. Improved testsuite/sanity check script * Need to use a code coverage tool to determine how much the sanity script tests, and fill in the holes. + diff --git a/gnu/usr.bin/cvs/README b/gnu/usr.bin/cvs/README index 5c4c9b6436f..fb8b5f81311 100644 --- a/gnu/usr.bin/cvs/README +++ b/gnu/usr.bin/cvs/README @@ -61,22 +61,17 @@ Thanks for your support! ------------------------------------------------------------------------------- -CVS is a freely available collection of programs that provide for software -release and revision control functions in a UNIX environment. It is -designed to work on top of the RCS distribution, V4 and later. CVS does -understand how to parse older RCS formats, but cannot do any of the fancier -features (like vendor branch support) without RCS branch support. - -Short blurb from the manual page (larger blurb is included there): - cvs is a front end to the rcs(1) revision control system - which extends the notion of revision control from a collec- - tion of files in a single directory to a hierarchical col- - lection of directories consisting of revision controlled - files. These directories and files can be combined together - to form a software release. cvs provides the functions - necessary to manage these software releases and to control - the concurrent editing of source files among multiple - software developers. +What Is CVS? + +CVS is a version control system, which allows you to keep old versions +of files (usually source code), keep a log of who, when, and why +changes occurred, etc., like RCS or SCCS. It handles multiple +developers, multiple directories, triggers to enable/log/control +various operations, and can work over a wide area network. The +following tasks are not included; they can be done in conjunction with +CVS but will tend to require some script-writing and software other +than CVS: bug-tracking, build management (that is, make and make-like +tools), and automated testing. And a whole lot more. See the doc/cvs.texinfo file for more information. @@ -112,9 +107,9 @@ Please read the INSTALL file for installation instructions. Brief summary: $ ./configure $ make - $ make check # optional, long-running, step + (run the regression tests if desired) $ make install - $ cvsinit + (create a repository if you don't already have one) The documentation is in the doc subdirectory. cvs.texinfo is the main manual; cvs.info* and cvs.ps are the info and postscript versions, @@ -219,4 +214,4 @@ apologize. Just write to me and let me know! Many contributors have added code to the "contrib" directory. See the README file there for a list of what is available. There is also a -contributed GNU Emacs CVS-mode in contrib/pcl-cvs. +contributed GNU Emacs CVS-mode in tools/pcl-cvs. diff --git a/gnu/usr.bin/cvs/README.VMS b/gnu/usr.bin/cvs/README.VMS new file mode 100644 index 00000000000..d3eaa3bd9af --- /dev/null +++ b/gnu/usr.bin/cvs/README.VMS @@ -0,0 +1,185 @@ + CVS port to VMS + +DISCLAIMER: This port must be considered experimental. Although +previous versions have been in use at one large site since about +October, 1995, and the port is believed to be quite usable, various +VMS-specific quirks are known and the port cannot be considered as +mature as the ports to, say, Windows NT or unix. As always, future +progress of this port will depend on volunteer and customer interest. + +This port is of the CVS client only. Or in other words, the port +implements the full set of CVS commands, but cannot access +repositories located on the local machine. The repository must live +on another machine (a Unix box) which runs a complete port of CVS. + +Most (all?) work to date has been done on OpenVMS/AXP 6.2. Other VMS +variants might work too. + +You will also need GNU patch installed on your system. Here's a list +of ftp servers which have VMS GNU resources, taken from + + ftp://prep.ai.mit.edu/pub/gnu/vms.README + + mvb.saic.com + wuarchive.wustl.edu + ftp.wku.edu + ftp.spc.edu + ftp.stacken.kth.se + +Please send bug reports to bug-cvs@prep.ai.mit.edu. + +As of CVS 1.5.something, this port passed most of the tests in +[.src]sanity.sh. I say "most" because some tests to not apply to the +CVS client. The tests were run by hand because the VMS POSIX shell +was incapable of running the script. The tests that sanity.sh +provides are not conclusive but at least provides some assurance that +the client is usable. + +To compile, you will need DEC C (CC), DEC UCX, and of course DCL +installed on your machine. Just type "@build" in the top level +directory. This will build the sources in each subdirectory, and link +the executable [.src]cvs.exe + +Copy the executable to an appropriate directory, and define the symbol "CVS" +in a .COM file which everyone running CVS will need to run. Here's an example +of what needs to be done. + +$ CVS :== $YOUR_DEVICE:[YOUR.DIRECTORY.CVS]CVS.EXE + +Accessing a remote repository can happen in several ways. + +0. pserver +1. Direct TCP using a listener process running on the CVS server. + (unprivileged) +2. rsh - privileged (default) +3. rsh - unprivileged (on VMS side) + +Here's how to do each of the above: + +------------------------------------------------------------------------------- +0. pserver. This is the preferred way. It works just as it is +documented in the CVS manual (see the README file in the CVS +distribution for more information on the manual). + +1. Using direct TCP to communicate with a CVS server. This method is +broken in the current version of CVS; the following text is included +for historical information but will be removed once we have verified +that the so-called "direct TCP" is not worth resurrecting. + +Compile the file contrib/listener.c on the machine which will be the CVS +server. For each developer using the CVS client, choose a unique TCP port +number. This listener program is run on the server after defining a pair of +environment variables, and acts as a proxy for the VMS client, which is +authenticated only by reverse address resolution of hostname. + +Commits to the repository on a particular port will seen by the repository +as being from the same user. + +On the VMS side, you will need to define the logical CVS_CLIENT_PORT. Here's +an example: + +$ DEFINE CVS_CLIENT_PORT 3050 + +This will direct CVS to expect a direct connection to the CVS server on +TCP port 3050 on whatever host is defined as the respository (whether through +CVSROOT or the "-d" command option. + +The repository must have a full (client/server) CVS installed. Choose a +TCP port number (say 3050) [with coordination of your network administrator] +for YOUR CVS transactions. Each user of CVS under this arrangement will +require a separate port. Again, commits to the same port from the same +host are all attributed to the user running the listener. Invoke listener +as follows (asuming csh syntax) + +% setenv SERVER_PORT 3050 +% setenv SERVER_ALLOW my.vms.host.com +% listener /my_cvs_path/cvs server & + +This will set up the CVS server to listen for connections on port 3050 +(instead of running through rsh, inetd, etc.). It will immediately +terminate the connection if the IP address of the connection does not +resolve to "my.vms.host.com". This at least gives some measure of the +host control access afforded by rsh. If the connection is not +terminated, then the command "/my_cvs_path/cvs server" is invoked and +it's stdin/stdout is redirected through the port. Listener is used as +a "poor man's (unprivileged) inetd". + +------------------------------------------------------------------------------- +2. Using CVS internal rsh support (privileged) + +VMS's RSH is unusable for CVS's purposes (that is, the one in UCX. +Don't know about Multinet). However, there is code within CVS to +emulate RSH for purposes of contacting a CVS server "in the usual way" +via rshd. Unfortunately, this requires the VMS CVS client to be +installed with OPER privilege, by your system administrator. + +RSH uses privileged ports and trusted software/hosts to determine +which user on the client side is trying to connect. Part of this +security is due to the fact that on VMS or UNIX, a non privileged +process is not permitted to bind a socket to a privileged port. + +If rshd receives a connection on a non-privileged port, the connection is +immediately aborted. Only connections arriving from a privileged port will +be authenticated and served. The CVS client will therefore need privileges +under VMS to produce such a connection. + +*** Please note that no careful examination has been done of the security + implications of installing CVS with the OPER privilege. If some hole + exists, then by doing so, you will enable users who are already on + your system to gain unauthorized privileges *** + +------------------------------------------------------------------------------- +3. Using CVS internal rsh support (non-privileged) + +There is a workaround, but this is one case where I think the cure is worse +than the disease. If you patch an rshd to not care that the RSH originating +port is "non-privileged", the CVS VMS client will allow you to define the +logical CVS_RCMD_PORT to the port number where this patched rshd will be +listening. I leave the talk of patching rshd to the gentle reader and his/her +friendly system administrator. + +If I put an entry in my /etc/services file: + +cvs_rcmd 4381/tcp cvs_rcmd + +And add a line to /etc/inetd.conf, then restart inetd via "kill -1" + +cvs_rcmd stream tcp nowait root /usr/sbin/tcpd /usr/local/sbin/cvs_rcmd + +On the VMS side, you will have to do this: + +$ define CVS_RCMD_PORT 4381 + +Then run CVS in the "usual way". + +Note that the patched rshd will need to be invoked via inetd as root, so it can +authenticate and _become_ the intended user, the same as the regular rshd. + +***Please note that you will be installing a security hole by doing this.*** + +Please also note that this security hole is no larger than allowing a +Macintosh, PC (OS/2, NT, etc.) to have it's hostname in any .rhosts file, +as any user can create a privileged socket without authentication, under these +environments. In fact, existing ports of CVS to these environment use this +to their advantage. + +------------------------------------------------------------------------------- +Wildcard expansion is not yet implemented (i.e. CVS COMMIT *.c won't +work.) I have found GPL'd routine which does shell globbing, but I +have not tried to put it in yet. + +Log messages must be entered on the command line using -m. I wanted to start +up TPU for editing log messages, but apparently SYS$SYSTEM:TPU.EXE requires +some command table parsing through DCL, and cannot be directly invoked using C +within CVS. [I did get LSEDIT to launch, but it wasn't interested in argv at +all.] + +You can use -e or define the logical EDITOR to cause CVS to try other editors +if you want to test what's available on your system. I haven't tested this, +but if you install vi or emacs, chances are it will probably work. Just make +sure the .EXE files are in a directory listed in VAXC$PATH. + +Credits: + +Initial VMS port by Benjamin J. Lee <benjamin@cyclic.com>, Cyclic +Software, October 1, 1995 (Update March 1, 1996). diff --git a/gnu/usr.bin/cvs/TESTS b/gnu/usr.bin/cvs/TESTS new file mode 100644 index 00000000000..a559c21af01 --- /dev/null +++ b/gnu/usr.bin/cvs/TESTS @@ -0,0 +1,128 @@ +To run the tests: + + $ make check + +Note that if your /bin/sh doesn't support shell functions, you'll +have to try something like this, where "/bin/sh5" is replaced by the +pathname of a shell which handles normal shell functions: + + $ make SHELL=/bin/sh5 check + +WARNING: This test can take quite a while to run, esp. if your +disks are slow or over-loaded. + +You will probably need GNU expr, which is part of the GNU sh-utils +package. + +If there is some unexpected output, that is a failure which can be +somewhat hard to track down. Finding out which test is producing the +output is not always easy. The newer tests (that is, ones using +dotest*) will not have this problem, but there are many old tests +which have not been converted. + +If running the tests produces the output "FAIL:" followed by the name +of the test that failed, then the details on the failure are in the +file check.log. If it says "exit status is " followed by a number, +then the exit status of the command under test was not what the test +expected. If it says "** expected:" followed by a regular expression +followed by "** got:" followed by some text, then the regular +expression is the output which the test expected, and the text is the +output which the command under test actually produced. In some cases +you'll have to look closely to see how they differ. + +If output from "make remotecheck" is out of order compared to what is +expected (for example, + + a + b + cvs foo: this is a demo + +is expected and + + a + cvs foo: this is a demo + b + +is output), this is probably a well-known bug in the CVS server +(search for "out-of-order" in src/server.c for a comment explaining +the cause). It is a real pain in running the testsuite, but if you +are lucky and/or your machine is fast and/or lightly loaded, you won't +run into it. Running the tests again might succeed if the first run +failed in this manner. + +For more information on what goes in check.log, and how the tests are +run in general, you'll have to read sanity.sh. Depending on just what +you are looking for, and how familiar you are with the Bourne shell +and regular expressions, it will range from relatively straightforward +to obscure. + +If you choose to submit a bug report based on tests failing, be +aware that, as with all bug reports, you may or may not get a +response, and your odds might be better if you include enough +information to reproduce the bug, an analysis of what is going +wrong (if you have the time to provide one), etc. The check.log +file is the first place to look. + +ABOUT STDOUT AND STDERR +*********************** + +The sanity.sh test framework combines stdout and stderr and for tests +to pass requires that output appear in the given order. Some people +suggest that ordering between stdout and stderr should not be +required, or to put it another way, that the out-of-order bug referred +to above, and similar behaviors, should be considered features, or at +least tolerable. The reasoning behind the current behavior is that +having the output appear in a certain order is the correct behavior +for users using CVS interactively--that users get confused if the +order is unpredictable. + +ABOUT TEST FRAMEWORKS +********************* + +People periodically suggest using dejagnu or some other test +framework. A quick look at sanity.sh should make it clear that there +are indeed reasons to be dissatisfied with the status quo. Ideally a +replacement framework would achieve the following: + +1. Widely portable, including to a wide variety of unices, NT, Win95, +OS/2, VMS, probably DOS and Win3, etc. + +2. Nicely match extended regular expressions of unlimited length. + +3. Be freely redistributable, and if possible already the kind of +thing people might have already installed. The harder it is to get +and install the framework, the less people will run the tests. + +The various contenders are: + +* Bourne shell and GNU expr (the status quo). Falls short on #1 +(we've only tried unix and NT, although MKS might help with other DOS +mutants). #3 is pretty good (the main dependency is GNU expr which is +fairly widely available). + +* Bourne shell with a new regexp matcher we would distribute with +CVS. This means maintaining a regexp matcher and the makefiles which +go with it. Not clearly a win over Bourne shell and GNU expr. + +* Bourne shell, and use sed to remove variable portions of output, and +thus produce a form that can be compared with cmp or diff (this +sidesteps the need for a full regular expression matcher as mentioned +in #2 above). The C News tests are said to work this way. This would +appear to rely on variable portions of output having a certain syntax +and might spuriously recognize them out of context (this issue needs +more investigation; it isn't clear how big a problem it is in +practice). Same portability issues as the other choices based on the +Bourne shell. + +* Dejagnu. This is overkill; most of dejagnu is either unnecessary +(e.g. libraries for communicating with target boards) or undesirable +(e.g. the code which stats every file in sight to find the tests). On +the plus side, dejagnu is probably closer than any of the other +choices to having everything which is needed already there. + +* Write our own small framework directly in tcl and distribute with +CVS. The tests would look much like dejagnu tests, but we'd avoid the +unnecessary baggage. The only dependency would be on tcl (that is, +wish). + +* perl or python or <any other serious contenders here?> diff --git a/gnu/usr.bin/cvs/TODO b/gnu/usr.bin/cvs/TODO index ef9306c3687..5ce4681f465 100644 --- a/gnu/usr.bin/cvs/TODO +++ b/gnu/usr.bin/cvs/TODO @@ -9,30 +9,26 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ 22. Catch signals for cleanup when "add"ing files. 24. Insist on a log message. - (This should be configurable via commitinfo or some new config file - -kingdon, Jun 1995). + (If done, this should be configurable via commitinfo or some new + config file -kingdon, Jun 1995). 30. Add "patch" program option to the modules database. 31. Think hard about ^C recovery. -35. Add "admin" command as an interface to "rcs". - [[ a cheesy version is there, but it should be re-done ]] - 38. Think hard about using RCS state information to allow one to checkin a new vendor release without having it be accessed until it has been integrated into the local changes. -39. Think about allowing parallel source trees that can easily track - each other. - [[ sort of solved with the automagic branch support, but I want more ]] - -45. Consider enhancing the "patch" and "tag" command support in the module - database -- they seem hard to use since these commands deal directly - with the RCS ,v files. +39. Think about a version of "cvs update -j" which remembers what from + that other branch is already merged. This has pitfalls--it could + easily lead to invisible state which could confuse users very + rapidly--but having to create a tag or some such mechanism to keep + track of what has been merged is a pain. -46. Perhaps checkout/checkin/tag/patch commands should be imbedded in the - file system directly, using special known command names? +45. Consider enhancing the "rdiff" and "tag" (rtag??) command support in + the module database -- they seem hard to use since these commands + deal directly with the RCS ,v files. 49. cvs xxx commands should be able to deal with files in other directories. I want to do a cvs add foo/bar.c. @@ -63,22 +59,12 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ 66. Length of the CVS temporary files must be limited to 14 characters for System-V stupid support. As well as the length on the CVS.adm files. -67. cvs import should populate the vendor sources with CVS.adm files so - that one could use the vendor sources directly without having the check - them out. - -69. Consider enhacing import to add a module automatically to the module - database. Perhaps with a new option, or perhaps with an editor. - 72. Consider re-design of the module -o, -i, -t options to use the file system more intuitively. 73. Consider an option (in .cvsrc?) to automatically add files that are new and specified to commit. -76. Consider adding a layer of abstraction so that CVS can work with both - RCS and SCCS files. Larry says this should be #ifdef'ed. - 79. Might be nice to have some sort of interface to TFS and tagged revisions. @@ -91,9 +77,6 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ 85. Add revision controlled symbolic links to CVS using one of the tag fields in the RCS file. -91. Better document the format of the source repository and how one might - convert their current SCCS or RCS files into CVS format. - 92. Look into this: After a bit of soul searching via dbx, I realized my sin was that I'd specified "echo" as the program to call from loginfo. The commit @@ -156,10 +139,15 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ (why? What is wrong with piping stdout to "tee"? -kingdon, Jun 1995) 119. Consider an option to have import checkout the RCS or SCCS files - if necessary. + if necessary. (this is if someone want to import something which is + in RCS or SCCS without preserving the history, but making sure they + do get the latest versions. It isn't clear to me how useful that is + -kingdon, June 1996). 122. If Name_Repository fails, it currently causes CVS to die completely. It - should instead return NULL and have the caller do something reasonable. + should instead return NULL and have the caller do something reasonable + (??? -what is reasonable? I'm not sure there is a real problem here. + -kingdon, June 1996). 123. Add a flag to import to not build vendor branches for local code. @@ -179,13 +167,6 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ 128. When I tag a file, the message tells me that I'm tagging a directory. -129. Something strange seems to have happened here. When I check this out, - the update lines (U CFTS/...) seem to report a bogus leading CFTS - (e.g. U CFTS/Medusa_TS/...) when the later files are checked out. - - The directory structure doesn't seem to be botched, just the - messages. I don't recall seeing this before. - 130. cvs diff with no -r arguments does not need to look up the current RCS version number since it only cares about what's in the Entries file. This should make it much faster. @@ -197,7 +178,8 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ 134. Make a statement about using hard NFS mounts to your source repository. Look into checking NULL fgets() returns with ferror() to - see if an error had occurred. + see if an error had occurred. (we should be checking for errors, quite + aside from NFS issues -kingdon, June 1996). 135. The email CVS sends with each checkin, should include the version number of each file it is checking in. @@ -252,6 +234,10 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ other than "rcsmerge" can be used, like Sun's filemerge or emacs's emerge.el. (but be careful in making this work client/server--it means doing the interactive merging at the end after the server is done). + (probably best is to have CVS do the non-interactive part and + tell the user about where the files are (.#foo.c.working and + .#foo.c.1.5 or whatever), so they can do the interactive part at + that point -kingdon, June 1996). 149. On Sun, 2 Feb 92 22:01:38 EST, rouilj@dl5000.bc.edu (John P. Rouillard) said: @@ -279,7 +265,9 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ The text is saved as CVS/foo.c,m (or some such name) and commit is modified to append (prepend?) the text (if found) to the log message - specified at commit time. Easy enough. + specified at commit time. Easy enough. (having cvs commit be + non-interactive takes care of various issues like whether to connect + to the server before or after prompting for a message -kingdon, June 1996) 151. Also, is there a flag I am missing that allows replacing Ulrtx_Build by Ultrix_build? I.E. I would like a tag replacement to be a one step @@ -311,10 +299,6 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ the various flags that are now available, or if somebody has a lot of files to put into a module. -157. The "cvs release" command does not understand about module names with - the same flexibility that the "checkout" and "rdiff" commands do. - It should, though, since it's confusing right now. - 158. If I do a recursive commit and find that the same RCS file is checked out (and modified!) in two different places within my checked-out files (but within the realm of a single "commit"), CVS will commit the @@ -322,13 +306,6 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ should catch this (typically unusual) case and issue an appropriate diagnostic and die. -159. On "update", when a merge is done, CVS should remember that your file - was merged into and should keep reminding you of this fact until you - actually look at the file (change its access time). Once you do this, - it should go back to being a normal, unmodified file. This way, after - a big update, you can run update again to see which files just got - merged and may need attention. - 160. The checks that the commit command does should be extended to make sure that the revision that we will lock is not already locked by someone else. Maybe it should also lock the new revision if the old @@ -343,11 +320,6 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ tag (like "Mon", "Tue", ...) all the time and still have it tag the real main-line code. -164. The *info files should allow multiple ocurrences of $CVSROOT and/or - other cvs variables. They probably should *not* expand environment - variables, as their behavior probably should not depend on who is - running CVS. - 165. The "import" command will create RCS files automatically, but will screw-up when trying to create long file names on short file name file systems. Perhaps import should be a bit more cautious. @@ -359,15 +331,6 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ - What all the tags mean in an "import" command - Tags are important; revision numbers are not -167. "cvs log" doesn't understand about CVS magic branch numbers. As such, - the command: - - cvs log -r1.63.2 - cvs log -rC2 - - where "C2" is a magic branch that resolves to 1.63.2 do not print the - same things. Sigh. - 169. We are using CVS as the configuration control for a software reuse library. What we do is do system calls passing the needed arguments. In the next release, it would be nice to see an option to put cvs .o files into a @@ -421,3 +384,25 @@ $CVSid: @(#)TODO 1.26 94/09/21 $ 179. "cvs admin" does not log its actions with loginfo, nor does it check whether the action is allowed with commitinfo. It should. + +180. "cvs edit" should show you who is already editing the files, + probably (that is, do "cvs editors" before executing, or some + similar result). (But watch out for what happens if the network + is down!). + +181. Make a "cvs message" command which prompts for a log message and + stores it in the CVS directory. Then "cvs ci" would use it. + This solves the problem with where in the client to prompt for + the log message (see comment in commit.c at call to + start_server), allows users more flexibility in specifying + messages per-directory ("cvs message -l") or per-tree ("cvs + message") or per-file ("cvs message foo.c"), and fixes the + incompatibility between client/server (per-tree) and + non-client/server (per-directory). + +182. There should be a way to show log entries corresponding to +changes from tag "foo" to tag "bar". "cvs log -rfoo -rbar" doesn't +cut it, because it is inclusive on the bar end. I'm not sure that is +ever a useful or logical behavior ("cvs diff -r foo -r bar" is not +similarly inclusive), but is compatibility an issue? + diff --git a/gnu/usr.bin/cvs/acconfig.h b/gnu/usr.bin/cvs/acconfig.h index 551a8aa6524..5e74b1baddc 100644 --- a/gnu/usr.bin/cvs/acconfig.h +++ b/gnu/usr.bin/cvs/acconfig.h @@ -10,3 +10,6 @@ /* Define if you want to use the password authenticated server. */ #undef AUTH_SERVER_SUPPORT + +/* Define if you want encryption support. */ +#undef ENCRYPTION diff --git a/gnu/usr.bin/cvs/build.com b/gnu/usr.bin/cvs/build.com new file mode 100644 index 00000000000..1d5b9089b38 --- /dev/null +++ b/gnu/usr.bin/cvs/build.com @@ -0,0 +1,8 @@ +$ set def [.zlib] +$ @build_zlib.com +$ set def [-.vms] +$ @build_vms.com +$ set def [-.lib] +$ @build_lib.com +$ set def [-.src] +$ @build_src.com diff --git a/gnu/usr.bin/cvs/config.h.in b/gnu/usr.bin/cvs/config.h.in index 91819366096..9a9a5b83392 100644 --- a/gnu/usr.bin/cvs/config.h.in +++ b/gnu/usr.bin/cvs/config.h.in @@ -7,11 +7,6 @@ #undef _ALL_SOURCE #endif -/* Define if type char is unsigned and you are not using gcc. */ -#ifndef __CHAR_UNSIGNED__ -#undef __CHAR_UNSIGNED__ -#endif - /* Define to empty if the keyword does not work. */ #undef const @@ -27,9 +22,6 @@ /* Define if utime(file, NULL) sets file's timestamp to the present. */ #undef HAVE_UTIME_NULL -/* Define as __inline if that's what the C compiler calls it. */ -#undef inline - /* Define if on MINIX. */ #undef _MINIX @@ -77,6 +69,9 @@ /* Define if you want to use the password authenticated server. */ #undef AUTH_SERVER_SUPPORT +/* Define if you want encryption support. */ +#undef ENCRYPTION + /* The number of bytes in a int. */ #undef SIZEOF_INT @@ -86,6 +81,9 @@ /* Define if you have the connect function. */ #undef HAVE_CONNECT +/* Define if you have the crypt function. */ +#undef HAVE_CRYPT + /* Define if you have the fchdir function. */ #undef HAVE_FCHDIR @@ -104,6 +102,12 @@ /* Define if you have the getpagesize function. */ #undef HAVE_GETPAGESIZE +/* Define if you have the getspnam function. */ +#undef HAVE_GETSPNAM + +/* Define if you have the initgroups function. */ +#undef HAVE_INITGROUPS + /* Define if you have the krb_get_err_text function. */ #undef HAVE_KRB_GET_ERR_TEXT @@ -197,6 +201,9 @@ /* Define if you have the <utime.h> header file. */ #undef HAVE_UTIME_H +/* Define if you have the crypt library (-lcrypt). */ +#undef HAVE_LIBCRYPT + /* Define if you have the inet library (-linet). */ #undef HAVE_LIBINET @@ -206,5 +213,8 @@ /* Define if you have the nsl_s library (-lnsl_s). */ #undef HAVE_LIBNSL_S +/* Define if you have the sec library (-lsec). */ +#undef HAVE_LIBSEC + /* Define if you have the socket library (-lsocket). */ #undef HAVE_LIBSOCKET diff --git a/gnu/usr.bin/cvs/contrib/ChangeLog b/gnu/usr.bin/cvs/contrib/ChangeLog index 80db5b857f3..5826410c65b 100644 --- a/gnu/usr.bin/cvs/contrib/ChangeLog +++ b/gnu/usr.bin/cvs/contrib/ChangeLog @@ -1,3 +1,40 @@ +Sun Sep 29 19:45:19 1996 Greg A. Woods <woods@most.weird.com> + + * README: add entry for patch-2.1-.new-fix. + + * README: re-write the top section a bit. + + * patch-2.1-.new-fix: re-generated using fixed "cvs patch" command. + + * patch-2.1-.new-fix: new file. + +Sun Sep 29 14:25:28 1996 Dave Love <d.love@dl.ac.uk> + + * rcs2log.sh (month_data): Make default date format acceptable to + CVS post v1.8 as well as earlier CVSs and RCS. + Message-Id: <199609291546.QAA25531@mserv1.dl.ac.uk> + To: bug-gnu-emacs@prep.ai.mit.edu + +Thu Aug 29 11:58:03 1996 Jim Blandy <jimb@totoro.cyclic.com> + + * rcs2log: Update FSF address. + + * rcs2log: Be more aggressive about finding the author's full + name; try nismatch and ypmatch. + + * rcs2log: If the hostname appears not to be fully qualified, see + if domainname provides any useful information. + +Fri Aug 16 16:02:36 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * Makefile.in (installdirs): support this target + +Mon May 6 13:04:57 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (install): Don't tell user to run cvsinit. It isn't + called cvsinit anymore, and it isn't necessary (repositories are, + and need to be, compatible between cvs versions). + Sun Apr 14 11:30:36 1996 Karl Fogel <kfogel@floss.red-bean.com> * Removed pcl-cvs/ subdir; see tools/ subdir in the top-level from diff --git a/gnu/usr.bin/cvs/contrib/README b/gnu/usr.bin/cvs/contrib/README index d453f8d5616..004d894551a 100644 --- a/gnu/usr.bin/cvs/contrib/README +++ b/gnu/usr.bin/cvs/contrib/README @@ -1,27 +1,33 @@ $CVSid: @(#)README 1.12 94/09/25 $ -This "contrib" directory is a place holder for code/scripts sent to -me by contributors around the world. This README file will be kept -up-to-date from release to release. BUT, I must point out that these -contributions are really, REALLY UNSUPPORTED. In fact, I probably -don't even know what they do. Nor do I guarantee to have tried them, -or ported them to work with this CVS distribution. If you have questions, -you might contact the author, but you should not necessarily expect -a reply. USE AT YOUR OWN RISK -- and all that stuff. +This "contrib" directory is a place holder for code/scripts sent to me +by contributors around the world. This README file will be kept +up-to-date from release to release. BUT, we must point out that these +contributions are really, REALLY UNSUPPORTED. In fact, we probably +don't even know what some of them really do. We certainly do not +guarantee to have tried them, or ported them to work with this CVS +distribution. If you have questions, your best bet is to contact the +original author, but you should not necessarily expect a reply, since +the author may not be available at the address given. -"Unsupported" also means that noone has volunteered to accept and -check in changes to this directory. So submissions for new scripts to -add here are unlikely to be accepted. Suggested changes to the -existing scripts here conceivably might, but that isn't clear either. -The exception is pcl-cvs; that is more actively maintained (see -pcl-cvs/README). If you have some software that works with CVS that -you wish to offer it is suggested that you make it available by FTP or -HTTP and then announce it on the info-cvs mailing list. There is also -a web page of software related to CVS at -http://www.loria.fr/~molli/cvs-index.html which would presumably be -willing to list your software. +USE AT YOUR OWN RISK -- and all that stuff. -Contents of this directory: +"Unsupported" also means that no one has volunteered to accept and check +in changes to this directory. So submissions for new scripts to add +here are unlikely to be accepted. Suggested changes to the existing +scripts here conceivably might, but that isn't clear either, unless of +course they come from the original author of the script. + +If you have some software that works with CVS that you wish to offer it +is suggested that you make it available by FTP or HTTP and then announce +it on the info-cvs mailing list. + +There is a web page of software related to CVS at the following URL which +would presumably be willing to list your software. + + http://www.loria.fr/~molli/cvs-index.html + +An attempt at a table of Contents for this directory: README This file. log A perl script suitable for including in your @@ -104,3 +110,7 @@ Contents of this directory: by hostname, then runs a subprocess whose input/output is redirected through the port. Contributed by Benjamin J. Lee <benjamin@cyclic.com> + patch-2.1-.new-fix + A fix for GNU Patch version 2.1 which (more) properly + handles creation of new files. + Contributed by Greg A. Woods <woods@planix.com> diff --git a/gnu/usr.bin/cvs/cvs.spec b/gnu/usr.bin/cvs/cvs.spec new file mode 100644 index 00000000000..e2f73ab59fa --- /dev/null +++ b/gnu/usr.bin/cvs/cvs.spec @@ -0,0 +1,45 @@ +Summary: Concurrent Versions System +Name: cvs +Version: @VERSION@ +Release: 1 +Copyright: GPL +Group: Development/Version Control +Source: ftp.cyclic.com:/pub/cvs-@VERSION@.tar.gz +Buildroot: / + +%description +CVS is a version control system, which allows you to keep old versions +of files (usually source code), keep a log of who, when, and why +changes occurred, etc., like RCS or SCCS. It handles multiple +developers, multiple directories, triggers to enable/log/control +various operations, and can work over a wide area network. The +following tasks are not included; they can be done in conjunction with +CVS but will tend to require some script-writing and software other +than CVS: bug-tracking, build management (that is, make and make-like +tools), and automated testing. + +%prep +%setup + +%build +./configure --prefix=$RPM_BUILD_ROOT/usr +make CFLAGS="$RPM_OPT_FLAGS -DRCSBIN_DFLT=\\\"/usr/bin\\\"" LDFLAGS=-s + +%install +make installdirs +make install +rm -f $RPM_BUILD_ROOT/usr/info/cvs* +make install-info +gzip -9nf $RPM_BUILD_ROOT/usr/info/cvs* + +%files +%doc BUGS COPYING COPYING.LIB ChangeLog ChangeLog.zoo FAQ HACKING +%doc INSTALL MINOR-BUGS NEWS PROJECTS README TESTS TODO +/usr/bin/cvs +/usr/bin/cvsbug +/usr/bin/rcs2log +/usr/man/man1/cvs.1 +/usr/man/man5/cvs.5 +/usr/man/man8/cvsbug.8 +/usr/info/cvs* +/usr/lib/cvs diff --git a/gnu/usr.bin/cvs/cvsnt.mak b/gnu/usr.bin/cvs/cvsnt.mak index ca4765749d6..37c617d3a09 100644 --- a/gnu/usr.bin/cvs/cvsnt.mak +++ b/gnu/usr.bin/cvs/cvsnt.mak @@ -48,9 +48,9 @@ $(OUTDIR) : if not exist $(OUTDIR)/nul mkdir $(OUTDIR) # ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c -# ADD CPP /nologo /W3 /GX /YX /Ob1 /I "windows-NT" /I "lib" /I "src" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "HAVE_CONFIG_H" /FR /c +# ADD CPP /nologo /W3 /GX /YX /Ob1 /I "windows-NT" /I "lib" /I "src" /I "zlib" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "HAVE_CONFIG_H" /FR /c # SUBTRACT CPP /WX -CPP_PROJ=/nologo /W3 /GX /YX /Ob1 /I "windows-NT" /I "lib" /I "src" /D "NDEBUG"\ +CPP_PROJ=/nologo /W3 /GX /YX /Ob1 /I "windows-NT" /I "lib" /I "src" /I "zlib" /D "NDEBUG"\ /D "WIN32" /D "_CONSOLE" /D "HAVE_CONFIG_H" /FR$(INTDIR)/\ /Fp$(OUTDIR)/"cvsnt.pch" /Fo$(INTDIR)/ /c CPP_OBJS=.\WinRel/ @@ -110,6 +110,8 @@ BSC32_SBRS= \ $(INTDIR)/watch.sbr \ $(INTDIR)/login.sbr \ $(INTDIR)/scramble.sbr \ + $(INTDIR)/buffer.sbr \ + $(INTDIR)/zlib.sbr \ $(INTDIR)/getwd.sbr \ $(INTDIR)/sighandle.sbr \ $(INTDIR)/getopt.sbr \ @@ -135,7 +137,21 @@ BSC32_SBRS= \ $(INTDIR)/strippath.sbr \ $(INTDIR)/stripslash.sbr \ $(INTDIR)/rcmd.sbr \ - $(INTDIR)/startserver.sbr + $(INTDIR)/startserver.sbr \ + $(INTDIR)/zutil.sbr \ + $(INTDIR)/infutil.sbr \ + $(INTDIR)/infblock.sbr \ + $(INTDIR)/compress.sbr \ + $(INTDIR)/uncompr.sbr \ + $(INTDIR)/inflate.sbr \ + $(INTDIR)/inftrees.sbr \ + $(INTDIR)/gzio.sbr \ + $(INTDIR)/infcodes.sbr \ + $(INTDIR)/deflate.sbr \ + $(INTDIR)/adler32.sbr \ + $(INTDIR)/crc32.sbr \ + $(INTDIR)/inffast.sbr \ + $(INTDIR)/trees.sbr $(OUTDIR)/cvsnt.bsc : $(OUTDIR) $(BSC32_SBRS) $(BSC32) @<< @@ -143,12 +159,10 @@ $(OUTDIR)/cvsnt.bsc : $(OUTDIR) $(BSC32_SBRS) << LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386 /OUT:"WinRel/cvs.exe" -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ - odbccp32.lib wsock32.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no\ - /PDB:$(OUTDIR)/"cvsnt.pdb" /MACHINE:I386 /OUT:"WinRel/cvs.exe" +# ADD BASE LINK32 advapi32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386 +# ADD LINK32 advapi32.lib wsock32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386 /OUT:"WinRel/cvs.exe" +LINK32_FLAGS=advapi32.lib wsock32.lib /NOLOGO /SUBSYSTEM:console\ + /INCREMENTAL:no /PDB:$(OUTDIR)/"cvsnt.pdb" /MACHINE:I386 /OUT:"WinRel/cvs.exe" DEF_FILE= LINK32_OBJS= \ $(INTDIR)/mkmodules.obj \ @@ -200,6 +214,8 @@ LINK32_OBJS= \ $(INTDIR)/watch.obj \ $(INTDIR)/login.obj \ $(INTDIR)/scramble.obj \ + $(INTDIR)/buffer.obj \ + $(INTDIR)/zlib.obj \ $(INTDIR)/getwd.obj \ $(INTDIR)/sighandle.obj \ $(INTDIR)/getopt.obj \ @@ -225,7 +241,21 @@ LINK32_OBJS= \ $(INTDIR)/strippath.obj \ $(INTDIR)/stripslash.obj \ $(INTDIR)/rcmd.obj \ - $(INTDIR)/startserver.obj + $(INTDIR)/startserver.obj \ + $(INTDIR)/zutil.obj \ + $(INTDIR)/infutil.obj \ + $(INTDIR)/infblock.obj \ + $(INTDIR)/compress.obj \ + $(INTDIR)/uncompr.obj \ + $(INTDIR)/inflate.obj \ + $(INTDIR)/inftrees.obj \ + $(INTDIR)/gzio.obj \ + $(INTDIR)/infcodes.obj \ + $(INTDIR)/deflate.obj \ + $(INTDIR)/adler32.obj \ + $(INTDIR)/crc32.obj \ + $(INTDIR)/inffast.obj \ + $(INTDIR)/trees.obj $(OUTDIR)/cvs.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< @@ -251,10 +281,9 @@ $(OUTDIR) : if not exist $(OUTDIR)/nul mkdir $(OUTDIR) # ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c -# ADD CPP /nologo /W3 /GX /Zi /YX /Ob1 /I "windows-NT" /I "lib" /I "src" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "HAVE_CONFIG_H" /FR /c -# SUBTRACT CPP /WX -CPP_PROJ=/nologo /W3 /GX /Zi /YX /Ob1 /I "windows-NT" /I "lib" /I "src" /D\ - "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "HAVE_CONFIG_H" /FR$(INTDIR)/\ +# ADD CPP /nologo /W3 /GX /Zi /YX /Ob1 /I "windows-NT" /I "lib" /I "src" /I "zlib" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "HAVE_CONFIG_H" /FR /c +CPP_PROJ=/nologo /W3 /GX /Zi /YX /Ob1 /I "windows-NT" /I "lib" /I "src" /I\ + "zlib" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "HAVE_CONFIG_H" /FR$(INTDIR)/\ /Fp$(OUTDIR)/"cvsnt.pch" /Fo$(INTDIR)/ /Fd$(OUTDIR)/"cvsnt.pdb" /c CPP_OBJS=.\WinDebug/ # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -313,6 +342,8 @@ BSC32_SBRS= \ $(INTDIR)/watch.sbr \ $(INTDIR)/login.sbr \ $(INTDIR)/scramble.sbr \ + $(INTDIR)/buffer.sbr \ + $(INTDIR)/zlib.sbr \ $(INTDIR)/getwd.sbr \ $(INTDIR)/sighandle.sbr \ $(INTDIR)/getopt.sbr \ @@ -338,7 +369,21 @@ BSC32_SBRS= \ $(INTDIR)/strippath.sbr \ $(INTDIR)/stripslash.sbr \ $(INTDIR)/rcmd.sbr \ - $(INTDIR)/startserver.sbr + $(INTDIR)/startserver.sbr \ + $(INTDIR)/zutil.sbr \ + $(INTDIR)/infutil.sbr \ + $(INTDIR)/infblock.sbr \ + $(INTDIR)/compress.sbr \ + $(INTDIR)/uncompr.sbr \ + $(INTDIR)/inflate.sbr \ + $(INTDIR)/inftrees.sbr \ + $(INTDIR)/gzio.sbr \ + $(INTDIR)/infcodes.sbr \ + $(INTDIR)/deflate.sbr \ + $(INTDIR)/adler32.sbr \ + $(INTDIR)/crc32.sbr \ + $(INTDIR)/inffast.sbr \ + $(INTDIR)/trees.sbr $(OUTDIR)/cvsnt.bsc : $(OUTDIR) $(BSC32_SBRS) $(BSC32) @<< @@ -346,12 +391,11 @@ $(OUTDIR)/cvsnt.bsc : $(OUTDIR) $(BSC32_SBRS) << LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386 /OUT:"WinDebug/cvs.exe" -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ - odbccp32.lib wsock32.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes\ - /PDB:$(OUTDIR)/"cvsnt.pdb" /DEBUG /MACHINE:I386 /OUT:"WinDebug/cvs.exe" +# ADD BASE LINK32 advapi32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386 +# ADD LINK32 advapi32.lib wsock32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386 /OUT:"WinDebug/cvs.exe" +LINK32_FLAGS=advapi32.lib wsock32.lib /NOLOGO /SUBSYSTEM:console\ + /INCREMENTAL:yes /PDB:$(OUTDIR)/"cvsnt.pdb" /DEBUG /MACHINE:I386\ + /OUT:"WinDebug/cvs.exe" DEF_FILE= LINK32_OBJS= \ $(INTDIR)/mkmodules.obj \ @@ -403,6 +447,8 @@ LINK32_OBJS= \ $(INTDIR)/watch.obj \ $(INTDIR)/login.obj \ $(INTDIR)/scramble.obj \ + $(INTDIR)/buffer.obj \ + $(INTDIR)/zlib.obj \ $(INTDIR)/getwd.obj \ $(INTDIR)/sighandle.obj \ $(INTDIR)/getopt.obj \ @@ -428,7 +474,21 @@ LINK32_OBJS= \ $(INTDIR)/strippath.obj \ $(INTDIR)/stripslash.obj \ $(INTDIR)/rcmd.obj \ - $(INTDIR)/startserver.obj + $(INTDIR)/startserver.obj \ + $(INTDIR)/zutil.obj \ + $(INTDIR)/infutil.obj \ + $(INTDIR)/infblock.obj \ + $(INTDIR)/compress.obj \ + $(INTDIR)/uncompr.obj \ + $(INTDIR)/inflate.obj \ + $(INTDIR)/inftrees.obj \ + $(INTDIR)/gzio.obj \ + $(INTDIR)/infcodes.obj \ + $(INTDIR)/deflate.obj \ + $(INTDIR)/adler32.obj \ + $(INTDIR)/crc32.obj \ + $(INTDIR)/inffast.obj \ + $(INTDIR)/trees.obj $(OUTDIR)/cvs.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< @@ -1810,6 +1870,67 @@ $(INTDIR)/scramble.obj : $(SOURCE) $(DEP_SCRAM) $(INTDIR) $(CPP) $(CPP_PROJ) $(SOURCE) # End Source File +################################################################################ +# Begin Source File + +SOURCE=.\src\buffer.c +DEP_BUFFE=\ + .\src\cvs.h\ + .\src\buffer.h\ + ".\windows-NT\config.h"\ + ".\windows-NT\options.h"\ + .\lib\fnmatch.h\ + ".\windows-NT\pwd.h"\ + .\lib\system.h\ + .\src\hash.h\ + .\src\client.h\ + .\src\myndbm.h\ + .\lib\regex.h\ + .\lib\getopt.h\ + .\lib\wait.h\ + .\src\rcs.h\ + .\src\error.h\ + .\src\update.h\ + .\src\server.h\ + ".\windows-NT\ndir.h" + +$(INTDIR)/buffer.obj : $(SOURCE) $(DEP_BUFFE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\src\zlib.c +DEP_ZLIB_=\ + .\src\cvs.h\ + .\src\buffer.h\ + ".\windows-NT\config.h"\ + ".\windows-NT\options.h"\ + .\lib\fnmatch.h\ + ".\windows-NT\pwd.h"\ + .\lib\system.h\ + .\src\hash.h\ + .\src\client.h\ + .\src\myndbm.h\ + .\lib\regex.h\ + .\lib\getopt.h\ + .\lib\wait.h\ + .\src\rcs.h\ + .\src\error.h\ + .\src\update.h\ + .\src\server.h\ + ".\windows-NT\ndir.h" + +$(INTDIR)/zlib.obj : $(SOURCE) $(DEP_ZLIB_) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\src\ChangeLog +# End Source File # End Group ################################################################################ # Begin Group "lib" @@ -2180,6 +2301,215 @@ $(INTDIR)/startserver.obj : $(SOURCE) $(DEP_START) $(INTDIR) $(CPP) $(CPP_PROJ) $(SOURCE) # End Source File +################################################################################ +# Begin Source File + +SOURCE=".\windows-NT\ChangeLog" +# End Source File +# End Group +################################################################################ +# Begin Group "zlib" + +################################################################################ +# Begin Source File + +SOURCE=.\zlib\zutil.c +DEP_ZUTIL=\ + .\zlib\zutil.h\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/zutil.obj : $(SOURCE) $(DEP_ZUTIL) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\infutil.c +DEP_INFUT=\ + .\zlib\zutil.h\ + .\zlib\infblock.h\ + .\zlib\inftrees.h\ + .\zlib\infcodes.h\ + .\zlib\infutil.h\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/infutil.obj : $(SOURCE) $(DEP_INFUT) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\infblock.c +DEP_INFBL=\ + .\zlib\zutil.h\ + .\zlib\infblock.h\ + .\zlib\inftrees.h\ + .\zlib\infcodes.h\ + .\zlib\infutil.h\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/infblock.obj : $(SOURCE) $(DEP_INFBL) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\compress.c +DEP_COMPR=\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/compress.obj : $(SOURCE) $(DEP_COMPR) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\uncompr.c +DEP_UNCOM=\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/uncompr.obj : $(SOURCE) $(DEP_UNCOM) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\inflate.c +DEP_INFLA=\ + .\zlib\zutil.h\ + .\zlib\infblock.h\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/inflate.obj : $(SOURCE) $(DEP_INFLA) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\inftrees.c +DEP_INFTR=\ + .\zlib\zutil.h\ + .\zlib\inftrees.h\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/inftrees.obj : $(SOURCE) $(DEP_INFTR) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\gzio.c +DEP_GZIO_=\ + .\zlib\zutil.h\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/gzio.obj : $(SOURCE) $(DEP_GZIO_) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\infcodes.c +DEP_INFCO=\ + .\zlib\zutil.h\ + .\zlib\inftrees.h\ + .\zlib\infblock.h\ + .\zlib\infcodes.h\ + .\zlib\infutil.h\ + .\zlib\inffast.h\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/infcodes.obj : $(SOURCE) $(DEP_INFCO) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\deflate.c +DEP_DEFLA=\ + .\zlib\deflate.h\ + .\zlib\zutil.h\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/deflate.obj : $(SOURCE) $(DEP_DEFLA) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\adler32.c +DEP_ADLER=\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/adler32.obj : $(SOURCE) $(DEP_ADLER) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\crc32.c +DEP_CRC32=\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/crc32.obj : $(SOURCE) $(DEP_CRC32) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\inffast.c +DEP_INFFA=\ + .\zlib\zutil.h\ + .\zlib\inftrees.h\ + .\zlib\infblock.h\ + .\zlib\infcodes.h\ + .\zlib\infutil.h\ + .\zlib\inffast.h\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/inffast.obj : $(SOURCE) $(DEP_INFFA) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\zlib\trees.c +DEP_TREES=\ + .\zlib\deflate.h\ + .\zlib\zutil.h\ + .\zlib\zlib.h\ + .\zlib\zconf.h + +$(INTDIR)/trees.obj : $(SOURCE) $(DEP_TREES) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +# End Source File # End Group # End Project ################################################################################ diff --git a/gnu/usr.bin/cvs/doc/ChangeLog b/gnu/usr.bin/cvs/doc/ChangeLog index 01efb1a2ef7..b97c695c86c 100644 --- a/gnu/usr.bin/cvs/doc/ChangeLog +++ b/gnu/usr.bin/cvs/doc/ChangeLog @@ -1,3 +1,482 @@ +Tue Oct 1 14:15:33 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo: Revert all recent changes (the last unscathed one + is the CVSUMASK one from Sunday). For the most part said changes + are for new features which are not appropriate at this stage of + the release process. None of the changes being reverted need to + go into 1.9, that is for sure. + +Mon Sep 30 18:17:34 1996 Greg A. Woods <woods@most.weird.com> + + * cvs.texinfo (Credits): add comment asking if we should update. + Add more detail about printing Letter on A4. + Add some comments about internal comments. + (From files): describe "cvs import -b 1" for importing existing + projects onto the main branch. + (First import): add a couple of helpful hints about naming vendor + and release tags, etc., and regularize the examples with this. + (Tracking sources): noted some reasons why you might use vendor + branches with "cvs import". + (Update imports): mention using "update" in place of "checkout" if + you have an existing working directory. + (Binary files in imports): add sub-menu separator comment. + (Tracking sources): new menu entry "Reverting to vendor release". + (Reverting to vendor release): new node to describe reverting + local changes and optionally using patch(1) to move local changes + forward. + (Global options): describe -D and -g, as well as DIFFBIN and + GREPBIN. + (export examples): add one. + (import options): describe the effect of '-b 1'. + +Mon Sep 30 08:09:53 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo: Adjust comments concerning A4 vs. US letter, + referring to ../README. + + * cvs.texinfo (Common options): Add comment about dates which CVS + uses in output. + +Sun Sep 29 11:14:16 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Keyword list): Don't mention Name twice. + + * cvs.texinfo (File permissions): Expand CVSUMASK stuff a bit. + (Setting a watch, Environment variables, Global options): Update + index entries for "read-only files, and ...". + + * cvsclient.texi (Requests): State that Gzip-stream is preferred + to gzip-file-contents. Cite RFC1952/1951 rather than just "gzip". + Say that RFC1950/1951 compression is also known as "zlib". + +Sat Sep 28 09:31:45 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Repository): Move all information about the + internal structure of the repository to User modules node. Rename + it to "Repository storage" ("User modules" wasn't particularly + clear). Mention CVSUMASK. Much clarification and + reorganization. + (Basic concepts): Remove material which duplicates what is now in + Repository. Rewrite paragraph introducing modules. + + * cvs.texinfo (Starting a new project): In discussing difficulty + in renaming files, don't refer to "cvs 1.x"--there is no + non-vaporous "cvs 2.x". Reword to reflect that part of the reason + to avoid renames (where possible) is not because of CVS at all, and + to try to give a general impression of how bad CVS issues involved in + renaming are. + +Fri Sep 27 04:23:44 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Adding files): Talk about directories, not modules, + since that is what is meant. Suggest using -kb option to add + rather than running cvs admin after the fact and xref to Binary + files not admin examples. Incorporate information which had been + in "add" node (there was a lot of duplication). Don't document + use of "add" on a directory to take the place of "cvs update -d"; + the latter is simpler and more logical. + (add, add options, add examples): Removed. + (release output, release options): Update xrefs accordingly. + (Adding files, Removing files): Mention the fact that adds and + removes are branch-specific. + (Merging adds and removals): New node. + + * cvs.texinfo (Concurrency): When mentioning RCS locks, use the + term reserved checkouts and xref to the place where we discuss + them in more depth. + +Thu Sep 26 08:26:01 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (log): Add comments about timezones. + (log, Common options): Add index entries for timezone and zone, time. + +Wed Sep 25 11:05:30 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (log options): Add xref to where we describe the + date formats that -d accepts. + (Common options): Don't refer to date formats accepted by co(1); + CVS's rules have never been the same. Add long whiny comment + about what a mess date formats are. + +Tue Sep 24 11:49:02 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (From other version control systems): The RCS file + must not be locked when you copy it to the CVS repository. + + * cvs.texinfo (Editing files): Also discuss how to revert in the + non-watch case. Add some index entries. + + * cvs.texinfo (update output): Add comment about how we *should* + be handling .# files. Mention fact that it is different under + VMS. Add .# to index. + +Fri Sep 20 13:08:33 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Multiple developers): Revise text on reserved + versus unreserved checkouts extensively. Move index entries for + "reserved checkouts" and "RCS-style locking" to here. Add + cross-reference to cvs admin -l. Add new section "Choosing a + model". + (Editing files): Add note about use of the word "checkout". + +Tue Sep 17 00:54:57 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Defining the module): Don't suggest "cvs co + modules"; that depends on a "modules" module being defined which + is not the default which is created by "cvs init". Instead + suggest "cvs co CVSROOT/modules" which should always work. + +Tue Sep 17 00:43:49 1996 VaX#n8 <vax@linkdead.paranoia.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Rename by copying): Suggest "cvs tag -d" on the file + "new", not on everything. Also don't suggest deleting branch tags. + +Tue Sep 17 00:34:39 1996 David A. Swierczek <swierczekd@med.ge.com> + + * Makefile.in (install-info): Note whether files are in srcdir and + deal with it rather than cd'ing into srcdir. + +Mon Sep 16 23:33:36 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Wrappers): Add comment about using wrappers to + compress files in the repository. + + * cvs.texinfo (modules): Add comments about how we should be + documenting how -i and friends operate in client/server CVS. + + * cvs.texinfo (File permissions): Describe the need for write + permissions for locks and val-tags. + + * cvs.texinfo (commitinfo): Add comment about using commitinfo to + enforce who has access. + +Wed Jul 24 17:01:41 1996 Larry Jones <larry.jones@sdrc.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (checkout): Refer to "update output" node. + (import): Add new import output node. + (release): Correct release output menu entry (used to be + release options instead). + (update output): Say this is output from checkout as well as + update. + +Mon Sep 16 16:18:38 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Common options): Clarify that CVS uses MM/DD/YY dates. + + * cvs.texinfo (Common options): Add comment about what HEAD means. + +Mon Sep 16 10:52:04 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * cvs.texinfo (Global options): Document global '-T' option. + +Sat Sep 14 10:46:58 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Keeping a checked out copy): New node. + +Fri Sep 13 23:55:42 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Magic branch numbers): Delete song and dance about + how cvs log can't cope with magic branches because rlog doesn't + know about them; cvs log no longer calls rlog. Delete item about + how you can't specify a symbolic branch to cvs log; that is fixed. + +Wed Sep 11 22:48:21 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Password authentication server): Add comments + regarding port numbers and troubleshooting. + +Tue Sep 10 10:36:00 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (What is CVS?): Reword text regarding info-cvs, + to avoid overfull hbox. + + * cvs.texinfo (Binary files): Add comment about further issues + with recovering from failure to use -kb. + + * cvs.texinfo (Conflicts example): Describe the "feature" by which + CVS won't check in files with conflicts. + (File status): Expand and revise to document all the possible + statuses from cvs status. Also document "Working revision" and + "Repository revision". Refer to other sections for other aspects + of cvs status. + (status options): Refer to other sections as appropriate. + (update output): Refer user to Conflicts example node. Add + comment regarding purging of .# files. + +Fri Sep 6 11:47:14 1996 Ian Lance Taylor <ian@cygnus.com> + + * cvs.texinfo (Kerberos authenticated): Mention need for + --enable-encryption option in order to use encryption. + (Global options): Likewise, in description of -x option. + +Thu Sep 5 14:31:42 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Connecting via rsh): Discuss :ext:, :server:, and + CVS_RSH. + (Remote repositories): Mention what default is if no access method + is specified. + (Environment variables): Don't discuss CVS_RSH at length here; + rely on reference to "Connecting via rsh" node. + +Mon Aug 26 15:39:18 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Protocol Notes): When talking about having the + client know the original contents of files, suggest cvs edit as a + solution. + +Thu Aug 22 10:44:40 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Keyword list): Document Name keyword. + + * cvs.texinfo (Tags): Revise comment regarding legal tag names. + +Mon Aug 12 14:58:54 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Password authentication security): Add comment + about how some of this is not pserver-specific. + +Tue Aug 6 16:48:53 1996 Ian Lance Taylor <ian@cygnus.com> + + * cvs.texinfo (log, log options): Update for changes to cvs log + now that it no longer invokes rlog. + +Thu Jul 25 10:10:16 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Requests): Fix typo (Kerberos-request -> + Kerberos-encrypt). + +Wed Jul 24 18:53:13 1996 Ian Lance Taylor <ian@cygnus.com> + + * cvs.texinfo (Kerberos authenticated): Change the note that the + Kerberos connection is not encrypted. + (Global options): Add documentation for -x. + * cvsclient.texi (Protocol Notes): Remove enhancement note about + Kerberos encryption. + (Requests): Add documentation for Kerberos-encrypt request. + +Thu Jul 18 18:27:40 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Creating a repository): Mention need to be able to + create lock files in the repository. + + * cvsclient.texi (Responses): In F response, make at least a + minimal attempt to define "flush". + + * cvs.texinfo (Wrappers): Document -k. + (From files, Binary files in imports): Say that imports can deal + with binary files and refer to Wrappers node for details. + (Binary files): Likewise for imports and adds. + +Sat Jul 13 18:29:10 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Binary files): Add paragraph concerning the fact + that the keyword expansion mode is not versioned, and why this is + a problem. + +Fri Jul 12 18:55:06 1996 Ian Lance Taylor <ian@cygnus.com> + + * cvsclient.texi (Requests): Document Gzip-stream. + +Thu Jul 11 21:51:45 1996 Ian Lance Taylor <ian@cygnus.com> + + * cvsclient.texi (Responses): Document new "F" response. + +Wed Jul 10 18:46:39 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (log): Don't document "rlog"; it is deprecated. + +Sat Jul 6 22:07:45 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Environment variables): Document more temp + directory nonsense, this time with "patch". + +Fri Jul 5 23:27:40 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Responses): Add comment regarding "/." ending. + +Fri Sep 13 10:52:09 1996 Greg A. Woods <woods@clapton.seachange.com> + + * cvs.texinfo: don't force afourpaper -- Letter prints much better + on A4 than the other way around, believe you me! + (rdiff options): describe -k and new -K. + (RCS keywords): add description of $Name. + (Using keywords): add description of #ident and example of using + $Name. + - also fixed cross references to Substitution modes in various + places. + (import options): mention that -b 1 imports to the trunk. + +Tue Jul 2 22:40:39 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Sticky tags): Update to reflect change in + "resurrected" message. + +Fri Jun 28 10:48:33 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Connecting via rsh): Add comment about what we + might be saying about troubleshooting. + +Sun Jun 23 10:07:45 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Password authentication security): Add comment + regarding anoncvs as practised by OpenBSD. + +Wed Jun 19 15:41:11 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Administrative files): Add xref to Intro + administrative files. + (Intro administrative files): Add comment suggesting future + reorganizations of this material. + (syntax): Add comment regarding this node. + (Getting Notified): Actually document the notify file. It hadn't + really been documented to speak of. + (editinfo,loginfo,rcsfino,cvsignore): Make the index entries + follow the standard "foo (admin file)" format. + +Fri Jun 14 18:14:32 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (editinfo): Discuss the way editinfo falls down in + the face of -m or -F options to commit, or remote CVS. + +Thu Jun 13 15:08:27 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Watches): Add comment discussing the + fact that using cvs edit instead of chmod is not enforced. + + * cvs.texinfo (Setting up): Add index entry for "init (subcommand)". + (Creating a repository): Move contents of node Setting up here... + (Setting up): ...and remove this node. + (Creating a repository): Don't refer to the INSTALL file (it just + refers back to us!). + + * cvsclient.texi (Responses): Document the fact that the server + should send data only when the client is expecting responses. + +Wed Jun 12 16:04:48 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Entries Lines): Add comment regarding specifying + the meaning of "any other" data, in the conflict field. + (Example): Make it clear that using a separate connection for each + command is not required by the protocol. Add some comments + regarding ways in which the example is out of date or wrong. + +Fri Jun 7 18:02:36 1996 Ian Lance Taylor <ian@cygnus.com> + and Jim Kingdon <kingdon@cyclic.com> + + * cvs.texinfo (annotate): Document new -r, -D, and -f options. + +Fri Jun 7 16:59:47 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Invoking CVS): Add comment describing why only some + commands are listed here. + (Structure, Environment variables): Don't describe CVS as a + front-end to RCS. + +Tue Jun 4 21:19:42 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Responses): Document Created and Update-existing. + +Mon Jun 3 17:01:02 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Responses): Clarify "diff -c" versus "diff -u" + format in Patched response. Don't specify how the client must + implement its patch-applying functionality. + +Sun May 26 17:12:24 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * cvs.texinfo (tag options) Document option "-c". + +Thu May 23 21:11:56 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Credits): Rewrite section on FAQ to reflect the + fact that FAQ is no longer maintained. + (What is CVS?): Mention comp.software.config-mgmt as well as + info-cvs. Mention the fact that info-cvs-request can be slow in + responding. + (What is CVS?): Rather than say that cvs is not a configuration + mangement system, say specifically what it lacks (change control, + etc.). I added process control (which was sorely lacking from the + list of configuration management functionality), and deleted some + functions such as tape construction which are not provided by the + well-known configuration management systems. + + * cvs.texinfo (checkout options): Add comment regarding + subdirectories (lack of clarity pointed out by ian@cygnus.com). + Add comment about that infernal "short as possible" wording. + + * cvs.texinfo (Global options): Fix error ("diff" -> "log") + (reported by ian@cygnus.com). + Remove footnote "Yes, this really should be fixed, and it's being + worked on"--it isn't clear what "this" is, and I doubt anyone is + working on it. + +Tue May 21 17:22:18 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsclient.texi (Requests): Clarify Directory with "." as local + directory, and that filename for Questionable cannot contain "/". + +Mon May 20 13:15:25 1996 Greg A. Woods <woods@most.weird.com> + + * cvs.texinfo (rdiff): description from main.c:cmd_usage + (rtag): description from main.c:cmd_usage + (status): description from main.c:cmd_usage + (tag): description from main.c:cmd_usage + [all for the sake of consistency] + +Fri May 17 11:42:46 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo: Add index entries for :local:, etc. + (Password authentication server): Revert erroneous change + regarding the format of CVSROOT/passwd file. + +Thu May 16 17:06:46 1996 Noel Cragg <noel@gargle.rain.org> + + * cvsclient.texi (Notes): Removed paragraphs about various server + invocations which are now described in full in node "Connection + and Authentication." + (Requests): Include a note that "gzip-file-contents" doesn't + follow the upper/lowercase convention and that unknown reqests + always elicit a response, regardless of capitalization. + + * cvs.texinfo (Kerberos authenticated): Removed bogus version + number. + (Repository): explain the ":local:" access method. + +Wed May 15 23:43:04 1996 Noel Cragg <noel@gargle.rain.org> + + * cvsclient.texi (Goals): mention access methods. + (Requests): add note about convention: requests starting with a + captial letter don't have any expected response. Made sure each + request has a "Response expected" note. + + * cvs.texinfo (Remote repositories): add info about access + methods; fix pserver info. + +Tue May 14 08:56:41 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Environment variables): Try to document somewhat + more accurately where we put temporary files. + + * cvs.texinfo (From files): Say directory tree instead of module + where that is what we mean. Use @var{wdir} and @var{rdir} in the + example instead of using @var{dir} for two different things. + (From files): Say directory tree instead of module + where that is what we mean. + (Binary files): When using cvs admin -kb, one needs an extra + commit step on non-unix systems. + (Binary files in imports): New node. + (Wrappers): Add comment regarding indent example. + (Top): Don't refer to modules when that is not what we mean. + +Fri May 10 09:39:49 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.texinfo (Sticky tags): Explain what sticky dates and + non-branch sticky tags are good for. + + * cvs.texinfo (Repository): Document that -d overrides CVS/Root. + Wed May 1 15:38:26 1996 Jim Kingdon <kingdon@harvey.cyclic.com> * cvs.texinfo (Tags): Document un-revision of all-uppercase tag diff --git a/gnu/usr.bin/cvs/doc/cvsclient.texi b/gnu/usr.bin/cvs/doc/cvsclient.texi index 0d61ac151d9..cb4ad2cd207 100644 --- a/gnu/usr.bin/cvs/doc/cvsclient.texi +++ b/gnu/usr.bin/cvs/doc/cvsclient.texi @@ -80,7 +80,7 @@ that it runs over TCP, UUCP, etc. @item Security and authentication are handled outside this protocol (but see -below about @samp{cvs kserver}). +below about @samp{cvs kserver} and @samp{cvs pserver}). @item This might be a first step towards adding transactions to CVS (i.e. a @@ -109,22 +109,14 @@ client makes it complicated. @chapter Notes on the Current Implementation The client is built in to the normal @code{cvs} program, triggered by a -@code{CVSROOT} variable containing a colon, for example -@code{cygnus.com:/rel/cvsfiles}. +specially-formatted @code{CVSROOT} variable, for example +@code{:server:cygnus.com:/rel/cvsfiles}. The client stores what is stored in checked-out directories (including @file{CVS}). The way these are stored is totally compatible with standard CVS. The server requires no storage other than the repository, which also is totally compatible with standard CVS. -The server is started by @code{cvs server}. There is no particularly -compelling reason for this rather than making it a separate program -which shares a lot of sources with cvs. - -The server can also be started by @code{cvs kserver}, in which case it -does an initial Kerberos authentication on stdin. If the authentication -succeeds, it subsequently runs identically to @code{cvs server}. - The current server implementation can use up huge amounts of memory when transmitting a lot of data over a slow link (i.e. the network is slower than the server can generate the data). There is some @@ -140,10 +132,10 @@ A number of enhancements are possible: @item The @code{Modified} request could be speeded up by sending diffs rather than entire files. The client would need some way to keep the version -of the file which was originally checked out, which would double client -disk space requirements or require coordination with editors (e.g. maybe -it could use emacs numbered backups). This would also allow local -operation of @code{cvs diff} without arguments. +of the file which was originally checked out; probably requiring the use +of "cvs edit" in this case is the most sensible course (the "cvs edit" +could be handled by a package like VC for emacs). This would also allow +local operation of @code{cvs diff} without arguments. @item Have the client keep a copy of some part of the repository. This allows @@ -154,9 +146,6 @@ the latest nightly re-sync, then it would read what it needs to from the master). @item -Provide encryption using kerberos. - -@item The current procedure for @code{cvs update} is highly sub-optimal if there are many modified files. One possible alternative would be to have the client send a first request without the contents of every @@ -175,7 +164,7 @@ Connection and authentication occurs before the CVS protocol itself is started. There are several ways to connect. @table @asis -@item rsh +@item server If the client has a way to execute commands on the server, and provide input to the commands and output from them, then it can connect that way. This could be the usual rsh (port 514) protocol, Kerberos rsh, @@ -245,6 +234,9 @@ shall be silently ignored. @var{version} can be empty, or start with @samp{0} or @samp{-}, for no user file, new user file, or user file to be removed, respectively. +@c FIXME: should distinguish sender and receiver behavior here; the +@c "anything else" and "does not start with" are intended for future +@c expansion, and we should specify a sender behavior. @var{conflict}, if it starts with @samp{+}, indicates that the file had conflicts in it. The rest of @var{conflict} is @samp{=} if the timestamp matches the file, or anything else if it doesn't. If @@ -302,14 +294,20 @@ carefully thought out). @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. + 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. 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 -with @samp{gzip}. The length specified is that of the compressed -version of the file. +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 @@ -318,11 +316,12 @@ compressed form) ends with a newline. @table @code @item Root @var{pathname} \n Response expected: no. Tell the server which @code{CVSROOT} to use. -@var{pathname} must already exist; if creating a new root, use the -@code{init} request, not @code{Root}. @var{pathname} does not include -the hostname of the server, how to access the server, etc.; by the time -the CVS protocol is in use, connection, authentication, etc., are -already taken care of. +Note that @var{pathname} is a local directory and @emph{not} a fully +qualified @code{CVSROOT} variable. @var{pathname} must +already exist; if creating a new root, use the @code{init} request, not +@code{Root}. @var{pathname} does not include the hostname of the +server, how to access the server, etc.; by the time the CVS protocol is +in use, connection, authentication, etc., are already taken care of. @item Valid-responses @var{request-list} \n Response expected: no. @@ -343,14 +342,18 @@ also for @code{ci} and the other commands; normal usage is to send a for the original directory, then the command. @item Directory @var{local-directory} \n -Additional data: @var{repository} \n. This is like @code{Repository}, +Additional data: @var{repository} \n. Response expected: no. +This is like @code{Repository}, but the local name of the directory may differ from the repository name. If the client uses this request, it affects the way the server returns pathnames; see @ref{Responses}. @var{local-directory} is relative to the top level at which the command is occurring (i.e. the last -@code{Directory} or @code{Repository} which is sent before the command). +@code{Directory} or @code{Repository} which is sent before the command); +to indicate that top level, @samp{.} should be send for +@var{local-directory}. @item Max-dotdot @var{level} \n +Response expected: no. Tell the server that @var{level} levels of directories above the directory which @code{Directory} requests are relative to will be needed. For example, if the client is planning to use a @@ -427,6 +430,7 @@ knows what possible files may exist, and thus what files are nonexistent. @item Notify @var{filename} \n +Response expected: no. Tell the server that a @code{edit} or @code{unedit} command has taken place. The server needs to send a @code{Notified} response, but such response is deferred until the next time that the server is sending @@ -447,9 +451,14 @@ rest of the line are ignored. Response expected: no. Additional data: no. Tell the server to check whether @var{filename} should be ignored, and if not, next time the server sends responses, send (in a @code{M} response) @samp{?} followed -by the directory and filename. +by the directory and filename. @var{filename} must not contain +@samp{/}; it needs to be a file in the directory named by the most +recent @code{Directory} request. +@c FIXME: the bit about not containing / is true of most of the +@c requests, but isn't documented and should be. @item Case \n +Response expected: no. Tell the server that filenames should be matched against ignore patterns in a case-insensitive fashion. Note that this does not apply to other comparisons---for example the filenames given in @code{Entry} and @@ -467,6 +476,7 @@ Response expected: no. Append \n followed by text to the current argument being saved. @item Global_option @var{option} \n +Response expected: no. Transmit one of the global options @samp{-q}, @samp{-Q}, @samp{-l}, @samp{-t}, @samp{-r}, or @samp{-n}. @var{option} must be one of those strings, no variations (such as combining of options) are allowed. For @@ -474,7 +484,29 @@ graceful handling of @code{valid-requests}, it is probably better to make new global options separate requests, rather than trying to add them to this request. +@item Gzip-stream @var{level} \n +Response expected: no. +Use zlib (RFC 1950/1951) compression to compress all further communication +between the client and the server. After this request is sent, all +further communication must be compressed. All further data received +from the server will also be compressed. The @var{level} argument +suggests to the server the level of compression that it should apply; it +should be an integer between 1 and 9, inclusive, where a higher number +indicates more compression. + +@item Kerberos-encrypt \n +Response expected: no. +Use Kerberos encryption to encrypt all further communication between the +client and the server. This will only work if the connection was made +over Kerberos in the first place. If both the @code{Gzip-stream} and +the @code{Kerberos-encrypt} requests are used, the +@code{Kerberos-encrypt} request should be used first. This will make +the client and server encrypt the compressed data, as opposed to +compressing the encrypted data. Encrypted data is generally +incompressible. + @item Set @var{variable}=@var{value} \n +Response expected: no. Set a user variable @var{variable} to @var{value}. @item expand-modules \n @@ -510,8 +542,9 @@ specify a log message. @itemx init @var{root-name} \n Response expected: yes. If it doesn't already exist, create a @sc{cvs} -repository @var{root-name}. The @code{Root} request need not have been -previously sent. +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 Response expected: yes. Actually do a @code{cvs update} command. This @@ -555,16 +588,21 @@ expecting a response) sends back any responses pertaining to pending errors, pending @code{Notified} responses, etc. @item update-patches \n +Response expected: yes. This request does not actually do anything. It is used as a signal that the server is able to generate patches when given an @code{update} request. The client must issue the @code{-u} argument to @code{update} in order to receive patches. @item gzip-file-contents @var{level} \n -This request asks the server to filter files it sends to the client -through the @samp{gzip} program, using the specified level of -compression. If this request is not made, the server must not do any -compression. +Response expected: no. Note that this request does not follow the +response convention stated above. @code{Gzip-stream} is suggested +instead of @code{gzip-file-contents} as it gives better compression; the +only reason to implement the latter is to provide compression with +@sc{cvs} 1.8 and earlier. The @code{gzip-file-contents} request asks +the server to compress files it sends to the client using @code{gzip} +(RFC1952/1951) compression, using the specified level of compression. +If this request is not made, the server must not compress files. This is only a hint to the server. It may still decide (for example, in the case of very small files, or files that already appear to be @@ -589,17 +627,23 @@ When the client is done, it drops the connection. @section Responses After a command which expects a response, the server sends however many -of the following responses are appropriate. Pathnames are of the actual -files operated on (i.e. they do not contain @samp{,v} endings), and are -suitable for use in a subsequent @code{Repository} request. However, if -the client has used the @code{Directory} request, then it is instead 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 name (the pathname which is sent if -@code{Directory} is not used). Then the slash and the filename. For -example, for a file @file{i386.mh} which is in the local directory -@file{gas.clean/config} and for which the repository is -@file{/rel/cvsfiles/devo/gas/config}: +of the following responses are appropriate. The server should not send +data at other times (the current implementation may violate this +principle in a few minor places, where the server is printing an error +message and exiting---this should be investigated further). + +@c FIXME: should better document when the specified repository needs to +@c end in "/.". +Pathnames are of the actual files operated on (i.e. they do not contain +@samp{,v} endings), and are suitable for use in a subsequent +@code{Repository} request. However, if the client has used the +@code{Directory} request, then it is instead 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 +name (the pathname which is sent if @code{Directory} is not used). Then +the slash and the filename. For example, for a file @file{i386.mh} +which is in the local directory @file{gas.clean/config} and for which +the repository is @file{/rel/cvsfiles/devo/gas/config}: @example gas.clean/config/ @@ -631,7 +675,27 @@ new copy of the file is enclosed. This is used for a new revision of an existing file, or for a new file, or for any other case in which the local (client-side) copy of the file needs to be updated, and after being updated it will be up to date. If any directory in pathname does -not exist, create it. +not exist, create it. This response is not used if @code{Created} and +@code{Update-existing} are supported. + +@item Created @var{pathname} \n +This is just like @code{Updated} and takes the same additional data, but +is used only if no @code{Entry}, @code{Modified}, or +@code{Unchanged} request has been sent for the file in question. The +distinction between @code{Created} and @code{Update-existing} is so +that the client can give an error message in several cases: (1) there is +a file in the working directory, but not one for which @code{Entry}, +@code{Modified}, or @code{Unchanged} was sent (for example, a file which +was ignored, or a file for which @code{Questionable} was sent), (2) +there is a file in the working directory whose name differs from the one +mentioned in @code{Created} in ways that the client is unable to use to +distinguish files. For example, the client is case-insensitive and the +names differ only in case. + +@item Update-existing @var{pathname} \n +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. @item Merged @var{pathname} \n This is just like @code{Updated} and takes the same additional data, @@ -642,11 +706,13 @@ or without conflicts. @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, -the server sends a patch produced by @samp{diff -u}. This client must -apply this patch, using the @samp{patch} program, to the existing file. -This will only be used when the client has an exact copy of an earlier -revision of a file. This response is only used if the @code{update} -command is given the @samp{-u} argument. +the server sends a patch. This patch is produced by @samp{diff -c} for +@sc{cvs} 1.6 and later (see POSIX.2 for a description of this format), +or @samp{diff -u} for previous versions of @sc{cvs}; clients are +encouraged to accept either format. The client must apply this patch to +the existing file. This will only be used when the client has an exact +copy of an earlier revision of a file. This response is only used if +the @code{update} command is given the @samp{-u} argument. @item Mode @var{mode} \n This @var{mode} applies to the next file mentioned in @@ -738,6 +804,14 @@ A one-line message for the user. @item E @var{text} \n Same as @code{M} but send to stderr not stdout. +@item F \n +@c FIXME: The second sentence, defining "flush", is somewhat off the top +@c of my head. Is there some text we can steal from ANSI C or someplace +@c which is more carefully thought out? +Flush stderr. That is, make it possible for the user to see what has +been written to stderr (it is up to the implementation to decide exactly +how far it should go to ensure this). + @item error @var{errno-code} @samp{ } @var{text} \n The command completed with an error. @var{errno-code} is a symbolic error code (e.g. @code{ENOENT}); if the server doesn't support this @@ -753,6 +827,10 @@ The command completed successfully. @node Example @section Example +@c FIXME: Use Directory, not Repository! +@c FIXME-less-important: Use Created and Update-existing, not Updated. +@c FIXME: the presence of timestamps in the entries lines is not right. + Lines beginning with @samp{c>} are sent by the client; lines beginning with @samp{s>} are sent by the server; lines beginning with @samp{#} are not part of the actual exchange. @@ -778,8 +856,9 @@ s> 28 s> foo: foo.c s> $(CC) -o foo $< s> ok -# In actual practice the next part would be a separate connection. -# Here it is shown as part of the same one. +# The current implementation would break the connection here and make a +# new connection for the next command. However, the protocol allows it +# to keep the connection open and continue, which is what we show here. c> Repository /rel/cvsfiles/devo/foo # foo.c relative to devo/foo just set as Repository. c> Entry /foo.c/1.4/Mon Apr 19 15:36:47 1993 Mon Apr 19 15:36:47 1993// diff --git a/gnu/usr.bin/cvs/lib/ChangeLog b/gnu/usr.bin/cvs/lib/ChangeLog index 900d6d4d1ae..6772cc6aa94 100644 --- a/gnu/usr.bin/cvs/lib/ChangeLog +++ b/gnu/usr.bin/cvs/lib/ChangeLog @@ -1,3 +1,63 @@ +Wed Oct 2 10:43:35 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * getdate.y: removed CVSid variable + + * getdate.c: regenerated (using byacc 1.9) + +Wed Sep 25 10:25:00 1996 Larry Jones <larry.jones@sdrc.com> + + * vasprintf.c: Fix type clashes in calls to strtoul. + +Wed Sep 11 15:55:31 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * build_lib.com: Add valloc.c. + +Tue Sep 10 23:04:34 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (DISTFILES): Add build_lib.com. + +Fri Aug 16 16:01:57 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * Makefile.in (installdirs): new (empty) target + +Mon Aug 12 11:03:43 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * system.h: Don't use #elif. It is said to cause problems with + one of the HP compilers on HPUX 9.01. + +Sun Jul 7 23:25:46 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * memmove.c: Removed. The memove function was used by a very old + version of the CVS server for nefarious purposes and it has been + long gone. + * Makefile.in (SOURCES): Remove memmove.c. + +Thu Jun 6 15:12:59 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * vasprintf.c: If STDC_HEADERS, include stdlib.h rather than + declaring its functions ourself. + +Wed Jun 05 10:14:29 1996 Mike Ladwig <mike@twinpeaks.prc.com> + and Jim Kingdon <kingdon@cyclic.com> + + * system.h: If ERRNO_H_MISSING is defined, don't include errno.h. + +Wed Jun 05 10:14:29 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * regex.c: Don't define MAX and MIN if already defined. + +Sun May 12 09:40:08 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * getdate.y: Replace alloca.h include with a comment explaining + why we avoid alloca and the consequences of that. + * getdate.c: Regenerated. + +Wed May 8 09:31:03 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * getdate.c: Regenerate with the version of byacc in Red Hat 3.0.3 + (which I believe is byacc 1.9). byacc, unlike bison, does not + require alloca in the generated parser. + Thu Apr 25 18:26:34 1996 Jim Kingdon <kingdon@harvey.cyclic.com> * getdate.y (get_date): Set Start from nowtime, not now->time, diff --git a/gnu/usr.bin/cvs/lib/build_lib.com b/gnu/usr.bin/cvs/lib/build_lib.com new file mode 100644 index 00000000000..0b808e59d9b --- /dev/null +++ b/gnu/usr.bin/cvs/lib/build_lib.com @@ -0,0 +1,19 @@ +$ CC :== CC/DEBUG/NOOPTIMIZE/STANDARD=VAXC/DEFINE=HAVE_CONFIG_H- +/INCLUDE_DIRECTORY=([-],[-.LIB],[-.SRC],[-.VMS])/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES +$ CC fnmatch.c +$ CC getdate.c +$ CC getline.c +$ CC getopt.c +$ CC getopt1.c +$ CC md5.c +$ CC regex.c +$ CC savecwd.c +$ CC sighandle.c +$ CC strippath.c +$ CC stripslash.c +$ CC valloc.c +$ CC xgetwd.c +$ CC yesno.c +$ library/create gnulib.olb fnmatch.obj,getdate.obj,getline.obj,- +getopt.obj,getopt1.obj,md5.obj,regex.obj,savecwd.obj,sighandle.obj,- +strippath.obj,stripslash.obj,valloc.obj,xgetwd.obj,yesno.obj diff --git a/gnu/usr.bin/cvs/lib/regex.c b/gnu/usr.bin/cvs/lib/regex.c index 03fc721f38d..2f590d64b90 100644 --- a/gnu/usr.bin/cvs/lib/regex.c +++ b/gnu/usr.bin/cvs/lib/regex.c @@ -234,8 +234,13 @@ char *alloca (); #define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) +/* The Mac CodeWarrier9 compiler defines MAX and MIN. */ +#ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif typedef char boolean; #define false 0 diff --git a/gnu/usr.bin/cvs/lib/system.h b/gnu/usr.bin/cvs/lib/system.h index 363124dcb47..cff72cdc55c 100644 --- a/gnu/usr.bin/cvs/lib/system.h +++ b/gnu/usr.bin/cvs/lib/system.h @@ -270,18 +270,20 @@ extern long timezone; check for struct utimbuf, but for now I'm checking NeXT here (so I don't have to debug the configure check across all the machines). */ #if defined (HAVE_UTIME_H) && !defined (NeXT) -#include <utime.h> -#elif defined (HAVE_SYS_UTIME_H) -# include <sys/utime.h> +# include <utime.h> #else -#ifndef ALTOS +# if defined (HAVE_SYS_UTIME_H) +# include <sys/utime.h> +# else +# ifndef ALTOS struct utimbuf { long actime; long modtime; }; -#endif +# endif int utime (); +# endif #endif #if STDC_HEADERS || HAVE_STRING_H @@ -295,7 +297,9 @@ int utime (); /* memory.h and strings.h conflict on some systems. */ #endif /* not STDC_HEADERS and not HAVE_STRING_H */ +#ifndef ERRNO_H_MISSING #include <errno.h> +#endif /* Not all systems set the same error code on a non-existent-file error. This tries to ask the question somewhat portably. @@ -422,14 +426,55 @@ char *getwd (); #define S_IWOTH 0000002 /* write permission, other */ #endif -/* Under MS-DOS and its derivatives (like Windows NT), mkdir takes only one - argument; permission is handled very differently on those systems than in - in Unix. So we leave such systems a hook on which they can hang their - own definitions. */ +/* Under non-UNIX operating systems (MS-DOS, WinNT, MacOS), many filesystem + calls take only one argument; permission is handled very differently on + those systems than in Unix. So we leave such systems a hook on which they + can hang their own definitions. */ + +#ifndef CVS_ACCESS +#define CVS_ACCESS access +#endif + +#ifndef CVS_CHDIR +#define CVS_CHDIR chdir +#endif + +#ifndef CVS_CREAT +#define CVS_CREAT creat +#endif + +#ifndef CVS_FOPEN +#define CVS_FOPEN fopen +#endif + #ifndef CVS_MKDIR #define CVS_MKDIR mkdir #endif +#ifndef CVS_OPEN +#define CVS_OPEN open +#endif + +#ifndef CVS_OPENDIR +#define CVS_OPENDIR opendir +#endif + +#ifndef CVS_RENAME +#define CVS_RENAME rename +#endif + +#ifndef CVS_RMDIR +#define CVS_RMDIR rmdir +#endif + +#ifndef CVS_STAT +#define CVS_STAT stat +#endif + +#ifndef CVS_UNLINK +#define CVS_UNLINK unlink +#endif + /* Some file systems are case-insensitive. If FOLD_FN_CHAR is #defined, it maps the character C onto its "canonical" form. In a case-insensitive system, it would map all alphanumeric characters diff --git a/gnu/usr.bin/cvs/macintosh/AE_example.pl b/gnu/usr.bin/cvs/macintosh/AE_example.pl new file mode 100644 index 00000000000..4fa4ccf69e9 --- /dev/null +++ b/gnu/usr.bin/cvs/macintosh/AE_example.pl @@ -0,0 +1,95 @@ +# +# This fragment illustrates how to invoke MacCVS via AppleEvents and pass environment +# variables to MacCVS. Not all CVS environment variables make sense for MacOS. This +# fragment also illustrates the default result handling mode, which is to put the info on +# a SIOUX console. +# + +&MacPerl'DoAppleScript(<<ENDIT); +tell application "Data:Mike:Projects:cvs-1.8.6:macintosh:MacCVS" + do script { "status" } environment { "CVSROOT", "ladwig\@manic:/projects/sdt/repository/eM2" } +end tell +ENDIT + +exit(0); + + + +# +# This fragment illustrates how to invoke MacCVS change its directory prior to executing +# the CVS command. This is akin to being in a directory when you invoke CVS. +# + +&MacPerl'DoAppleScript(<<ENDIT); +tell application "Data:Mike:Projects:cvs-1.8.6:macintosh:MacCVS" + do script { "status" } environment { "CVSROOT", "ladwig\@manic:/projects/sdt/repository/eM2" } pathway "OS:Workspace:eM:src:daemon" +end tell +ENDIT + +exit(0); + + + +# +# This fragment illustrates how to get MacCVS to return results via AppleEvents. +# Note: If you add "NoLineBuffer True" after the "Mode AE", each individual line +# of results will be returned in a separate AppleEvent. +# + +use Mac::AppleEvents; + +AEInstallEventHandler("MCVS", "DATA", "MacCVSData", 0); + +&MacPerl'DoAppleScript(<<ENDIT); +tell application "Data:Mike:Projects:cvs-1.8.6:macintosh:MacCVS.PPC" + do script { "-help add" } environment { "CVSROOT", "ladwig\@manic:/projects/sdt/repository/sdt" } Mode AE +end tell +ENDIT + +$done = 0; +$in = 0; +while( $done = 0 ) { sleep(1);} +print "QUITTING!\n"; + +AERemoveEventHandler ("MCVS", "DATA"); +exit(0); + +sub MacCVSData { + my($event) = @_; + + print "**** MCVS/Data Handler called\n"; + + $rDesc = AEGetParamDesc($event, "----"); + if( $rDesc ) + { + $data = AEPrint($rDesc); + chop $data; $data = substr($data, 1); + print "---- data = <$data> \n"; + } + AEDisposeDesc($rDesc); + + $rDesc = AEGetParamDesc($event, "DONE"); + if( $rDesc ) + { print "!!!! DONE\n"; $done = 1; AEDisposeDesc($rDesc); } + + print "Exiting MCVS/Data Handler ****\n"; + return 0; +} + + + + + +# +# This fragment illustrates how to have MacCVS save the results to a file in your MacOS +# filesystem. +# + +&MacPerl'DoAppleScript(<<ENDIT); +tell application "Data:Projects:cvs-1.8.6:macintosh:MacCVS" + do script { "-d ladwig\@manic:/projects/sdt/repository/eM2", "status" } mode file filename "os:out.file" +end tell +ENDIT + +exit(0); + diff --git a/gnu/usr.bin/cvs/macintosh/ChangeLog b/gnu/usr.bin/cvs/macintosh/ChangeLog new file mode 100644 index 00000000000..22c25d6cfdf --- /dev/null +++ b/gnu/usr.bin/cvs/macintosh/ChangeLog @@ -0,0 +1,190 @@ +Mon Sept 30 13:17:07 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * ae_if.c (DoScript): Fixed bug cutting off the last character of + the path in the 'SPWD' AE Parameter. + +Tue Sep 24 14:39:40 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * options.h: Add TMPDIR_DFLT. + +Wed Sep 4 13:40:35 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (Makefile): New rule. + +Mon Aug 26 12:46:10 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (mkdir_if_needed): Added. + +Fri Aug 16 16:04:26 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * Makefile.in (installdirs): new (empty) target + +Wed Aug 14 12:01:39 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * MacCVS68k.sit.hqx, MacCVSPPC.sit.hqx: New copies of these files + from Mike Ladwig (gets rid of alloca.c; presumably adds + mac_config.h; not sure if there are other changes). + +Tue Aug 13 15:02:15 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * ae_if.c: Part of the 9 Aug change didn't get checked in. Fix it. + +Fri Aug 9 14:53:01 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * ae_if.c: Include 'mac_config.h" to get macintosh configuration + values. Reworked application I/O code (many routines) to make + MacCVS either a "pure" faceless application (AE or file output) _OR_ + a SIOUX console application. This decision is made at compilation + time by defining (or not) AE_IO_HANDLERS. + * mac_config.h: Added, moving many configuration parameters from the + maccvs.pch header file here. This makes it possible to change + macintosh build -specific parameters without recompiling all CVS and + Mac port code. + * mac_init.c: Include 'mac_config.h" to get macintosh configuration + values. Removed unnecessary toolbox initialization code. Made + AE/Console choice at buildtime. + * maccvs.pch: Moved most configuration parmeters to 'mac_config.h" + * filesubr.c, macos_filesys.c, pwd.c, rcmd.c, run.c server_if.c: + Include 'mac_config.h" to get macintosh configuration values. + +Wed Jul 31 11:41:55 1996 Mike Ladwig <mike@twinpeaks.prc.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * server_if.c (macos_start_server): If getservbyname returns NULL, + use port 514 rather than giving an error. + +Wed Jul 31 11:41:55 1996 Mike Ladwig <mike@twinpeaks.prc.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (DISTFILES): Add maccvs.r. + +Mon Jul 29 14:48:45 1996 Jim Blandy <jimb@totoro.cyclic.com> + + * Makefile.in (DISTFILES): Fix capitalization of MacCVS68k.sit.hqx. + +Fri Jul 26 16:17:48 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * README.MacCVS: Change CVS version number from 1.86 to 1.8.6. + They are not the same and the latter is what is intended. + + * run.c: Remove Popen; it has been replaced by run_popen. + + * options.h: Remove RM and SORT; CVS no longer uses them (this + restores some changes which were wiped out by Ladwig's 26 Jul 96 + submission). + + * config.h: Remove alloca cruft. CVS no longer uses alloca. + * Makefile.in (SOURCES): Remove alloca.c. + * alloca.c: Removed. + +Fri Jul 26 16:17:48 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * server_if.c: Revert to version before Ladwig's 26 Jul 96 + submission. In particular, this is to pick up the following + changes: + + Tue Mar 19 17:51:52 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * server_if.c (macos_start_server): Added support for + CVS_RCMD_PORT (and thus made consistent with WindowsNT and VMS) + + Wed Feb 28 11:31:11 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * server_if.c (macos_start_server): Don't use alloca. + +Fri Jul 26 16:17:48 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (HEADERS): Remove SIOUX*.h. + (SOURCES): Remove SIOUX.c. These files are copyright by + metrowerks and therefore we cannot distribute them. + +Fri Jul 19 14:23:01 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * Added support for zlib (and Gzip-stream compression) to both the PPC and + 68k ports. + +Mon Jul 15 11:53:41 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * For the 68k port, setup memory allocation differently in order to keep the + heap and stack from colliding in large recursive operations. The 68k and PPC + versions now both allocate 128k to the stack. + +Tues Jun 25 09:26:32 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * Removed the requirement for the 'services' file; it only needs to be there + if you want to use a non-standard port. + +Mon Jun 24 10:12:17 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * Fixed bug in NoLineBuffer that sent an AE for every character in certain CVS + modes (e.g. help). + * Fixed bug in 68K port that didn't set the HLE flag in the size resource + +Thurs Jun 7 18:11:43 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * MacCVS fixes inserted into the "mainstream" CVS sources - thanks, Jim! + * Fixed bug with reading log information from a file + +Thurs Jun 6 16:09:03 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * Improved MacCVS builds by moving the maccvs.rsrc information to maccvs.r + * Fixed bug where MacCVS would crash if an error was encountered and + output was going to AppleEvents or a file + +Thurs Jun 6 12:38:54 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * Fixed bug keeping CRLF conversion code from getting called + * Modified "file results" code to use an intermediate file, and to + rename that file to the requested filename when complete. + +Tue Jun 4 13:58:01 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * CVS Code base updated to cvs-1.8.2 (5/27/96 snapshot) + * Updated to CodeWarrier 9. The SIOUX redirection stuff is broken under + CW9. Using MSL seems promising, but MSL's ccommand is broken. + * Redid the 680x0 port. + +Fri May 16 14:54:21 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * CVS Code base updated to cvs-1.8.2 (5/16/96 snapshot) + * Bugs in macos_filesys.c related to relative pathnames fixed + +Fri May 1 15:58:41 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * Added AppleEvents support (undocumented) + +Fri Feb 9 11:26:32 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * CVS Code base updated to cvs-1.7 + +Wed Jan 10 11:40:32 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * CVS Code base updated to cvs-1.6.5 1/8/95 snapshot + +Fri Dec 27 14:20:12 1995 Mike Ladwig <mike@twinpeaks.prc.com> + + * Cleanup of rcmd code, removing inappropriate tests + * CVS Code base updated to cvs-1.6.3 12/27/95 snapshot + * Again fixed(?) binary/text file handling. + * OT problem traced to GUSI - OT bug. Corresponding with Matthias. + +Fri Dec 08 12:39:22 1995 Mike Ladwig <mike@twinpeaks.prc.com> + + * Fixed problem with 'stat' emulation + * Used better GUSI resource template so file type/creator was available + +Thurs Dec 07 16:13:09 1995 Mike Ladwig <mike@twinpeaks.prc.com> + + * Port cleanup for inclusion into main cvs distribution + * Fixed(?) binary file handling + * Better SIOUX feedback + * Updates only via whole files (no '-u' to update) + +Wed Nov 29 09:33:16 1995 Mike Ladwig <mike@twinpeaks.prc.com> + + * Initial port of CVS 1.6.1 snapshot 11/14/95 + * Requires CW GUSI 1.6.4 and CodeWarrier 7 + * 68k version is essentially untested, due to lack of a 68k machine + * 'release' doesn't work, due to cvs implementation approach + * Tons of obvious "TODOs", but at least the heavy stuff is done + diff --git a/gnu/usr.bin/cvs/macintosh/MacCVS68k.sit.hqx b/gnu/usr.bin/cvs/macintosh/MacCVS68k.sit.hqx new file mode 100644 index 00000000000..7b260948dac --- /dev/null +++ b/gnu/usr.bin/cvs/macintosh/MacCVS68k.sit.hqx @@ -0,0 +1,179 @@ +(This file must be converted with BinHex 4.0) +:%%eKBd0@8bif1'XZY5jcDA3!8dP84&0*9#%!N!3K%!#3"'Zc8dP8)3!"!!!K%(* +-BA8#r`#3!aErr`d0$%eKBd0@8bif1'XZY9"`&!"$UBS!N!1!!*!%!eJmC#D(!*! +Drj!%68e38N0A588"!+dX5cQZ-2[8!!!ZC`!!fMB!!!Sj!!!@86j(Rqm!N!BBS`h +!q#r,DmdZ"d8h*I5ikfCRYfPRC'8VMpfQK2*edcVk-Spl[TZYc1GkfjL%DE*e-if +[qAZe,MR0c3JMR"c[k(kk'D(E#0Z%FR+F((-cXJNEE'N4YSr`YpJqZNp#YjIZCdF +fhBb`*)cXBa(ZEF)MarB46MCKj$Nj&Me#Yb[`eAGpYeN1cH0Vj2DaFe01EKmMqmK +S(pN[RQaJ[!%"D'BA!!F!f5X"&Z%Tc%%3+SZU+c9'Rk1H`!ZKXpSGPV89aTcF4ih +2'hLmBEADbLe9UiSi#'+mKbZa9IlIYlMdIS"Ij3!B0a+I+S0PL58lfe#GLeFZ"Q@ +PHJK'[q25p9$-3"j9,Nqjj9B5$)h4lDSlIb8@0+3"TF#J!8i1`RQ)BVH'8f"NAX# +[4b))Q%K!PBhNkm3EYr2I#KjCa+S!X&#LK#S5C6GkQ`*M@I+CKZ3IqIpKVT1,i6H +2jPN@UXcY1LYCNK&Cc,r'03Y$i!CB@J)3EmGl*Y"52e(5"B-KIGiE9YC66`%m'+5 +2AD'+aQLYASrGi4e[#C!!"E&F(lmep(qT1#PY%*@![@peK5%RYp43j[)mk[4IC#* +RX0NXec+N&GKXC4p+Y4E2!Tm2pD%'`-0U,5Z-j0'AZHS-UaTpARq!5RXPKp9@9U` +5`+2+XN)GS+lP&C0@i#mm*1p49qrilSami,qr%QDr!29"rM'Hm+5Mr8(J1h5&GVI +Ekr8B9MVG2Xb*Gr[ap0&pBDQTQlJ3$piiEQ''[G"eG5MHc*'GV3V!3c!kaJ[b!3m +UZcT!AAfhL%ccF,B`(YcaBpd0h3h`EG1,SdR+RDdA%lqaq5cllcl6%pEVC3FmABq +%%)paH8!FmV$C4BIGIE1`XLHhLfS"2+jiqkQk+TjF5cc'1Y%8$plSpl*'&0EVbb0 +jK('pRQ`2ke8Flp0D,%1"f-Mk01@mh+HV,DXRI8`#*5QHF$)E[)kQ#)p)N!$rm)X +6FimT(Q+pqm,Bilh3fiVHVbVb#$5T"2#Jd"K4*IqZUifd'2(N+L#1'dYl*FGGahf +$KfU!iejG@'+BV)I99K@TKpU(FlpHeE[1IB,(Y(1Ij(((Z8r@pBjcMr!)1rHrL[d +rc[eU2IlTh'm8pZr12F,MMR1r5Z-IcRf#KhU!FpFB4HG'863ahHZh2"I+&IZ%e!H +3!%H*[CNQ`D(J-Nj,i[ceFMD)9[p`h,K4F5A(AFGpR3H&5S$MaM@,T4mhY16QA(2 +F-Apc6&Ih2X+GBFSa6I#BGMU6pEMMG#)mTMVja&l-G#GAFGL[1GqTKLF5f%,'H(M +V'Qla@&hA%1%aNbc$Y5E&)Sl0KSbY,Pr'kC[Hie+-H)r3E%J9J)I&,BTJG,MYBei +S'T9id`[GTk0I0Y04"DJ(Qm@S!["3CM&Xp[+r@8b8X3'VIl-HIpD(l&eG[M'GNAH +0m(KNPFh`S6lSPhPA93#G-HqU#X#$3UX+d)HN6Ui'S!rd(eQiTHI'A5hDeH-iXcN +pP'cSQEGJb0Z!j`r`2!C$5mUiHErY![MQA%MDXhr-4+JiK,3CbCETEJ5ViG#"-f( +mG(FQD1EQGap[iGB!Tc@Ed@UCcAc[Z5`m1r#d8Dq%P&HUki2RmX2iUj@c+k&d4a[ +I5lKP49%aP`2FB3b&'prlMJlcqD#djK&)q@QZG1IF9TBrBlZ#RcTA"k8`QpX$4BH +kG&XN2RK[Mjbr2aK-ANEmq5mr5Icl&Ik-C+pZ#m0R&"Z!ImG0I2Mf@DRm%qY`me6 +U#(MUq(DpKQq2DmGr(prqRAjF#P`QekJ@CI-6aKr[F%0-!pMac'DU+8N%-P,UT*S +-S#B'8"-$YYFaU#Df6#JPA+N*Pd-+'0(!`"#HYINlN!"(5!-$c(mJa,B#qGl"Ce% +2+m+D'$Jef-TiGFRjAe)dL"UJ1XMiUjAm$c(KZV1-6kMQT!RL)H2%KfRJ+f[5830 +jI([mXI-D',5&0&#kSjpkBE6Ch%U03(McGl@J2G`5l2[5!m'q,lEKZC0XM2$QllF +KPKlXqpUlH"jPrDI2N!!Fl2YP@bCef36q3'iRIq$q3PJM#*Nq38K+$IEp`XFIqCa +0f,A[&0h"A0XJZZXX(2ad[b$--T'Q+$$r'Y$X`V(3Mr0dAKUE8PrE@IXZ,3EcFfS +a9cHr-A8ZT1h9)AB)V')qRU&p$%(ib$H%[I9RK,fZ4PEI)mY6q50j0[j)mdX-2f4 +pQR3Y#)QTQ+X6S#FCFmc!-`&2$CikVK+i4$2fJ+U((UjBCACj(1kQ$Fk,H%Mhm@d +U$,d`i9qpF"EfJF4Dl!-Gild3Vm5ET9@BLLBI68A-+LbH#2f!2Y`(F-jN0MX#iJJ +qkJIdbHS,IZ$VqbrkJ4U6kEBIb1R#(P#0RZMYF6q3!$HU!HD0)#114ikRZ*jGpAJ +HaV06d8"8,T356[F[Di$VfCf(plY(0)$iITC2eJ$Qq!0NG,b0*p-PiSEG"aQ[%e, +qh5$aHk@DDaRdKA(N5aXE0GXCIbi3Jrd*SdI5J))6(p)!ekSpc$Ark$QZ05U6fl6 +H"($2ir,pcV!'pU0[i(@J9DISF+S,`DN#[$'J&K,*S%&$bY3J[4SJ#b1@2FZ!*m2 +e%)d)1q3-,e-IL3frH,&`)CkP4V35(j!!Em6NdJjLe-PUjQVr'`pLK-!UH)ZEaEG +4Y6kk#!IDLA3TkZ5&P-YJKSc%1TT&A"M!BTEH@-3+4bbq-4&Z*mIT(BXrY4JeS&L +rAJcBrEFHh9!r#-j%6hRJfamiU&@ld5V0qdX+eKBJP+bmkU,B"cR)8i4[SB2S8`I +T%-RX&4`eQMK)R90(`jCLPpYCk43$aZGY&R+)`aD4(*[N!!@FN!$35@-ZG3!['*( +YX&HN9hTiIM-eTHdi8hhXm`JBQErM4ecHqi6`E559'0e,LKPp1HVm1eU#CqH*P%r +KPA6Z"H"pIZGR)325I'YT%iel[++bI"lqEp--6f+MH)M$AceKpld)mr%hNc"(#h` +#IpQmce%%Y+ZrMV!eIf6VQ'bc,5N12S0mf03V23[`A5fFLQ1N[3'E%1XJc2SXI!' +aEa%@EB'[)RD#X*UI`j0Bd!@%a5`"I%2TRPf%jEB!rXpKq`)"%qc$#F0[#%Zd`[F +3'b3XhJBr!jM,TJY@2lb'@"VVH&[J0')XAq"T`(hIHHaHG4rJM(GH&Z0pP1SeRbQ +TaXdP!5aJDhaY24bq3VD!Y!1cjk-hK3@XhJm8Fjm%q"M64-2V(#iLCZ849VkE@id +BUdIc-acQ@VLB#HS3cC-AQ@9jTH"j,`(#@AD2k8PRmhXER)k!`HS5(G'&IZmQdHQ +29bkK@%@Aea-[EfCAfIdHPfHMU'GlN!!'LlI4KchI2j-fB5hH$Fk(R*lBm&BXZbB +c84JS+I8+`k+@J0mZDSXfZ!*H[kEBk`PS+qhqMFk!VX$KF)SL,S8(k[%q5c16(VQ +3!)NQ%,E#*H+#PV1a$LR&KPr!B(PNKRTTpc0%A)+95QSYa9C-TQ0lNR,'QI4iPF+ +5X&'@iCHYSJR#Y@1@6mkYNajB`DTjR'iGlXq&L2mI!*!$$X$i@$TXd-$Vc2`Z&Z9 +HAV4a)pr,kr2Xj%FE0,#M'dmpkFYG*aarACGY"jDGCjBAffalRB1mc*([@DAAT22 +-2JH,,R`jIS[T`TH"&bHr%"lK4rJ92mYC+A!A-&jkhIVX1Y8qVRKQRlG)&R*m)C2 +GNB8-1!3J%*JH(RJ&kVcXFJH$2J"3m2p!J(rm*Ijr&A19q2mJr0N`b),4i)*KH4@ +UHel9N!$+S"iH8K@-k'i0m[!2FPG"'H3M'SA,KAL!H+8,U`KS*[lU2[c06$LGm'E +[`-YRH(1m0EUU0fN'abZ%!B4hj!kmh(-XY)mq!1M4!hmc"2rJS6H`BdI[`#ZBXD" +UPJ8*VNhiQpliCpEAT`d2Hmh`"[DTDM,#QTm3[CV4$V%YA2crIr@$8D[5YIUP%#B ++a1p@rqfpVY8[V+)dr[l[TZ*[0[0Xd36mlId[i1rISYq2GUeqmB92R[bRGCmmqFm +&RccjqhpM[bFH!qDhQ,qam(Um3[@#Dq@UYq"+Z+Hp&JA+RQ0mEq[4[0PqV"daAr` +kiGr'm&dVqNehVHJc%Q!NpN[Jimp"QBTU89$"@9D-4#LH1,QGj#+LcC0djE++bMR +P,!1ZUFL6bFrPFQdTpRPV1LJ@hE$j"N,&$24JU*0FKD@9[SM"rRFJ4cGXQQZKETS +,"c(8L5mA9XfDYq!XeKl@TNp40cjc++&L"RSbe"0lp+ZF8aA@[B'kmNM!E46Aq5, +DYU,AhP4a1D*@c#PK'FMLIIe0[`SeA)p9BV&$KShhMTVX'EkYD1cQfk+[Ed1f@@[ +HI*4NK$'+Jc[Cd$+VF,1bI&l*k80B"R)ikX$XFUp2-iVVECPU1AVjCPJq[qbXq6b +65kMcQd+GU0(SJ,8Q+XrN68Ae+TL6ir(U@L#FJQeqrZR&*LV2j,0D6aQ4EB3phQ# +QeLQYIk"D@DE!V$@leKd)qp+Sc4m1HC0UCCP#%cAID$*'DESH50EEr2a6EeNG`N` +[Xd-jf#&NGDVBH)GkQl8@X&SM!5q#ld4ZI[kC`keD-G1R[80ZMeDEC"mbClhJd(V +Sba@Pj*!!DA1VCT@V+#E$5cr6X1L'e`j9PTZ+mYUKF,#*fTp3jijLZ#0'**!!SaY +lh%@SQ)&$fMX86ZY$miG($lDBKjP$fe%cR'hT1E!rk4$,(%EDi'D&IUi0E`[Q[3h +p605XX0HI!8h`YEpJ192b!b`rR%ei[G8m[qTf0aM&)AF(EQ[4Q"N+4f8C1-*N3bp +%VIF'Y&&U`2"q@[(D,5pFDYE+-`0-e0i@DT*pDdjVq,@*bM0(%SHD'P4ITjC[q2Y +Ce&H@'8KDlJlk3fTDbe[k$[dAiL[,(0A1FQr3EE1mZ93pM,5"C3DCU(N-e3LRUQf +jjFCDUT9P"TXcbL'P`B$('rB'!kS2"d8p'1paG2#@UG4APKPLSZD80H#)NUC$(29 +S%cArM)MA[F5MUie*pDSC3+JmF`bK9RLADTk+S#FT4Y'Ua64lmFcA606HSYEjfY* +2+4'If)DDU,RcUKD%[@QH4cImqQ5,jCJjPYK3SIQ$HP1DjE&DLkL[dd)KRcCIp5e +*XL''HTb*fUYdIJPV%9*fjqJ34ae'IChZ9Ah"ZP4IikM$,CEVHP$r6jBI6e0[K4C +!eq$!V$c#4-e$(3VV`46eiUJMUDq,[!&2X$(GejLLR%#e-NNS3pAlSYCLBPj9@!e +i90h$[)"ZjSfL@LY9pa+e,Q8$a&&(QkJ&PC@Pc+JS#5lGL4Y((G-q!@5Q0Tb3!(2 +&V*`,BpXRE#2SAU*em!%Rj&q*@IPA-)j3!eSBKkM`+'qJ!rApkkd*QfA'QkMCL1K +*@`#`jY+4#fMfBTN*0%@C(N!+GYfI0VjVS[,-4%,0Z!Dm3aYA$+-1XF`N%l@204e +U1"DT1fTHihr[61S3bda'G`jkpmqY$IM9X,Zqf*h8SEmCmAYcIQ8C1*&3kj!!$@T +BXe'MMcaACk+b$*c8KZV$$U93*m!@3X8-R'bLjL"U-"5f35%kkBi2#48cF%TEVBJ +kaSCYl[R)85BUbm#T*QSfSMCk8U8Q8%mc8A[k2425Q"aeN!"!(346U&CGUp1@TR' +M[pRm'[89-c#9qQUS$CSlh52%HPfJ[Jl6604m`eYAMc-!b[p1h'MIqJ#KBJC+,&4 +d4%,S!L69SFAliGZN$CL"8K1eJ+-D2YASJ%8XBMR,`(5UY8%e3ZLrK'Z6(BVeYBb +dBHNZ`VE-Z)p3@3E+LAQi5B!1B*Tj*r5R[V)-c$#G(R4%!VAHY$r81VLCDQ8CQ'Q +UFKCh[M0H921a$p-NbM+cb,2*H*3FG8VV&Z&&EF(pLCL@*h&4I3E5h-!bXrrF9a1 +9CqD3!&ZQ'SDQTrfKk*6eMeJG`Na&6-Y6Nde-AqF5+Nj4Z(14VM@Q$I1S3ck[hp[ +Tp%aTI8G`k"fST$N[XXXmA22(NmMjjTNcfLH!0-N6%m#CfbD!&#jL(503Mi'Uq!4 +J1chM5iiJ0Q!'jV0pRGiHTLK"2H0Yh,aU*LNPCQ#"jBPkkp"H1m#KK@eqZDTh1UR +V(aADm#JX-P&cUhI"V[[Vh[p!Xc,,R'AfYDIUbFaVU&i$Y$G)P6%$Ca-E9)mIarm +8EQYZLBp3-32RQ+LjlRV0[550fhV`4GB%J"Nied60ikM"L$h"Y[Dld+S9-l$B3X8 +"b[$@0Rf"HTk*QZ2fHGN'KYhBeN(Rd*c(-R#qK4VdSe5Q8@-FUMC4#pbkKKC!09* +T*c*Um9Y#PGq#Va2cd#cAhCRCDr%eIb48c)"USQCj[,A*`G$Xd*%2qUP$Q)%D3Y@ +B8jC"c5d*#TB(`8dX4`+aaDl-K'e0KjJ"ccCp65Z+Djh&)Fb!CU)@DNY$1*CAfc0 +fke%j0#Zc$0550Y5LMkH'`hDjU$j@VCL"1YT8B+K'T#D&@M5'R"k@JATLH5hkP08 +"eCmN423r20EXK4R`%[2UlHQI8(h9la!UCZ!#BPipfPl-MNlVkjZLVfr#%P)[(&' +#HXT8JZLV(iHT9Xb!cd,eKh"RX92c,$CJ"[c89aqkMCf+-ZJF5e%`!`'D8G$!rRa +'LHP3N!!8"9%lCa48RhH&$Vd,)HSVS[U0G,Ra[PjSSZElPrL$RJME&1Y`Aelp1#) +i&!'Gq2Sj*ZpV523e"!Ceb0m8m04dc!c8erG%Apq$-08D#&Ch$J(4Malr!k&L"L, +8ej!!UKZD0e#EG([LY6B3me#1dilSpVif%XYeh!$XC2R"&eR-```XTEiLUY[[5A- +SKYTNS@VZ#(BfKAT8$ZNVbm!bJBTc3aS91I#qB-2lm!hLUiil)JeTI881A#MBF#& +F4"c5Y4"Zj+3jG15$eL5+'ELBp&82"MXRYRL(,V&3`fUR`-BlG#Re&IfV"LdpXU' +#kd,,G9KZSH+H%Lk*C0KJS@)',U-1CHBZhYH,,ep'IF8-I*-8C9GE'BFX(F)-A%i +GLS3kVAR@9d2deB"[N6BJ&3cFT8STLR+fa9I-`,IE8D[4C%ZVXZA0B`DZ)'eSh+f +[@cPd*GADU+ZK8*U`VBF0*LeR'9K"(',,H4PR$UFJDkE%$&aPcXUjD&)L'9,)k)4 +D%cCQB+@*fM18GZ9-jVed+MQT,(2eePNj$4ZGdG#$1)3Cq%j-[@aFj0X(JRNI`$8 +aImK'MIY$emBQYP5YVYpC,-F-I0Id+E-DeG5H%SZ@$FImUiR+-V#UIBV+F#MkqVr +62-3bm,fBjU8k"02r4+LBJG8*(k8$0qihI(qVUj6Kkk3lXkP@c-"emGfA*($,Jdp +F3'c!$&br65R6VZhl9ep#U*L"(jJka2C%JdBephZD2YAQeU+a"eP1cpL$i)IYkY8 +jE450l503qm!0*QU@MY0Vjqa90,Dr31d20e+Y1Lj&lDU9pJ"B"Qib8I00cD[f*Pd +!a"SU8)I#cArH(L!hQQ9qa1m"2&Z)+k8c0G@$mmh1N`9i1k!A,+qS+*h*-lI3hSC +j45#pYq&j)iYUCCPE59(mDUI4Nh#9INcUCEKee9pMVr4!Y1RDMdQ(-!1hdEB(l5[ +Vk4PPJPAV5a2J*kb[*ee&p`"X8&Ml9hG209&C"Qih8I2`9NBRm0SKVeUSQ)%l604 +H*DV2&``'E13ikTdQDYpTC3Y3(ZCVZRmRm0TI[SrA%6JUCZ!Z%c9r@YQmQJXd0dk +`1eZdGS4ZeBSCZ0Y%,CK@GUC@KeiP@T@I`FBlG-r8RVKCXY,F"%T4#*U2lhZFLFS +bX)Df&4RUQ@LC9eGfE#XH[r"@#hAKVE$@V$AAV"9KNl8q9S3Z1rXpbm#kYPhfDQm +JjCQh&Tfhb0,AmaC"-meH0C(DfX`NfPSidCUL-!-Y-G585a&$MC+@ibSl@V!Te*C +RVU1Y#*D"9Y,ACHak3dCIHkf`I"6-`(T!$[94FP9FPp2(M8hj$38VDF*Q'EMA4-e +MHr1kCYL@5"ceTbCUYPYhTb[GMRSIG3M242Jb9NmFGB1*QP@h$-pYC0J33pe)I88 +6Y5EMIL-@H3!X!rHhSETarch$KUfS$e"I%E9@09*'B"ce`6E8,MCX4AfSV80KA6[ +3SBIEDX9&-Grq@Rp',1mXG!IUckP@2#h$0#96kdF#p50iK'TGeYQIlDL2dJ5!Sb& +HXNKHk@%6`1**H"%%Tek@J8fN+&aIdij)[0E(V!kaaF-dE"aeFeccNVKapATm'aX +1e2T%3[15rP#-VdmQ&'8IkLm55VN2pDQi$UACX"AekELqIS(kM+N0fDU@FPj-E9M +dSM8G,RS4RQ8hThUV"@bQc'bBYKDGDqh-B3CGLa"Z91&P-%6R0kYBZ(M'ZE3LiR$ +kASJlJ[`'9D`1TimLRU([4lR@+I!Xlj!!JUiSZmD9PkM,F9C%h%EIGh&23B'lZ8Z +J`*hFQ9$J$XVI`hd!"GEb'9f"0Ac#9q"fq[e2Z0HL+,p9AX&UaLIkiEL!)Rj!hdA +m)S-#!rP&&`8'mpXB#XcQHlm+M+$I(dII`qJlMepc8Q!ii3fKl`*qH8Q"(-+Cb6H +F&CM(Gd891),IYP&J%Vp(S-!!IV9'J@-*lhMk2SCI4e&J2,qXS-!iITG"JD(mNSN +#S`KR0(dIc5pQ+2!ebKI6Gckrfk0!,rVZ6pppq#8P"3Vjc5F&$Z8AL"3iLYqS8@! +X[akK`#"qI8D"-I`'K3+(m2Y'#NcJYaX8k-h[1#P`-rF4&6L"kZj(GHEb@eN+614 +A'a5Sj"[%#SbNIKh*lqmS#Ee4cPIBYE@KRqPKTeXMBPdA[bdq@cbfq*[JlBqidjR +QEB+I#9lH`Mh2EKlq2rlCI%[b#eeBTXJ&#AijIVL)(p+ha3Z,$b[jPNHkheErV(l +Cr(p*H4QV'jISMq1mLlLKLrm*A6q-hp,k2hfA&qLkaDH%[LqJH8+qS211[RITZMe +(1VX4)Qj-kNkLrrYeaPAVBS0e@D)IcYD&L*ZN!6ScLpqdk0DEdrN9#jR#A#RId"p +l[Vb'lhBT-)2QqK9mmke0$m`,%!T8m"XF#Pc0pmlDGBY[H5P`&Gpp8f!9hm45i%a +qT8+"lr#0-`AQdKcm2EjcTF"hqCjAQml`LkIYZYGeb8%%FhANCMVMk%X9[f[5V62 +RZjK[-MfK-mlY$a&R5ppdaY'AJ)YG6Lj2k)Zcf55L*Di[FrLP**Q9cM6c663*KGi +i9iP%R#-0QfHqcrI+fh4Q0Gp1Pa(S6A*qGZjCL6KAHMFrTr4Peq8c%BZPGrTbL@X +jUX2-lIj-eidm%HG*Xr6PJ#q6Q*Z[ijG@GZM1'Ia'T`a!IaTF5e%pq2ABQ2lXZVB +SiRcTQ9pMkiqdB+jflR@+U*EHcGA*r5hRXUX)HMZ+4%aIT!YcM(-,@)3Ukr-(RD[ +4)UahXNMhr"QiRYpU6-h4c[ea%GE[jAGcG(*[d,PB,m)MMG'CKIbe#M)-[9R%hmF +JSGMVFYik)%+6h[NfbEdDje8-)QVMqL+rfVXrS$2bJlfDT&rM[+Y#4*hdE+k4"pa +(X[HhZPlL)F)kMbRGfppbhQ`L`LXYQjqP#6kJmmSA%4G)lqDBT,iilm%4X86@0bF +l,`F5`Gj2+RI6PkrZ9$T[64,KPrA0bFkVT%3%C(ecX[0q,4(@FfEPGh[-YKr6pH) +a%IbG`e)mRE(pQ+jA'SQi9GBh,cY[X"0aS6629lE[bhbK-S#[r*2PkBcp$S+ZGak ++X*l3,KrE*j8Zq$21#b&&K'9pqc,1@c*&4+4pqc*GV`i9d5$lfjGahUNUSP&DjXY +)%h6'HGQX#(E06BkR-mQlImjEH%8d5F2QCRR!qfHqZXrJ[+CBa$*CRprX[,YCa$G +NIIVL[0"Da%@b2Reah[)YiQ*jRljd2BrFLNYNIIVL[+pDa)qPGrTbVBZpmr2dlIj +Her[c49`UhGU2qGrhD-N6hTeLqme'@!e(pKL#l08dFMkrCZmE'9KF*Vh6&hZ[HEm +G#0q8[ZR,JEdrqrefNC!!*r2-q,DiA$UhErU92j1,CU(K$ADIS2b@V-qIiIT5(Hi +f!,mY[G1Aj0bFhEMr[Y%9dX'jZ9&A3k%pLcCA5ZrQ'[ZpJ-YmhTUpaR1VY'b25eU +J0r"BDm(+Mr"lNrQY2+dmLqSa"RV%jj[DJ(rIC$hjbrRQJ0lB1L-[d*H%VXJRp#5 +K)jCZN!"H+*Z8cFM#dGYjA+H&pbd@R#J0Q&0Y(NYpq1[c"VVjHp,q1A!feHhSXMb +(aehmc8(q"N0l,TDFr08F*Hh4A@ZqlY4Ij1qBh33q4IV%hjH8Pj&pia,mc8Eq0RV +f''QR5JIiQr$,j!NqQIb#clB[PZ!eq9Hf,[IdHbEXfmXp6GUNbr6HFGYIa$YaGGV +523bH)R[bT5aIfCk[FJfe3A2[QE#Q5JYmBR[1NYI`fGSVS(eejEI++mM+m3PHja[ +HZRTm@1[Z3eA6T#9cXhaMVm5HRap3(N*fMYV"Eh`1FQMhUfN"5Q40ml20f`,1@m1 +hqe@9TG)QhLERj*`'eBG2VqXf2+,5+Kmbk@2P0kK'52F'`Xi,BDC,4r4B2[&ZDIZ +pdJPp6[SG18[h,`U8GI(i`(l9IrYCmKUphZphC$GT4X"jB`f,FQR6[X$j`1iX()4 +r-ApC43Y5(cGf0h2AdlG96hc2fDi[cahdKh60f(fJjYkre*IYeYelZJI`dklkVS! +9M!lEqH(4DRelph[[Sqq%$L4dG$2@brE(%r8r[UX2@AA,[([P&6E3Yke,LAlBIEJ +9EX-U#VEc'Cp59,2hMCXEpr2K#DbAlG[rJVkIT1qRk0[Zcpf`"UXVr+`rlU#Rqk& +Nprp2Ijk@"I3T&rY8UaVGLkX25"2kC1XIpQQIrMhiCCqql!2MG9MAZRR0TY1pIE" +imDAq-6j%`PlIEMim,$h3[b42X[H4"10RdS"jaCiV)`%qqHhZa-rr-TGP,p[(3S" +(T!(c8$R-l2%lr1iCkd2"M!99XiVRi#fCLC0RGrD"Sf&BG@6&kZJrE@l9V(*ef0a +4ilh$5dH-B1@`XVEAFI#Z1JkK1PJ9U4TBp0e94fk&kTjA9Ba(FVViCGh95GC4@&V +TLaMXIeFYPTq8V+0IjC`Uh-`)e*@MX"M&GEk)eP'3!-A2C"ejmi0"(h,#+,BH-*U +-l+kq9XfDYq#XcaPQKU9EGPmVF%8)+m"#KL"T4dhf$1mS51!L93*h()lik+3G2lU +bh-GIBYFMF$[kVL2aP9R4818F`hSY'kZ61H1ZbLUYlT02a)m'iNq'XGm`AIVr!!# +b#J!!: diff --git a/gnu/usr.bin/cvs/macintosh/MacCVSPPC.sit.hqx b/gnu/usr.bin/cvs/macintosh/MacCVSPPC.sit.hqx new file mode 100644 index 00000000000..b9cdc9b60db --- /dev/null +++ b/gnu/usr.bin/cvs/macintosh/MacCVSPPC.sit.hqx @@ -0,0 +1,209 @@ +(This file must be converted with BinHex 4.0) +:%%eKBd0@8bj38%-ZY5jcDA3!8dP84&0*9#%!N!3Qf!#3"2bm8dP8)3!"!!!Qf(* +-BA8#r`#3!aErr`d0$%eKBd0@8bj38%-ZY9"`&!"$UBS!N!1!!*!%!eJmC"@&!*! +Drj!%68e38N0A588"!+Z[LaLZ-2[+!!#9(J!!fEJ!!"!j!!!@'AGNSHF!N!BXQJl +!q,j"RTaQEaIPElqb`5DEGC5hERD%dfj6[[+*RYNe81l+U6ABIZc%Xr@N,lXeIkq +$11@88m,1"RNVfrV4YZGYeX52FMmkUD0EZjbNQd@j[9eD*YPRZ[8fB3h)*V`MM($ +#pNQ1CclK&,J'e,kchpl#1VmcFTc`@mJQl(,NCB-)$CKXJ28%6Mrl!$J!Q,-1S"6 +re5N6RhbRF""HbXCE,&E#`D#N(M#`1&+pG-TVG4pUcEc01-+UYeL-qJGe+XaL0PX +bM5-(QcLS`l-YVT`5qE[U[K[M!GBq$$$h()LmT8IG`1)&[3U6*N&5M4fk*@''8Je +dCYr&#hX9&NrT99LMJHi+*mAC%If6*d0N5JPNP203K(QkeNb%EZ@6S(ML'am8eLb +%q*TciFcYqEUA6)6Z%eHp8jLd#%Q9lq0434Kq4B%Qa"9S-FV*4iU,Rr@RpjEiMK- +1+NbNCU6LepFjGad9SSJL!&#``lJB`Vl#H,dli0qCD5$l%-@"(r,hF+k8kk#k[M( +0Z"a%`d%b`mBY4DC!NmVlqIm$Y5cXJHL89"B*pSY*#6LFpN'#dc2BC4F+$j-Cr%R +eRIr-b6+0bM*EV$V8#&0FTbe*)V&d@35[Xcqb&-Y`!dc2"iKi%-Ar02*e-D2,B(D +-&``@VhZFB22l$(*+RG8Gm0S%h5VP3Rp$-fFGS"c+q4`2)X+MKRLi#(i-!CJ,#cT +QQIZ0k@mGBh6iE1ia@FDYp'Q+!J(R6RTh#8Q6Mi4pUaDj+R0Ff9k94U8kI(k[Bfc +![apZ5+8jj51'[GHZdKrY8fNMCc5(3KI[9HKT-ZekNI8@KHD@PicZhDj3`ck&EZD +-jY"Sq9k0aLTmThRG,VrJXKr5D&lP'rf'Y@[ddKD0KMJM8'STkh1)R1HKa6Y55L( +SU,lcY8IDGAT4LdiPcLL9@QVKEH2jA-&h5+2M+YpIQddde0)3Cc5(6KIYe@N(KI- +@6bTL',qXrpeRYHYd3)Y15442fNRKfZS4E)iFKqeJ)3hQhr1Xlj3R[Da&Rb(1D!k +G9Zl9D@HCmbc"jpGEE9k(CeIEpQ1GZLSbhP[IVY2,MqLdL6-#aI'JK-B,13jR@kF +8-44@pVLQT&fTrIFV9H'-jY$R[SQ$MScVKXTd@*rAPEppASpfI9jb8*q0R&%S%`G +Q`@X,q"eZ[DfYLKC9TNkY*KBQ$KSj)e88QYHQd1XVjVem2Y@J815-3&&SY0Q5E"V +ZGcKpE88d1)%%U+&*hbUdJ60D4D&(LfK`BX@m2m@3!!d+cD04ZJA)pSJXUpmVm2P +kfq&aN!"J#GE39G4#Yf!,C`5+5Q1D'$p55S16X)lf*"DQ5*Xj)e*UUFIM&%`&JX[ +IiNQ$Nl'@,U-ADQN6Cr5+5JmAdq!8V+AaT)0+U44IQX)lR@khbkFILi($+TeD&Ij +U)EQJdXfFN5L6T#('@`IJJMFXkaYh!l8`5GV%'BR5alBBd`IVHH(iES0TjA0A1DL +&2RB$Cc5(3KIX9@L%a(EE)!M$-,dbqqDlfa@DH&LK*%S2@kkIq6LKe+E1B"@AYja +NU*m5Ch4+r6`fJBdBCP3ZA$@6C+LI9-F%pS%C%'3kfC4PDP0Sm-BUc[d+Z6!$%Z+ +-4ZRL',%EiRB+,3-J$-0-%Q!'j%!ATj%c)U@+bRbh69,0)J%Q3!j@dAV15*5jH%Z +UeqdjdFB*cXBUqLYUB5kqRM-DTB)bVTf#rjJ2,DfXHL+IA+LJ)FjS&"pUXMY`HKN +lmke90$J(+qK$j))2EH5-@0&SUa%0rKapk!9dJdE*MMR%rEX5,DC#h'AR3mCE[8l +`jXUU9HG5#lX5QcLM8ES&DEL2jQ5hB#jkR9-lq!jd#a61#"9pYZhq3!ccd1F-S"R +d5D0i(25KDEL`-b29P0E@+rK&GHqP$j!!#ckdN6-DC@Y"QKXPN!$KjZfYN`A"qHK +aRL)AYKCXjSa'kBZQ1pdiVhamLmkYU0*(bB@qD)Jc@N@KEE-IYe9XA(&UKf@E3UQ +8f3qf,[pN0qGfV+'2N3[G!S8c3N@I*lSjGf!hCbM0S%qbSjYc3*pQhZ%k@6r[*"R +UTm)CSD,2%r9c!GE2,*T"Rf6+jLQ,9mJ4[),,*V4ZRPU)pI0aFQ&EcQE1k"@9(YN +mY3LVk'M53D98bZBTLdm)f0h5V-Z4MBKhN3"Gki-UEH+-4TNYD'#mC50L'FQ`%A% +cCc4+hb$6jl@Gl"[FMChV*mQ&[S(#'BfL6bYIm0d8iQ,d1L[)"AdUR"%UqMa42jH +Jbr(4$2UN86D3!10Z-1RG$mHhq#r&q[NEFQ%h@)Jc8N@KalEihi-9Y*KU8#MC882 +h[rc$NL9imadZYp1GHpf42CA"FK*J2qAqPhpXjia'kB`fXRjiXd5`DPNLr`pbS61 +kQ6-5j88kPZrHa)!BUY'6VU3@AU46caQPSXpM6ChJ-R5NdiN'I9)Gmam(1JBM(5k +lqpVM2CelXAl@NJXGJa"RT)T#Mr9dlU[BZ'STeD"3XU1RXfmMEhLQ+6R9E$UU6RC +QG#RR*VlEVY!,pbP8iBa#f5FK-De2YPJbMUScV[cY2YF4#rXN'MQM8"b1c$BZ)@k +VRefVZ#QRYS0pkh!D1508&'T1hNEJ0`VY9Xk9k'N'KBUF%5S+Y@BH8qMTk(+SKFQ +24XiSP"PHUq"RY)m3['cYia'&aPFXIhd@X6$$fm`CKI+k!ZYeq4N1erLM4C5Tp)c +blKGF55bmVN$KM1*3Cf,p'eLrIP'VNL81)rh8Yh%[Dhi*b0U&3`!k-REk3MKlV@` +)CIflAmq42YQjp9D!bq[B6lc#hXlD)GcXG[%fpblXDZJ$89bYUU6qHcXjRHk(-2D +Da@&@(6kX9XGN+AJYFJ)GV2XEUKh8FSB"582P$-e3iXA1caqRkEQSSKT326B)1[r +lcIVEACk)qe3J88@Ea-"[!a[CUfMC3fTS!"aQFdB+k1eZfdiF-4Q1XEV"q4khemq +ShB,$m4ll0&XbdSJ!(#10U63!Vm05KZLqj!1lfA[ib'3QPJ6JJrN'YAjXRXhRNh" +dQh4,#-FkdD9Sj4Hpk0M',2QUkTFj)Jje[`f,f$I$SG,EG[1U0Br8'ApS6%LSCh8 +EV`b(4Qp,5#!"F+Me0KXCJ-0$!q"!AMdH)J#(8,J,aalGKr5DpadIc&T)I(KXH5G +`-'2$F)3c(!N*"!!1PGkl'iFk8bK5kZXfI66Uc#INlUb,J$L'm!8mUi[+e9"Gh#M +@4Dcd!@MA+k[6APbD332Jm18jam)A1SZaQ0,fq!qI2d!%i'"(mi8IfX-VXlYE2A" +c3XAKVL!$(#i"J11!`d9U2eE3!BIl+3l*i4)![-V1P!$!368i8d8GTjcTjcMqkdb +ra2'0-rf5efqFi"iFp))crB523mld%ab(R1RR11J!CkV5qhEAaA#N)GQA,pC&j@T +cA4aP()DqiA-qBPQ5HJmRFG[-"rhKF(IiS3-1G`F1GQJ!KaXYYKSq-EIL18edZ-A +GrS*+rkaRXIddpLcU(5i*J-2Sp2P!Eh2b1bY9"&E1chSS8U85R5N*`)IS6%N!()S +chBAMrjeTQ(iFX[mCMUrd)6X,KfHRcTLcf)2MUX%@l%dAlFEa&4qL)b!"G#Bk!K) +!KqL)5)!k*&9b#N!I1)l6"c3i[D(",h`I2QF`m!QV1Ilm&k(,+eV)$0-#2#mHb1` +"#4C)rAiCP+4l6HPLmJJiJq-6rQbcXmIRilN(lK,I6ar*AXdI1Y,Pfr[B4h$m"BX +j3fq)M+KlfTi)F(%0XaIXpLdV9F`ULhB$-C9#Yp'TN!!CMNrF"rL)2G%ImH-pY"q +U6IMGGqdLMJIGTPJ,3b!H"2UdI34Fq9'fL2+LIr89r`d2[FMaLCMc"`b&CJYf#6$ +QN51SJA#$`HNBDc"3'"VJZUpI$lU01Z5[QL$3!&Bm5N-$EfdL"c5!Ia%'3a%V"1T +R(XQ'm1F,kfTRA&CA1ldBrmYB#98rmqKXM(@[Ujhc%Ikr*'+[eFA9eIkqf1A@pEK +8Ch)(r,UaJSd2U0@p2@TePrLkfYpj9'YqDP%[AED"hF&FXb&LrLCik2&0DR@R[Z[ +PSr-lmN'c&&PqmK+YQmh*-I@8CBX+8*fEMEN@UA,MHm+C&9U-V3DcEb$qedrjUp9 +Rc&0Aj,fPVN!F,1@D5q09DbkaU0B8L(9IYGTm"k0CVHiFMlP+!DVM-%FNrXIL[`E +rYD`1G$BB$-D4kF1YJ`d1PmdCX!X'!e94"lV(-Mr`e`hNJ"p)"e9(0Qf)$AeV`-1 +k+iC"!Qr(S9"$IECdmlYFqK8IiRGjb2RGe4-k&`hFi3YTKm-81&QYL%[KEhiKidr +K8)V2$q*r+DX$-D%kJ2elJf'r(bMQ8+bdJKpiXj3Fm!0mN`C%Em3'8a[L!lRUaDA +3jD80d2@CV-KU'&VMj+TCh)M231%'!#HU48&@[53$mpA!8-p9d2AC*1R1iT9LrV0 +R[LARd#dZJk(3$9p#2RM&4Zd%#3rQH8[+[b3@BNqI$&fI'X89rRZ4'*IaLb#VY42 +%H'5D$P4,UKNHVZ$aeCbr`hbC"MD"UZ@+`NCa44&6ZD*`#hIY''3F-8Ri&c(YL2M +&1bSYK%1deC'2$jA5T3K#ka[5#*!!Jj@-JK'"H1,%hT%XLSB6KE@De@[T9Ja%B%6 +mNr1X`MS#BE`HrI&am*IMN6EEF#@MYNiNYq+T$`lR5VN1UZZh#,mCC5*%+ScE#Rc +BS0GMkleql'*Vf@M3"r-FbVfAa6Rj(EN)Rc0QM-r2Hdm8'!,JF(faVmVU($CUU4Z +YXRlrN!$N%FNBLQ298(3,XRf3!!rc&#&6J3lL14UN3X5"h#)KCmkMV(*'BH201-, ++609jjfe2NSqA*3FBYNlk"h4SSeC5#,*Ym)VrFBTkdGqT'PhH&i!dC)cPNa36&HS +V5&ji$QUl&2r9+@TAfCYGVm!VhERR31h"*f[!fG$6JfYk-022dU`Ql(eamkaCQEh +`Zda6`hVRV0X!N!"DJ*QB[m#6kiA[i@G[&V[L3qL2RpMj!aJr%pMXc$8XPY-4f," +E$SXP&X$9q2NqLdfm#3S`drdXP[3U6-2BheQXm!AF0J01NF&"EX$qZR-!Ld9HM9e +`F%jPX6jr`$de-%(X(A[,!(IH6"2aGEXGISflF"!AjSk'e4LEc@,4-f!YaK!,32B +i`'Qpi,dX&R%@i"c2$$&Ijq@!RG3CiMh0"e`-aK!,jPl1G3@iFCk)fm6e"*JT@UB +aicJpaPjRX9'c1+aM-m@C)'dLKlYNCMh-BTN",K0JpSXX0M+0'`e`NmK(4LU(qi& +ZNLVXDYE",AfK@F,Ac)&Fe*lBS99[%R-JRlLP4PlRSj0A+QQ9Z"NAmd5NH0hAqJ4 +[4`[[Xr&1h8MHkh+iFRdaZ%`cdkJcZ[-pq*B+Eh4KdJ!-fS9d`4A&BY)3SRK0KK1 +cH9Q3!!*)34#MS-CAb(PjAcKl-*lEUf([p3V2iVfjJPqEE--AN!$iG"EHRiIha66 +4E&q0M$Z@a9)G2TcK%[,()U5Sd$)E-Bp#K$5'@`pF#L[%KK[6c*K-+djSb4QMfFi +!"5@,0D%-,45)B#'Fpa6cbEQedT`YXZB5R&Sf[+X!ram!N!-1`0(1-rXQACkG[5H +hTpcY`-lVE1cE41l*PHXek1hSaP221MahIH2iVmZf!m[1R'A[p@DkfAB5ZqL!GhV +E3GV&kMa[0q$,J1adiC&EI-PJmG+&AqPRRVGG21!ZB2c4kr3U6fh!9@DIYdJ@FR` +KNjeNa"F!XJ$3``1[3*fA"h!"A3m$!-2rK`2mC!lqEm*D$IiIM$mE"d9`-K6!Z** +U*6#hYVa'0kbec!rP2cQB4I'AJ2p2K3Ri6DHJ32aUA%RPJYVb@MeZ"05ecNpKFm% +X&ReZ84GD&eiTajZM04L+d3T[3SASEb,qFL,fGmSf22mP$YVQG`!'$F,IP1%I22% +U6Qa),plKC62ReeBjN!#UUCTEKV"e)(Cr`fYE68Z0%++QQZ80VH@mKi*H22lr[qF +"PH@ePQ*THK64f)D#%pK'mAm*Qffq[)4ahX&b0M[q-K6'EG#a&pq"[eh*CP[$UBe +2X0R0-9E#EQ8P"4VqEa@r,m9DD8'V0eU#a[rcDZG9E[XPlqrI"Hq4!ri*lm*mGKZ +lU1!Uj+"rd'@$@kBS4T5G)C!!iU)fflT$c'X3X-Nim61H+UZ+@US48J)UNZ'phY[ +R2MLCA@GDm3CHJ3+"HVH[@V'DqJ"Ye,qrB6fL0S8EH!8'FG66IMkdHQ(P[(M8dL, +Uq1hJ(@ZHq9GfAAA0R"Qm!S2YASI8e&6@SHBKSMPHIkrAUL(Bkk,+Z60i"3VYZIT +UV@"PEN),EhIQLK8S%UJh$Teb)@T1jAKXZ@p#D`qE5"2##[JimiB&#j9JF(`J`pr +18HUVE'AGp%9e[!,&0UT2#8DdD!Dhdcme6+KB!Eq0kJmdUB%P'Gc1!kjkK9#a!L8 +fDSP!eH0@#VEci#ZGAV%#T3jU@$&0,G6k!@UCM9SF#'YUe1X888GI%L98V+$5%US +HL@KCe"i1$E94b`+'UPKU29*T"h,(6pIraNEP&4K'c!XdQdBJ`lb1aEHp5kKBJH% +fDP&3#i@b01mml2%)63JV-),iLP6JbiJ(M(0jhCh3kh!!68Je$0h)DN2"``iEX!) +(fUK$e+8a*4UXMk%iEmIZ2+,i$8,&#Rb-1"65%$1U4&*$k[M2)#N+Vm""a)BQaGc +4T)-DVRq68,%#"a-EQM66dJe28,Kk[HDUefX`NV4"DicUKTVZYZ-A[lHS9kc!)3j +U*)DlEdj4IZdUbUrK8*TV@!mXbE&mp#@kUeikM+)0)+`h[Vm"q+FkU&L"`iMPL*V +E!&!4hR+ei5hFpZd*4C3FD(*#4a$c)RS`(XlS%-iPjNiS"U1*3j(@D,#K6eYT3Vp +c*r3l'%1p4[AkR&KfE(lfYi5+&5Lh88YMLQ'U@M5Npq%QHMf51)4L&mJ+8@+ZBiQ +[4L$0"0)K4aZ`!NI4A"%e%!PQ105$HV5$UJEL10NdkK(&T*5m!XF3m``eSMGR0!q +RHD8lebZKJYKJU$%p1eRF6*cG#bY`,#Q+SHXCR46-HpYPhYX`cN'eP*cS*5EdFCU +VL8C+2$-La$*F9!11Sel0H%0f(B+1UkpI4K2##Ka2,0mj)-i'4aZ`!LI3K1+a)1k +8ZIh9G2A9K"1*jFfUBD*"P'BjZpKK(PCJI$GU[CAC$MFrZmP9bNe`%U'f'%SXTUB +*dAR3'&*+AK&Z)!a6r(U-1eMQH1i@ENFGdqEXP&K"Ke#JiPiH$@Q0(LK(GI`'V+$ +[K$l+X*(q4YA+NDKMhGmddPbaJQkKLaV@SKR858$l+kqJbbK3La%94j[C88krhq% +39Q"59kq)1X'$E5YFGi50bLY`QShU3p5@V0H63$hG4Lf-"#IPG!La4VZSSq%-kY9 +3'p@Plfq([h*9q9G`TSeDDQU06@J#K&-XkKM44$V%+h!@F@MTcX'fchb8@-iVF$C +0#'hCD'TE%lfH10,a0V!#jj!!+U2lNTB6VLLM9-F$`!UFbjfjFilhQ9C3dc1i(HG +hrKEXARRP2%*YE9E#f@ile[a6&D(bb[Q68I2+jT5DVHC*k-$JE(FJYlh`r'pX9&' +CE2H+Qdd`V$@NQde-D)VGDh%mLTC)-)hDY[E'FG3VVdcYRP!JU)C5XfelBF-McS5 +`8YQ0DVA'd!AS3pedj"K#jC9T0ZV3L"*S3P8q5BQDfR[!UpriKfYY9&'CEU-1Fe" +6rDikVrR(0UUSc,!j9&6([H'-1#3i002ZYBc20FZMYKFf(Z+`!5ZcE035`BC-[iM +PGe(p81@bh0#LQAdS-D%,D0X)452#TdM"SZiI6VhbbQa5V`!RcrZDplVEkqX`apl +B#Q-Sj$Pp(IhLZ6DUU&3lFd@663RRj[UQfqZEF#&0++Z5K2U'LrS'c+9Y!jQ(5Be +-VcpGlcL1@)'DEVjbpb#&fhl[h5'l9e'jL%rSc--2V05M38e%0m)BL$(3(GN+hc( +QMFNd)9kC4f`)DfK'CaD(""YUl3RjiPNjiCVhlPQV5I0iTBj33i'SP5%HUR,jDii +UBf9qYjCRNGX,$ap*E1#9"E4Y"$@$Hr2TEH1&$B[G[@%a,0cLp@C9H@Ec)1)V9Q# +4ir5S"YSE'3jYI[BGepYi"blZ53qNrBDHp-!P26jPZYH#AcSH!&EJdUdEGSCjKH[ +'ZR[j@&MFicHN1G6M!9aQSaDe+*KZb(#SIFhBRp1'M4@i[0ZRc'Tjab[r3BiMVd$ +pe[4!'VIpRMYQ8DpB`AM49YmVc5'BpJIU&5ZJG(XEf3NP[)f'K0163Qjrr2YAd)5 +`!J&5C8bMU1MSCe6jNA@1+Q-PD'YH%Fq!jG5VlCJR#C9A9&*+c+1JYCc'E4pap,q +3!,lb5UKEP68pi+Pb@k9b%1NVVc6D1iU[,V16L`PeM++p395DE06LkFdSP0NGT@H +cdDMA'4T2!@5diFMPkfQZ[(+&M9Sk*4B,Uh9+H%PUfqK"A@+M$UfXQcVIdX+iIZe +S1B%DYP&,DT6!%U8a2D3%DX4',D18f&5p6p!6U0&Zjm$%a)IDah6FJRlNlN-r!Te +3SkU&iQ@GK$Q-(DK[hq@i,l`5Scd2%B-CH`K@AA[#I0S1HH9+dL(EfdM$2[b(Y@r +CU+*Lf+M$(IG&aH9AfBDq+[+lHG3VVjKG$TCLj,b04jjfpI9TX'a8Ire1f)IrGYJ +rdi4i*IiRApP'&C9QHfmSiqj,c-4B@PrNSehE4!iaVd",cbDDGI5Gc!&@B+RMT2* +H[5b9k*AF69k"9T&aI'P)EGAFqB[5!8*-%'jFa*EE#F+0Lf#CcBC5Hd,e@LScdeN +am@LD%&EJNcCUNB&TP&`#Sf,L5"Ge*&`e'GP39LebYA`iI%JlpU&a*p#%X!*A%iF +`Ua3a-h'+4*VUQS6[PB*Yrl[M#C9Ai&Sh-40@P8aL*T&(@GlYHqA5(K86KlYX'!l +AfDMFTp60qK$ILPVIbf%JeQ!AG6"mLRSe8**hpNSH!+r!pBk(VHRaV0r3%AbeL25 +99cjYpeU#%q+@H5c3"paC-@'QdqZ%QI!CbQlbL5U@jGN!LD6G$6CUNBTH@@jA2[d +"Rj1PH-!(Rl94I5djEa0Cr[BYea$,X3)hENA0*EHf*)&ZfM+Kpe0(@j*f0bICd)H +-((#b,eL"@i5@rh!)'SDc9#@)'CdG8SNTjD0JHA9ej5a4ZCAf9h3F,802a`i5QqK +YK&UR,V@QCpLA3,hG4[8[a1bQhT,HjpXE4T%()#UI)e8fP@BeN!"aL6Y1RASSX4` +VF!IPmb*,hXm3B[BblUB`ir"jBTiC-*4)JaG(JBl@fhp2U&L",p$ZeDbB-I6CVG3 +qP(#)[dJZa89a,E!ND#JY+CHLK`eh%QUeYP309Z["P"[98EZBQ#FUGpQS`paH1A' +h)5IiqLALkpaDESLNqGUajXGR8kqmmQ8EYEJDXi!BQNel86fpIS9kRDBTZ,4PY+% +(p@l(9H,HiAqj5Pqe8Ah9DK4$IIYGTAYXe+&iU8)8VB-Jpk3'r+'[r5Np3"2LPA[ +*Ek!Yb[$fKY%[6R)mJ"FR`3SqSE0Z)QI1!iA9IrA3C"Z99q$V0QS*hN54!ejGrJX +(&5Z`dNBG1P8*Kh8pkL%R8,pKSikB-RdqQJGeUK(C!EckVppH6kKBJIYXe0)TdqF +fA+%'d$lF-D,9aaY1VeL"qfh8XLR6jkQ0',0",GS1QjM3!j-,d@qifICIda5#YZ0 +'('ZMmJSm5"iE4jf(-IhkQMk2lEJ&+ac8"5[J)EYA[pdV`UCkr9l&Zf`jrcf[`$F +6qe$'EpLbEDbL[9ai"TPF+QlMML1#&9MGYFhADp(d$YYCFGP#"r@bKI!`Z5m0m9! +Sjf!01HdeYPbJBJADHP$6(PX2DM[T+dEQ-!5IlV9pijeK'j9A-"CJcaA&&4f+P+F +N(*(6d&A#ACPAS"13!+r$Q9r"S+*abN5[fFkbQpqK#@%&(V&45lJhEkLQ&jY0S(l +,4[8&M%#Qdel8Ep1%-'3AcLCC%kL2fUK&MFX`V*Ke+AT3ep"F-IcHN!#pI`#a0VQ +SQf"Y&fS!YpFX'lDJISIQLUJKa8aE+3R8alT3qpQ`"IAaVJPCKVTr3NpdpBU"U[# +qATmNPZFDhBEkAHSe(K@DNZeeXiZk'CkLATIPjY1,ZSkdB9NZ*GU,qV66+cI--l! +*e'F5kTA#6HM3plE1GAq[H1G1MhVe!5HBpfa5'rDLIMqTHAY4Ij!!8*3-'lDJ2TG +3bJp3RbHI8V!mZ`%-[6&'U&L"$IB@j928G!C!S&BXr%G#a3TXj,H!$92+q%kCc90 +d9PckLS0kk5Zicik$!-c#(c+1Ejm#8FPlcHlj0(d[`,3IATk9l#-r4rGXS1m1X48 +bf#JQa!T#"A`!dh[RdlpcZfF9I9mKR#-'UNKT-EK)Z&B-EUAI,D([f5*"bq!V9&m +JmSm-,K5j93Ch%fi6IGYC6!BDi9dJFVX-JL*$aQ#Hb)8bQ#Bbd3`-NE0K-&fNR4P +mQA#r5Yph#Qq438aNIaMS)MR%i%[#"f33*T`)IFm4f9d'Aa41*S1lk(I9e2Fp9$p +AT*!!'8bQlbVkRLTbi3c1&`Pf"[0&5T4"5165'%4&hSP"MFM5-TJP-Y!-+N8bR-' +9)Qh%B+C)9$1iMIUG3IdeLU3DJbNLYFkJ9L4H'Ga1mcT2j1dCA#a5R!`QL*32Jh0 +%jTqjHP![%SS-&SXX*B1&)Q(UkJ4F)[+F$%i@GeB`Z&cN)"PF+K+E$"D*E#Q$ZF+ +jBI!*N9eNF*P)@H)md0e'@8RU60iYG-qpp(fIm-NBh#qF,`EI%'iEJj98Id"i@`` +H%Vi6J`H&DmAJkr6l&F)rC1abaLpl1hUl,ZGF)rHXlYFp4qmFIA2dc0%a4lpZ%BQ +'M(iPG5UT6pH,"-Z!r[bIlRKkiqK,BUpJ2f-[)cY16I)VR`*bchApr)U6MLAhLq4 +HNGmRj!Pl4(*rN!![l!eI)ehqbrk3!1!hV)#9b-kb*,rcf6$h,+G[Kfm1cjapbq1 +&-epRITlq[-KH`Zj15FiRRq4ccbHP!A[YI[f4aqb[HGe*lC(jR+"l2TA5RH6mpqQ +-jjrNFkEZ@5E,mdpFRA([f#AGklm4e6dqkCR1j2APFb*K1U!cPaG`AfaD8QIbGqL +kTeMkTM0jIBN@a&!GCL6e*CqlFmr$#Ad*L"YSC&BkdbB5Ma)+[FRIlZdH[c4XRlP +"h+24T61I%EGab!Md*V8rjqq&Gdq*p'jr6Z[,cKF%Z+G8HUF[ea6`C-kXARqQrkd +*lX&hA8Lbp'@r,j2FQa[%2C(EG%F4Ydl+!25RZ@!TUXI-EIUcmp85lR(H%b)[mfX +mrC%@l0AjGfqiCkMdEUp1jEIb,b4acc$TQ,j)&rDBr*YDh11mSNHkj`rQE`Yecdf +b2Rm'2LYZY%h[dIRArlKRK$4[MdlP"[2[4A,2!G)BR6(&$IBb$,faa*hj%STF9rk +P8Hij8(VRfk4b0IRlfYecFd*Ij&Hjqrdk)fr)eI5rKF`p(j2ej@VbVfCccd(5XVe +'QV$(j0pCjjk$TAGl6%TImLrbFmp)@GqHR(qlSAX1NElTbdIh"qCIqqLH3f9pHh, +qACMZ'5AVfj2c,`Kecf(5[(bTjmId[rl+29G,mh6'mf2khcEV(RcjY*a[AmkrBFX +pr$8(FMaIfE[hi`19!AbGX5a2ClclkI[IjqbHdG+b2+Pd`Cr*[qcD2@0NIAQCr"[ +!h9-ZlF[,p,m@h6e(b[lb-[RhaEYRV,6-Pj%Qk%cq4IVZ18UDTc1TqpM`4ED"1$S +cZh6QD'RBhL`2H*I+4rFcj&m#l*jVCAeqFl'",kYYhRf2d6'b2Rh"&mE(m-Aj!dj +JKDa2AiS-AGrl[S&MjAhkBLPl,c!D*q[6PrcV`0hcHHQG[YaH`'rXZ+$Ahl2I1cQ +``E4)Yr)aIhNRP$cK25#HhfaDLS82CGqP4aqAp[NeHpl'c-padMYpmA,0qqa!1&l +kTLrlFhrHZpVLX@$fQI&Gj`6TA0ld)hr'MfDKUHN$9e#H+1[cCi5qe&X$"Z"ikCf +qT2CQAmZqqieZP!lZc5f'%S[Y$YUF*,hEDlahh#d,D`elM1IRT@8j,QQ"hX$6R@8 +hEmE[GIBhfm"qL1Sa!3BPpTY30,*hXllQ`reQ[pji1L-[d*HNVXJRp#5T)ijZN!" +HX'IBHQ6KbEdmEP5Y[F'#LG+!2GAMXG5([f%Y1X$I8rEYJA(U1kr,mK`Hpr1h'2Q +VahEI@(,U4hZ8Y%GhRIdkTlr)h`Ql#$a*qX6I&pP,BJY+m0H(r'd*lME56T-1m$I +TPmN6I$,j"CmpAbc*Dr+[2&dZM!3RlFhPRLjYdQ9kKlER,q)pFBhUdYd-2N2fj%X +j[V+hArP0T9N0l0k`[LNYm)Qp28YH`fFR9d"jGIBcpV*`Ra+m,M@eaLCmm1LZLkV +1P*EXcI+0A)Qh2cr'RK!TY&jqic0pBlYHX`V!8jG5T[hCiffCi+dCh[@UbQCT%fp +6Hh*aXa,'TpF0'"lYdLSI-Z9MP6BVCXc3SPEqK6"IN!#1k,&miMh*hMZ5NrUFmMZ ++Pqi,#Tc9cq2pqDVrmE2N0AUpcqr`YDTQ02r''Rl1PMEP"5i(IXr#B2cVmCF9Y## +08bEZBQiRI6[p*(,1ARmP!6d5-e4ce`8eMrbj2er!#1bH(X#hq[Zl3GaJiZrP4e! +0KIINHlp0hdNG51VS-pJ[cimRqrrHcMN805l6pXJV2%VIRLiPjq(0B3@Xa#l+H[Q +-6bPUf22'c6Alq,!Hqq9jqqr6pl2dr32kpZEc%+c#lSCXRdp!$`imP'cYrmlR19R +!R2`iTj!!BJi%9lmM6CL6ThmiTlhkppL(FrT`$TcAPU%1m2VaIA0`H2'KrR%qa#d +Y[)X2I%Z@'qKILLHq[56"mk3dB&rapXTi9'aqZbEah6r[CEjPHeN)m*3dB"qD!E- +'r4+r#h[Q8$CcIQh9q$PiPda06@9Z$PI4Yp0(88mI3kGF@&Y9AXQli0eNqR"`8hd +-UDfD1hr43"[3ZV-2Akd9V0cCJAdF2U6k++Z+@US48J*UIc-#,6Z2DSc5l*Q(Fmq +2al2UKCAciP&,LkJl#H,i@al2N!"KGESHaKl-mATf(UjZB8[4qi1)2`-[ipjF-b0 +XfVqjlpr`dY(*+)$MDZDB9[FJTr'2QPUemBprG(q%Vj3X'-Gr`rRbr`#3!e0a!!!: diff --git a/gnu/usr.bin/cvs/macintosh/ae_if.c b/gnu/usr.bin/cvs/macintosh/ae_if.c new file mode 100644 index 00000000000..b0a73d308f6 --- /dev/null +++ b/gnu/usr.bin/cvs/macintosh/ae_if.c @@ -0,0 +1,423 @@ +/* + * aeLink.c + * UNIX environment handling stuff for macos + * + * These routines make MacCVS able to accept a standard UNIX command line, + * environment, output redirection, and startup directory via AppleEvents + * and redirect all output to AppleEvents, a file, or the SIOUX tty window. + * + * Michael Ladwig <mike@twinpeaks.prc.com> --- April 1996 + */ +#include "mac_config.h" +#ifdef AE_IO_HANDLERS +#ifdef __POWERPC__ +#include <MacHeadersPPC> +#else +#include <MacHeaders68K> +#endif + +#include <AppleEvents.h> +#include <AERegistry.h> +#include <stdio.h> +#include <string.h> +#include <console.h> +#include <sys/fcntl.h> + +extern char *xmalloc (size_t bytes); + +enum { outToAE, outToFile }; + +static int outputMode = outToAE; +static char tempOutputFileName[256], outputFileName[256]; +static int outputFile; +static int noLineBuffer; + +AppleEvent gResponseEvent = {'null', nil}; +AppleEvent gResponseReplyEvent = {'null', nil}; +AEAddressDesc gResponseAddress; + +static char aeCmdIn = 0; +static char aeLinkDone = 0; + +char **Args; +char **EnvVars, **EnvVals; +int ArgC = 1; +int EnvC = 1; + +char * CopyInfo(Handle info) +{ + if( info ) + { + char * retarg = xmalloc(GetHandleSize(info) + 1); + + if (retarg) + { + memcpy(retarg, *info, GetHandleSize(info) ); + retarg[GetHandleSize(info)] = 0; + } + + return retarg; + } + else + return nil; +} + +void MakeEnvironment(const AppleEvent *event) +{ + AEDesc args; + long i, argCount; + + if (AEGetParamDesc(event, 'ENVT', typeAEList, &args) || AECountItems(&args, &argCount) || !argCount) + { + EnvVars[EnvC] = nil; + EnvVals[EnvC] = nil; + return; + } + + for (i = 0; i++<argCount;) + { + AEKeyword key; + AEDesc arg; + + EnvC++; + + // Variable + + if (!AEGetNthDesc(&args, i, typeChar, &key, &arg)) + { + HLock(arg.dataHandle); + EnvVars[EnvC-1] = CopyInfo(arg.dataHandle); + AEDisposeDesc(&arg); + } + + // Value + + i++; + if (!AEGetNthDesc(&args, i, typeChar, &key, &arg)) + { + HLock(arg.dataHandle); + EnvVals[EnvC-1] = CopyInfo(arg.dataHandle); + AEDisposeDesc(&arg); + } + } + AEDisposeDesc(&args); + + EnvVars[EnvC] = nil; + EnvVals[EnvC] = nil; +} + +pascal OSErr DoScript(const AppleEvent *event, AppleEvent *reply, long refCon) +{ + OSType mode; + DescType typeCode; + Size size; + AEDesc args; + long i, argCount, addrSize; + AEDesc env; + char *argString, *anArg, startPWD[1024]; + TargetID requestAddr; + DescType requestAddrType; + Boolean flag; + + if (AEGetParamDesc(event, '----', typeAEList, &args) || AECountItems(&args, &argCount) || !argCount) + return errAEEventFailed; + + // Get the address of the requesting app to we can send information back + + AEGetAttributePtr(event, + keyAddressAttr, + typeWildCard, + &requestAddrType, + (Ptr) &requestAddr, + sizeof(requestAddr), + &addrSize); + AECreateDesc( typeTargetID, &requestAddr, sizeof(requestAddr), &gResponseAddress ); + + // Pull the command line from the event + + for (i = 0; i++<argCount;) + { + AEKeyword key; + AEDesc arg; + + if (!AEGetNthDesc(&args, i, typeChar, &key, &arg)) + { + HLock(arg.dataHandle); + argString = CopyInfo(arg.dataHandle); + AEDisposeDesc(&arg); + anArg = strtok( argString, " " ); + Args[ArgC] = anArg; + ArgC++; + while( (anArg = strtok(NULL, " ")) != NULL ) + { + Args[ArgC] = anArg; + ArgC++; + } + } + } + AEDisposeDesc(&args); + Args[ArgC] = nil; + + // Pull the environment variables from the event + + MakeEnvironment( event ); + + // Figure out what mode should be used to return results + + if (AEGetParamPtr(event, 'MODE', typeEnumerated, &typeCode, &mode, 4, &size)) + outputMode = outToAE; + else + { + switch (mode) { + + // Batch (return results via Apple Events) + + case 'TOAE': + outputMode = outToAE; + break; + + // File (return results via a file) + case 'FILE': + outputMode = outToFile; + if (AEGetParamPtr(event, 'FILE', typeChar, &typeCode, &outputFileName, sizeof(outputFileName)-1, &size)) + { + outputMode = outToAE; + fprintf(stderr, "MacCVS Error: No filename parameter\n" ); + } + else + { + outputFileName[size] = 0; + strcpy( tempOutputFileName, outputFileName ); + strcat( tempOutputFileName, ".TMP"); + if( (outputFile = open(tempOutputFileName, O_WRONLY | O_CREAT | O_TRUNC)) == 1 ) + { + outputMode = outToAE; + fprintf(stderr, "MacCVS Error: Unable to open '%s'\n", tempOutputFileName); + } + } + break; + } + } + + // Check to see if there is a starting pathname for this invokation + + if ( ! AEGetParamPtr(event, 'SPWD', typeChar, &typeCode, &startPWD, sizeof(startPWD)-1, &size) ) + { + startPWD[size] = 0; + chdir(startPWD); + } + + // Check to see if we should not line buffer results in AE return mode + + if (AEGetParamPtr(event, 'LBUF', typeBoolean, &typeCode, (Ptr) &flag, 1, &size)) + noLineBuffer = 0; + else + noLineBuffer = flag; + + // All Done + + aeLinkDone = 1; + + return noErr; +} + +void GetUnixCommandEnvironment( char *name ) +{ + long timeOutTicks; + EventRecord theEvent; + +#ifdef __POWERPC__ + AEInstallEventHandler( kAEMiscStandards, kAEDoScript, NewAEEventHandlerProc(DoScript), 0, false); +#else + AEInstallEventHandler( kAEMiscStandards, kAEDoScript, DoScript, 0, false); +#endif + + // Allocate some storage for the command line and the environment + + Args = (char **) xmalloc(ArgMax * sizeof(char *)); + EnvVars = (char **) xmalloc(EnvMax * sizeof(char *)); + EnvVals = (char **) xmalloc(EnvMax * sizeof(char *)); + + // Initialize the first arg to the process name + + Args[0] = xmalloc(strlen(name)+1); + strcpy( Args[0], name ); + + // Defaults + + ArgC = 1; + EnvC = 0; + outputMode = outToAE; + + // Wait for the command line and environment + + timeOutTicks = TickCount() + (60*AE_TIMEOUT_SECONDS); // Timeout seconds set in maccvs.pch + while( (TickCount() < timeOutTicks) && (!aeLinkDone) ) + { + if (WaitNextEvent(everyEvent, &theEvent, 60, nil)) + { + if( ! (SIOUXHandleOneEvent(&theEvent)) ) + { + switch (theEvent.what) + { + case kHighLevelEvent: + AEProcessAppleEvent(&theEvent); + break; + } + } + } + } +} + +char * +getenv( const char *var ) +{ + int i; + + // Look it up in the environment + + for( i=0; i<EnvC; i++ ) + { + if( strcmp(EnvVars[i], var) == 0 ) return( EnvVals[i] ); + } + + return NULL; +} + +/* Free the allocated memory */ + +void CleanUpArgsAndEnv( void ) +{ + int i; + + // Clean up the args + + for( i=0; i<ArgC; i++ ) + free( Args[i] ); + + free( Args ); + + // Clean up the environment + + for( i=0; i<EnvC; i++ ) + { free( EnvVars[i] ); free( EnvVals[i] ); } + + free( EnvVars ); + free( EnvVals ); +} + +/* + * The following blocks of code are related to the redirection of output to + * AppleEvents. + */ + +static char outBuf[AE_OUTBUF_SIZE]; +static int outBufLen = -1; + +void InitOutBuffer( void ) +{ + outBufLen = 0; +} + +void SendOutBuffer( char outputDone ) +{ + if( outBufLen ) + { + AEPutParamPtr( + &gResponseEvent, + keyDirectObject, + typeChar, + outBuf, + outBufLen); + } + if( outputDone ) + { + AEPutParamPtr( + &gResponseEvent, + 'DONE', + typeChar, + "DONE", + 4); + } + AESend( + &gResponseEvent, + &gResponseReplyEvent, + kAEWaitReply+kAENeverInteract, + kAENormalPriority, + kNoTimeOut, + nil, nil); +} + +/* + * The following three routines override the "real thing" from the CW + * SIOUX library in order to divert output to AppleEvents. + */ + +short +InstallConsole(short fd) +{ + if (outputMode == outToFile) + return 0; + + AECreateAppleEvent ('MCVS', 'DATA', + &gResponseAddress, + kAutoGenerateReturnID, + kAnyTransactionID, + &gResponseEvent); + + return 0; +} + +long WriteCharsToConsole( char *buf, long length ) +{ + char *tCh; + + if( outputMode == outToFile ) + { + write( outputFile, buf, length ); + return length; + } + + if( outBufLen == -1 ) InitOutBuffer(); + + if( (length + outBufLen) > AE_OUTBUF_SIZE ) + { + SendOutBuffer( FALSE ); + InitOutBuffer(); + } + + for( tCh = buf; tCh < (char *) (buf+length); tCh++ ) + { + if( *tCh == '\012' ) *tCh = '\015'; + + outBuf[outBufLen] = *tCh; + outBufLen++; + } + + if( noLineBuffer && ( *(buf+length) == '\015') ) + { + SendOutBuffer( FALSE ); + InitOutBuffer(); + } + + return length; +} + +void RemoveConsole( void ) +{ + CleanUpArgsAndEnv(); + + if( outputMode == outToFile ) + { + close(outputFile); + if( rename(tempOutputFileName, outputFileName) != 0 ) + SysBeep( 100 ); + return; + } + + SendOutBuffer( TRUE ); + + AEDisposeDesc( &gResponseEvent ); + AEDisposeDesc( &gResponseAddress ); +} +#endif // AE_IO_HANDLERS diff --git a/gnu/usr.bin/cvs/macintosh/filesubr.c b/gnu/usr.bin/cvs/macintosh/filesubr.c new file mode 100644 index 00000000000..5ec82998b69 --- /dev/null +++ b/gnu/usr.bin/cvs/macintosh/filesubr.c @@ -0,0 +1,707 @@ +/* filesubr.c --- subroutines for dealing with files + Jim Blandy <jimb@cyclic.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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* These functions were moved out of subr.c because they need different + definitions under operating systems (like, say, Windows NT) with different + file system semantics. */ + +#include "mac_config.h" +#include "cvs.h" + +/* + * I don't know of a convenient way to test this at configure time, or else + * I'd certainly do it there. + */ +#if defined(NeXT) +#define LOSING_TMPNAM_FUNCTION +#endif + +static int deep_remove_dir PROTO((const char *path)); + +/* + * Copies "from" to "to". + */ +void +copy_file (from, to) + const char *from; + const char *to; +{ + struct stat sb; + struct utimbuf t; + int fdin, fdout; + + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> copy(%s,%s)\n", + (server_active) ? 'S' : ' ', from, to); +#else + (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to); +#endif + if (noexec) + return; + + if ((fdin = CVS_OPEN (from, O_RDONLY)) < 0) + error (1, errno, "cannot open %s for copying", from); + if (fstat (fdin, &sb) < 0) + error (1, errno, "cannot fstat %s", from); + if ((fdout = CVS_CREAT (to, (int) sb.st_mode & 07777)) < 0) + error (1, errno, "cannot create %s for copying", to); + if (sb.st_size > 0) + { + char buf[BUFSIZ]; + int n; + + for (;;) + { + n = read (fdin, buf, sizeof(buf)); + if (n == -1) + { +#ifdef EINTR + if (errno == EINTR) + continue; +#endif + error (1, errno, "cannot read file %s for copying", from); + } + else if (n == 0) + break; + + if (write(fdout, buf, n) != n) { + error (1, errno, "cannot write file %s for copying", to); + } + } + +#ifdef HAVE_FSYNC + if (fsync (fdout)) + error (1, errno, "cannot fsync file %s after copying", to); +#endif + } + + if (close (fdin) < 0) + error (0, errno, "cannot close %s", from); + if (close (fdout) < 0) + error (1, errno, "cannot close %s", to); + + /* now, set the times for the copied file to match those of the original */ + memset ((char *) &t, 0, sizeof (t)); + t.actime = sb.st_atime; + t.modtime = sb.st_mtime; + (void) utime (to, &t); +} + +/* FIXME-krp: these functions would benefit from caching the char * & + stat buf. */ + +/* + * Returns non-zero if the argument file is a directory, or is a symbolic + * link which points to a directory. + */ +int +isdir (file) + const char *file; +{ + struct stat sb; + + if ( CVS_STAT (file, &sb) < 0) + return (0); + return (S_ISDIR (sb.st_mode)); +} + +/* + * Returns non-zero if the argument file is a symbolic link. + */ +int +islink (file) + const char *file; +{ +#ifdef S_ISLNK + struct stat sb; + + if (lstat (file, &sb) < 0) + return (0); + return (S_ISLNK (sb.st_mode)); +#else + return (0); +#endif +} + +/* + * Returns non-zero if the argument file exists. + */ +int +isfile (file) + const char *file; +{ + return isaccessible(file, F_OK); +} + +/* + * Returns non-zero if the argument file is readable. + */ +int +isreadable (file) + const char *file; +{ + return isaccessible(file, R_OK); +} + +/* + * Returns non-zero if the argument file is writable. + */ +int +iswritable (file) + const char *file; +{ + return isaccessible(file, W_OK); +} + +/* + * Returns non-zero if the argument file is accessable according to + * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid + * bits set. + */ +int +isaccessible (file, mode) + const char *file; + const int mode; +{ +#ifdef SETXID_SUPPORT + struct stat sb; + int umask = 0; + int gmask = 0; + int omask = 0; + int uid; + + if ( CVS_STAT (file, &sb) == -1) + return 0; + if (mode == F_OK) + return 1; + + uid = geteuid(); + if (uid == 0) /* superuser */ + { + if (mode & X_OK) + return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH); + else + return 1; + } + + if (mode & R_OK) + { + umask |= S_IRUSR; + gmask |= S_IRGRP; + omask |= S_IROTH; + } + if (mode & W_OK) + { + umask |= S_IWUSR; + gmask |= S_IWGRP; + omask |= S_IWOTH; + } + if (mode & X_OK) + { + umask |= S_IXUSR; + gmask |= S_IXGRP; + omask |= S_IXOTH; + } + + if (sb.st_uid == uid) + return (sb.st_mode & umask) == umask; + else if (sb.st_gid == getegid()) + return (sb.st_mode & gmask) == gmask; + else + return (sb.st_mode & omask) == omask; +#else + return CVS_ACCESS (file, mode) == 0; +#endif +} + +/* + * Open a file and die if it fails + */ +FILE * +open_file (name, mode) + const char *name; + const char *mode; +{ + FILE *fp; + + if ((fp = CVS_FOPEN (name, mode)) == NULL) + error (1, errno, "cannot open %s", name); + return (fp); +} + +/* + * Make a directory and die if it fails + */ +void +make_directory (name) + const char *name; +{ + struct stat sb; + + if ( CVS_STAT (name, &sb) == 0 && (!S_ISDIR (sb.st_mode))) + error (0, 0, "%s already exists but is not a directory", name); + if (!noexec && CVS_MKDIR (name, 0777) < 0) + error (1, errno, "cannot make directory %s", name); +} + +/* + * Make a path to the argument directory, printing a message if something + * goes wrong. + */ +void +make_directories (name) + const char *name; +{ + char *cp; + + if (noexec) + return; + + if ( CVS_MKDIR (name, 0777) == 0 || errno == EEXIST) + return; + if (! existence_error (errno)) + { + error (0, errno, "cannot make path to %s", name); + return; + } + if ((cp = strrchr (name, '/')) == NULL) + return; + *cp = '\0'; + make_directories (name); + *cp++ = '/'; + if (*cp == '\0') + return; + (void) CVS_MKDIR (name, 0777); +} + +/* Create directory NAME if it does not already exist; fatal error for + other errors. Returns 0 if directory was created; 1 if it already + existed. */ +int +mkdir_if_needed (name) + char *name; +{ + if (CVS_MKDIR (name, 0777) < 0) + { + if (errno != EEXIST +#ifdef EACCESS + /* This was copied over from the OS/2 code; I would guess it + isn't needed here but that has not been verified. */ + && errno != EACCESS +#endif + ) + error (1, errno, "cannot make directory %s", name); + return 1; + } + return 0; +} + +/* + * Change the mode of a file, either adding write permissions, or removing + * all write permissions. Either change honors the current umask setting. + */ +void +xchmod (fname, writable) + char *fname; + int writable; +{ + struct stat sb; + mode_t mode, oumask; + + if ( CVS_STAT (fname, &sb) < 0) + { + if (!noexec) + error (0, errno, "cannot stat %s", fname); + return; + } + oumask = umask (0); + (void) umask (oumask); + if (writable) + { + mode = sb.st_mode | (~oumask + & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0) + | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0) + | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0))); + } + else + { + mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask; + } + + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> chmod(%s,%o)\n", + (server_active) ? 'S' : ' ', fname, + (unsigned int) mode); +#else + (void) fprintf (stderr, "-> chmod(%s,%o)\n", fname, + (unsigned int) mode); +#endif + if (noexec) + return; + + if (chmod (fname, mode) < 0) + error (0, errno, "cannot change mode of file %s", fname); +} + +/* + * Rename a file and die if it fails + */ +void +rename_file (from, to) + const char *from; + const char *to; +{ + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> rename(%s,%s)\n", + (server_active) ? 'S' : ' ', from, to); +#else + (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to); +#endif + if (noexec) + return; + + if ( CVS_RENAME (from, to) < 0) + error (1, errno, "cannot rename file %s to %s", from, to); +} + +/* + * link a file, if possible. Warning: the Windows NT version of this + * function just copies the file, so only use this function in ways + * that can deal with either a link or a copy. + */ +int +link_file (from, to) + const char *from; + const char *to; +{ + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> link(%s,%s)\n", + (server_active) ? 'S' : ' ', from, to); +#else + (void) fprintf (stderr, "-> link(%s,%s)\n", from, to); +#endif + if (noexec) + return (0); + +#ifdef macintosh + return (symlink ( (char *)macos_fixpath(from), (char *)macos_fixpath(to))); +#else + return (link (from, to)); +#endif +} + +/* + * unlink a file, if possible. + */ +int +unlink_file (f) + const char *f; +{ + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> unlink(%s)\n", + (server_active) ? 'S' : ' ', f); +#else + (void) fprintf (stderr, "-> unlink(%s)\n", f); +#endif + if (noexec) + return (0); + + return ( CVS_UNLINK (f)); +} + +/* + * Unlink a file or dir, if possible. If it is a directory do a deep + * removal of all of the files in the directory. Return -1 on error + * (in which case errno is set). + */ +int +unlink_file_dir (f) + const char *f; +{ + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> unlink_file_dir(%s)\n", + (server_active) ? 'S' : ' ', f); +#else + (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); +#endif + if (noexec) + return (0); + + /* For at least some unices, if root tries to unlink() a directory, + instead of doing something rational like returning EISDIR, + the system will gleefully go ahead and corrupt the filesystem. + So we first call isdir() to see if it is OK to call unlink(). This + doesn't quite work--if someone creates a directory between the + call to isdir() and the call to unlink(), we'll still corrupt + the filesystem. Where is the Unix Haters Handbook when you need + it? */ + if (isdir(f)) + return deep_remove_dir(f); + else + { + if ( CVS_UNLINK (f) != 0) + return -1; + } + /* We were able to remove the file from the disk */ + return 0; +} + +/* Remove a directory and everything it contains. Returns 0 for + * success, -1 for failure (in which case errno is set). + */ + +static int +deep_remove_dir (path) + const char *path; +{ + DIR *dirp; + struct dirent *dp; + char buf[PATH_MAX]; + + if (CVS_RMDIR (path) != 0 && (errno == ENOTEMPTY || errno == EEXIST)) + { + if ((dirp = CVS_OPENDIR (path)) == NULL) + /* If unable to open the directory return + * an error + */ + return -1; + + while ((dp = readdir (dirp)) != NULL) + { + if (strcmp (dp->d_name, ".") == 0 || + strcmp (dp->d_name, "..") == 0) + continue; + + sprintf (buf, "%s/%s", path, dp->d_name); + + /* See comment in unlink_file_dir explanation of why we use + isdir instead of just calling unlink and checking the + status. */ + if (isdir(buf)) + { + if (deep_remove_dir(buf)) + { + closedir(dirp); + return -1; + } + } + else + { + if (CVS_UNLINK (buf) != 0) + { + closedir(dirp); + return -1; + } + } + } + closedir (dirp); + return CVS_RMDIR (path); + } + + /* Was able to remove the directory return 0 */ + return 0; +} + +/* Read NCHARS bytes from descriptor FD into BUF. + Return the number of characters successfully read. + The number returned is always NCHARS unless end-of-file or error. */ +static size_t +block_read (fd, buf, nchars) + int fd; + char *buf; + size_t nchars; +{ + char *bp = buf; + size_t nread; + + do + { + nread = read (fd, bp, nchars); + if (nread == (size_t)-1) + { +#ifdef EINTR + if (errno == EINTR) + continue; +#endif + return (size_t)-1; + } + + if (nread == 0) + break; + + bp += nread; + nchars -= nread; + } while (nchars != 0); + + return bp - buf; +} + + +/* + * Compare "file1" to "file2". Return non-zero if they don't compare exactly. + */ +int +xcmp (file1, file2) + const char *file1; + const char *file2; +{ + char *buf1, *buf2; + struct stat sb1, sb2; + int fd1, fd2; + int ret; + + if ((fd1 = CVS_OPEN (file1, O_RDONLY)) < 0) + error (1, errno, "cannot open file %s for comparing", file1); + if ((fd2 = CVS_OPEN (file2, O_RDONLY)) < 0) + error (1, errno, "cannot open file %s for comparing", file2); + if (fstat (fd1, &sb1) < 0) + error (1, errno, "cannot fstat %s", file1); + if (fstat (fd2, &sb2) < 0) + error (1, errno, "cannot fstat %s", file2); + + /* A generic file compare routine might compare st_dev & st_ino here + to see if the two files being compared are actually the same file. + But that won't happen in CVS, so we won't bother. */ + + if (sb1.st_size != sb2.st_size) + ret = 1; + else if (sb1.st_size == 0) + ret = 0; + else + { + /* FIXME: compute the optimal buffer size by computing the least + common multiple of the files st_blocks field */ + size_t buf_size = 8 * 1024; + size_t read1; + size_t read2; + + buf1 = xmalloc (buf_size); + buf2 = xmalloc (buf_size); + + do + { + read1 = block_read (fd1, buf1, buf_size); + if (read1 == (size_t)-1) + error (1, errno, "cannot read file %s for comparing", file1); + + read2 = block_read (fd2, buf2, buf_size); + if (read2 == (size_t)-1) + error (1, errno, "cannot read file %s for comparing", file2); + + /* assert (read1 == read2); */ + + ret = memcmp(buf1, buf2, read1); + } while (ret == 0 && read1 == buf_size); + + free (buf1); + free (buf2); + } + + (void) close (fd1); + (void) close (fd2); + return (ret); +} + +/* Just in case this implementation does not define this. */ +#ifndef L_tmpnam +#define L_tmpnam 50 +#endif + +#ifdef LOSING_TMPNAM_FUNCTION +char * +cvs_temp_name () +{ + char value[L_tmpnam + 1]; + + /* FIXME: Should be using TMPDIR. */ + strcpy (value, "/tmp/cvsXXXXXX"); + mktemp (value); + return xstrdup (value); +} +#else +/* Generate a unique temporary filename. Returns a pointer to a newly + malloc'd string containing the name. Returns successfully or not at + all. */ +char * +cvs_temp_name () +{ + char value[L_tmpnam + 1]; + char *retval; + + /* FIXME: should be using TMPDIR, perhaps by using tempnam on systems + which have it. */ + retval = tmpnam (value); + if (retval == NULL) + error (1, errno, "cannot generate temporary filename"); + return xstrdup (retval); +} +#endif + +/* Return non-zero iff FILENAME is absolute. + Trivial under Unix, but more complicated under other systems. */ +int +isabsolute (filename) + const char *filename; +{ + return filename[0] == '/'; +} + + +/* Return a pointer into PATH's last component. */ +char * +last_component (path) + char *path; +{ + char *last = strrchr (path, '/'); + + if (last) + return last + 1; + else + return path; +} + +/* Return the home directory. Returns a pointer to storage + managed by this function or its callees (currently getenv). */ +char * +get_homedir () +{ + return getenv ("HOME"); +} + +/* See cvs.h for description. On unix this does nothing, because the + shell expands the wildcards. */ +void +expand_wild (argc, argv, pargc, pargv) + int argc; + char **argv; + int *pargc; + char ***pargv; +{ + int i; + *pargc = argc; + *pargv = (char **) xmalloc (argc * sizeof (char *)); + for (i = 0; i < argc; ++i) + (*pargv)[i] = xstrdup (argv[i]); +} diff --git a/gnu/usr.bin/cvs/macintosh/mac_config.h b/gnu/usr.bin/cvs/macintosh/mac_config.h new file mode 100644 index 00000000000..241a5dda64f --- /dev/null +++ b/gnu/usr.bin/cvs/macintosh/mac_config.h @@ -0,0 +1,15 @@ +/* + * mac_config.h - Macintosh-specific definitions and configuration settings + * + * MDLadwig <mike@twinpeaks.prc.com> --- July 1996 + */ +// MacCVS with AppleEvent IO and no console support. If this is not defined then IO will be +// via the SIOUX console +//#define AE_IO_HANDLERS +// Setup includes to use MSL instead of Plum-Hall ANSI library +//#define MSL_LIBRARY +#define AE_OUTBUF_SIZE 32000 // Maximum size of output Apple Events +#define AE_TIMEOUT_SECONDS 30 // Timeout for AppleEvents command recipt +#define ArgMax 512 // Maximum number of Args passed via AE command +#define EnvMax 512 // Maximum number of Env Vars passed via AE command +#define STACK_SIZE_68K 98305 // Stack size for 68k version (PPC set in CW prefs) diff --git a/gnu/usr.bin/cvs/macintosh/mac_init.c b/gnu/usr.bin/cvs/macintosh/mac_init.c new file mode 100644 index 00000000000..69f355b6e52 --- /dev/null +++ b/gnu/usr.bin/cvs/macintosh/mac_init.c @@ -0,0 +1,71 @@ +/* + * mac_init.c --- routines to initialize and cleanup macintosh behavior + * + * MDLadwig <mike@twinpeaks.prc.com> --- June 1996 + */ +#include "mac_config.h" + +#ifdef __POWERPC__ +#include <MacHeadersPPC> +#else +#include <MacHeaders68K> +#endif + +#include <sioux.h> +#include <GUSI.h> + +extern char **Args; +extern char **EnvVars, **EnvVals; +extern int ArgC; +extern int EnvC; + +extern int argc; +extern char **argv; + +void +macos_error_cleanup( void ) +{ + Lock_Cleanup(); + RemoveConsole(); // FIXME - Ugly, but necessary until MW fixes _exit +} + +void +InitializeMacToolbox( void ) +{ + #ifndef __POWERPC__ + SetApplLimit(GetApplLimit() - STACK_SIZE_68K); + #endif + + MaxApplZone(); + MoreMasters(); +} + +void +MacOS_Initialize( int *argc, char ***argv ) +{ + InitializeMacToolbox(); + + GUSISetup(GUSIwithSIOUXSockets); + GUSISetup(GUSIwithUnixSockets); + + SIOUXSettings.showstatusline = TRUE; + SIOUXSettings.autocloseonquit = FALSE; + SIOUXSettings.asktosaveonclose = TRUE; + + #ifdef AE_IO_HANDLERS + GetUnixCommandEnvironment( "cvs" ); + *argc = ArgC; + *argv = Args; + #else + *argc = ccommand(argv); + #endif + + error_set_cleanup (macos_error_cleanup); +} + +void +MacOS_Cleanup ( void ) +{ + RemoveConsole(); // FIXME - Ugly, but necessary until MW fixes _exit +} + diff --git a/gnu/usr.bin/cvs/macintosh/maccvs.r b/gnu/usr.bin/cvs/macintosh/maccvs.r new file mode 100644 index 00000000000..0e5c7e46f5f --- /dev/null +++ b/gnu/usr.bin/cvs/macintosh/maccvs.r @@ -0,0 +1,52 @@ +#define SystemSevenOrLater 1 + +#include "Types.r" +#include "SysTypes.r" +#include "BalloonTypes.r" +#include "AEUserTermTypes.r" +#include "AERegistry.r" +#include "AEObjects.r" + +#define __kPrefSize 512 +#define __kMinSize 512 + +#define GUSI_PREF_VERSION '0150' + +#include "GUSI.r" + +resource 'GU·I' (GUSIRsrcID) { + 'TEXT', 'CWIE', noAutoSpin, useChdir, approxStat, + noTCPDaemon, noUDPDaemon, + noConsole, + {}; +}; + +resource 'aete' (0, "MacCVS Suite") { + 0x01, 0x00, english, roman, + { + "MacCVS Suite", "Custom events", 'MCVS', 1, 1, + { + "Do Command", "Execute a CVS command", 'misc', 'dosc', + 'null', "", replyOptional, singleItem, notEnumerated, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, + 'TEXT', "Command to execute", directParamRequired, singleItem, notEnumerated, + changesState, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, + { + "Mode", 'MODE', 'MODE', "Mode (AE, File).", optional, singleItem, enumerated, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, + "Environment", 'ENVT', 'TEXT', "Environment variables.", optional, listOfItems, notEnumerated, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, + "Filename", 'FILE', 'TEXT', "Output file path.", optional, singleItem, notEnumerated, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, + "Pathway", 'SPWD', 'TEXT', "Starting pathway.", optional, singleItem, notEnumerated, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, + "NoLineBuffer", 'LBUF', 'bool', "if true, send each result line as separate AE.", optional, singleItem, notEnumerated, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, + } + }, + {}, + {}, + { + 'MODE', + { + "AE", 'TOAE', "Redirect standard output to apple events", + "File", 'FILE', "Redirect standard output to a file", + }, + }, + } +}; + diff --git a/gnu/usr.bin/cvs/macintosh/pwd.h b/gnu/usr.bin/cvs/macintosh/pwd.h new file mode 100644 index 00000000000..d451dbc0e4d --- /dev/null +++ b/gnu/usr.bin/cvs/macintosh/pwd.h @@ -0,0 +1,37 @@ +/********************************************************************* +Project : GUSI - Grand Unified Socket Interface +File : pwd.h - Provide mission header ioctl.h for CodeWarrior +Author : Matthias Neeracher +Language : MPW C/C++ +$Log: pwd.h,v $ +Revision 1.1 1996/10/18 03:36:59 tholo +Initial revision + +Revision 1.1 1996/07/26 20:08:29 kingdon +Check in new macintosh directory from Mike Ladwig. I believe that this +checkin contains exactly the tarfile he sent to me, with the exception +of the files SIOUX.c SIOUXGlobals.h SIOUXMenus.h SIOUXWindows.h which +are copyright Metrowerks and which we therefore cannot distribute. + +*********************************************************************/ + +#include <sys/types.h> + +struct group { /* see getgrent(3) */ + char *gr_name; + char *gr_passwd; + gid_t gr_gid; + char **gr_mem; +}; + +struct passwd { + char *pw_name; + char *pw_passwd; + uid_t pw_uid; + gid_t pw_gid; + char *pw_age; + char *pw_comment; + char *pw_gecos; + char *pw_dir; + char *pw_shell; +};
\ No newline at end of file diff --git a/gnu/usr.bin/cvs/man/ChangeLog b/gnu/usr.bin/cvs/man/ChangeLog index 69017c948e2..35feb355390 100644 --- a/gnu/usr.bin/cvs/man/ChangeLog +++ b/gnu/usr.bin/cvs/man/ChangeLog @@ -1,3 +1,36 @@ +Tue Oct 1 14:01:28 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.1: Revert all changes by Greg Woods since CVS 1.8.86. They + are for new features which are not appropriate at this stage of + the release process. + +Mon Sep 30 18:21:05 1996 Greg A. Woods <woods@most.weird.com> + + * cvs.1: document -D, -g, DIFFBIN, and GREPBIN. + +Mon Sep 16 23:22:16 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvsbug.8: Remove references to cvsbug.el (or other aspects of + emacs interface) and cvsbug.info (or other aspects of texinfo + documentation). Neither one has ever existed. + +Wed Jul 24 19:01:35 1996 Ian Lance Taylor <ian@cygnus.com> + + * cvs.1: Document -x. + +Fri Sep 13 11:01:59 1996 Greg A. Woods <woods@clapton.seachange.com> + + * cvs.1: add description of -k and -K for rdiff. Mention that + import allows '-b 1' to import to the trunk. + +Tue May 14 10:23:59 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * cvs.1: Add cvs.texinfo to the SEE ALSO section. Replace an out + of date list of default ignore patterns with a reference to + cvs.texinfo (if someone wants to undo this change that is OK with + me but I did it this way because it isn't clear people would + actually keep cvs.1 up to date). + Wed Mar 13 17:06:39 1996 Jim Kingdon <kingdon@harvey.cyclic.com> * cvsinit.8: Removed. diff --git a/gnu/usr.bin/cvs/man/cvsbug.8 b/gnu/usr.bin/cvs/man/cvsbug.8 index 496ef1458b6..23e17957781 100644 --- a/gnu/usr.bin/cvs/man/cvsbug.8 +++ b/gnu/usr.bin/cvs/man/cvsbug.8 @@ -211,33 +211,11 @@ code. /tmp/pf$$ copy of empty PR form, for testing purposes .br /tmp/pbad$$ file for rejected PRs -.SH EMACS USER INTERFACE -An Emacs user interface for -.B cvsbug -with completion of field values is part of the -.B cvsbug -distribution (invoked with -.BR "M-x cvsbug" ). -See the file -.B cvsbug.info -or the ASCII file -.B INSTALL -in the top level directory of the distribution for configuration and -installation information. The Emacs LISP template file is -.B cvsbug-el.in -and is installed as -.BR cvsbug.el . .SH INSTALLATION AND CONFIGURATION See -.B cvsbug.info -or .B INSTALL for installation instructions. .SH SEE ALSO -.I Reporting Problems Using cvsbug -(also installed as the GNU Info file -.BR cvsbug.info ). -.LP .BR gnats (l), .BR query-pr (1), .BR edit-pr (1), diff --git a/gnu/usr.bin/cvs/os2/ChangeLog b/gnu/usr.bin/cvs/os2/ChangeLog index 745a1687ef3..db022dae2da 100644 --- a/gnu/usr.bin/cvs/os2/ChangeLog +++ b/gnu/usr.bin/cvs/os2/ChangeLog @@ -1,3 +1,63 @@ +Thu Sep 26 14:15:55 1996 Jim Kingdon <kingdon@cyclic.com> + + * filesubr.c (mkdir_if_needed): mkdir only takes one + argument on OS/2. + +Wed Sep 25 14:31:51 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * options.h (TMPDIR_DFLT): Change from c:\temp to c:\\temp. + +Tue Sep 24 14:39:40 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * options.h: Add TMPDIR_DFLT. + +Mon Aug 26 12:31:10 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (mkdir_if_needed): Added. + +Fri Aug 16 16:05:29 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * Makefile.in (installdirs): new (empty) target + +Mon Aug 12 22:59:40 1996 Jim Kingdon (unknown@beezley) + + * filesubr.c (fncmp): Fix typo (n1 -> n2) which had caused the + function to always return 0. + + * Makefile.in (COMMON_OBJECTS): Add buffer.obj. + (COMMON_SOURCES): Add buffer.c. + (zlib_srcdir,ZLIB_OBJECTS): Added. + (cvs.exe): Also link with ZLIB_OBJECTS. + (OBJECTS): Add ZLIB_OBJECTS. + (LIB_OBJECTS): Add valloc.obj. + (COMMON_OBJECTS): Add zlib.obj. + +Mon Aug 12 16:25:32 1996 Steffen Siebert <siebert@susan.logware.de> + and Jim Kingdon (unknown@beezley) + + * Makefile.in (cvs.exe): Use subst so that we link with \ + and compile with / without needing to mess with SL. + * README: Adjust accordingly. + +Mon Jul 15 22:32:13 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * config.h: Remove EXECUTE_PERMISSION_LOSES; it is no longer used + anywhere (superceded by CHMOD_BROKEN). + +Fri Jun 7 13:07:37 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * config.h: Change INITIALIZE_SOCKET_SUBSYSTEM to + SYSTEM_INITIALIZE to reflect change in ../src/main.c. + +Tue May 14 13:38:51 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (cvs_temp_name): New function. + +Tue May 7 10:50:13 MET DST 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * filesubr.c (expand_wild): Real implementation (like + Windows-NT) for expanding. + Thu Apr 25 09:28:10 1996 Jim Kingdon <kingdon@harvey.cyclic.com> * README: Add note about LF vs. CRLF in makefile. diff --git a/gnu/usr.bin/cvs/os2/Makefile.in b/gnu/usr.bin/cvs/os2/Makefile.in index 169bfd6aac5..1c2268b67a7 100644 --- a/gnu/usr.bin/cvs/os2/Makefile.in +++ b/gnu/usr.bin/cvs/os2/Makefile.in @@ -6,10 +6,9 @@ project: cvs.exe # .SUFFIXES .c .obj .exe -# path slash -# Maintainers: always leave this set to "/", because `make dist' has -# to work on Unix systems. See os2/README to find out why we have -# this var. +# path slash. This was introduced so that it can be set to \ +# instead of / for linking, but now that the cvs.exe rule uses +# subst to produce \, it should be possible to nuke SL. SL = / # Directory in which to install executables. @@ -24,6 +23,8 @@ top_srcdir = @top_srcdir@ lib_dir = @top_srcdir@${SL}lib cvs_srcdir = @top_srcdir@${SL}src +zlib_dir = ${top_srcdir}/zlib + # Do we need these? # prefix = /usr/local # exec_prefix = ${prefix} @@ -34,7 +35,7 @@ CINC = -Is:${SL}ibmcpp${SL}include -Is:${SL}toolkt21${SL}c${SL}os2h # This says we are building an object file, not a full executable. OBJ_CFLAGS = -C+ CFLAGS = -W3 -Wpro+rea+tru+use+ -Ti+ -Ss+ -Gd+ -Gm+ -G4 -Q+ -Sm ${CINC} \ - -I${srcdir} -I${lib_dir} -I${cvs_srcdir} \ + -I${srcdir} -I${lib_dir} -I${cvs_srcdir} -I${zlib_dir} \ -DIBM_CPP -DHAVE_CONFIG_H \ -DTCPIP_IBM -Is:${SL}ibmtcpip${SL}include @@ -88,9 +89,11 @@ OS2_SOURCES = \ ${srcdir}${SL}getpass.c # sources we use from the common src dir, ..${SL}src +# FIXME: Is this used anywhere? I don't think it is. COMMON_SOURCES = \ ${cvs_srcdir}${SL}add.c \ ${cvs_srcdir}${SL}admin.c \ + ${cvs_srcdir}${SL}buffer.c \ ${cvs_srcdir}${SL}checkin.c \ ${cvs_srcdir}${SL}checkout.c \ ${cvs_srcdir}${SL}classify.c \ @@ -141,6 +144,7 @@ COMMON_SOURCES = \ # end of $COMMON_SOURCES # sources from ..${SL}lib +# FIXME: Is this used anywhere? I don't think it is. LIB_SOURCES = \ ${lib_dir}${SL}getopt.c \ ${lib_dir}${SL}getopt1.c \ @@ -175,6 +179,7 @@ OS2_OBJECTS = \ COMMON_OBJECTS = \ ${cvs_srcdir}${SL}add.obj \ ${cvs_srcdir}${SL}admin.obj \ + ${cvs_srcdir}${SL}buffer.obj \ ${cvs_srcdir}${SL}checkin.obj \ ${cvs_srcdir}${SL}checkout.obj \ ${cvs_srcdir}${SL}classify.obj \ @@ -221,7 +226,8 @@ COMMON_OBJECTS = \ ${cvs_srcdir}${SL}watch.obj \ ${cvs_srcdir}${SL}wrapper.obj \ ${cvs_srcdir}${SL}vers_ts.obj \ - ${cvs_srcdir}${SL}version.obj + ${cvs_srcdir}${SL}version.obj \ + ${cvs_srcdir}/zlib.obj # end of $COMMON_OBJECTS # objects from ..${SL}lib @@ -237,11 +243,26 @@ LIB_OBJECTS = \ ${lib_dir}${SL}xgetwd.obj \ ${lib_dir}${SL}md5.obj \ ${lib_dir}${SL}fnmatch.obj \ - ${lib_dir}${SL}regex.obj + ${lib_dir}${SL}regex.obj \ + ${lib_dir}/valloc.obj + +ZLIB_OBJECTS = ${zlib_dir}/adler32.obj \ + ${zlib_dir}/compress.obj \ + ${zlib_dir}/crc32.obj \ + ${zlib_dir}/uncompr.obj \ + ${zlib_dir}/deflate.obj \ + ${zlib_dir}/trees.obj \ + ${zlib_dir}/zutil.obj \ + ${zlib_dir}/inflate.obj \ + ${zlib_dir}/infblock.obj \ + ${zlib_dir}/inftrees.obj \ + ${zlib_dir}/infcodes.obj \ + ${zlib_dir}/infutil.obj \ + ${zlib_dir}/inffast.obj SOURCES = ${COMMON_SOURCES} ${LIB_SOURCES} ${OS2_SOURCES} HEADERS = ${COMMON_HEADERS} ${OS2_HEADERS} -OBJECTS = ${COMMON_OBJECTS} ${LIB_OBJECTS} ${OS2_OBJECTS} +OBJECTS = ${COMMON_OBJECTS} ${LIB_OBJECTS} ${OS2_OBJECTS} ${ZLIB_OBJECTS} DISTFILES = ${OS2_HEADERS} ${OS2_SOURCES} \ ${srcdir}${SL}README ${srcdir}${SL}ChangeLog \ @@ -253,6 +274,9 @@ all: .PHONY: all install uninstall all install uninstall: +installdirs: +.PHONY: installdirs + .PHONY: tags TAGS tags TAGS: @@ -289,16 +313,24 @@ install-cvs: cvs.exe # There seems to be no ICC option for specifying library locations, so # we must `set' the path in the compilation environment. Urgkle. +# +# I'm having some weird problem with "\" vs. "/". If I build +# with "\" as the path separator in the makefile, the compiler dumps +# core. Go figure. If I build with "/" as the path separator, the +# object files compile fine but the linker thinks the "/" is indicating +# options and gets all confused (though at least it doesn't dump core). +# So, use subst to compile with "/" and link with "\". cvs.exe: ${OBJECTS} echo Creating icc.in... echo -Q+ -Ti+ -Fe$@ -B"/batch" -B"/NOE" > icc.in - echo ${OS2_OBJECTS} >> icc.in - echo ${LIB_OBJECTS} >> icc.in - echo ${COMMON_OBJECTS} >> icc.in - echo ${TCPIPLIB} >> icc.in - echo ${ARGVLIB} >> icc.in + echo $(subst /,\,$(OS2_OBJECTS)) >> icc.in + echo $(subst /,\,$(LIB_OBJECTS)) >> icc.in + echo $(subst /,\,$(COMMON_OBJECTS)) >> icc.in + echo $(subst /,\,$(ZLIB_OBJECTS)) >> icc.in + echo $(subst /,\,$(TCPIPLIB)) >> icc.in + echo $(subst /,\,$(ARGVLIB)) >> icc.in echo Creating icc.in... done. - set LIB=${LIB} & icc @icc.in + set LIB=$(subst /,\,$(LIB)) & icc @icc.in # cvs.obj: ${OBJECTS} ${SOURCES} ${HEADERS} diff --git a/gnu/usr.bin/cvs/os2/README b/gnu/usr.bin/cvs/os2/README index 385c2d6b3ce..f46fdccafb3 100644 --- a/gnu/usr.bin/cvs/os2/README +++ b/gnu/usr.bin/cvs/os2/README @@ -3,26 +3,10 @@ You'll need to edit the makefile to reflect your system's paths (unless you're our customer for this port, in which case the paths are correct because we did the port on your machine. :-) ). - I'm having some weird problem with "\" vs. "/". If I build -with "\" as the path separator in the makefile, the compiler dumps -core. Go figure. If I build with "/" as the path separator, the -object files compile fine but the linker thinks the "/" is indicating -options and gets all confused (though at least it doesn't dump core). - - Right now the solution is to have a makefile variable called -SL, which must be set to "/" for the first invocation of make and "\" -for the second (the first pass will successfully build the object -files, but you can expect it do die with "unknown options" errors at -link time). - - $SL is defined near the top of the makefile. If you're going -to set $SL in the makefile itself, make sure to quote it ("\\"). On -the command line (i.e., "make SL=\"), I believe just one will do. - - That should be all -- edit the makefile, do "make" twice -(changing $SL the second time), and get os2\cvs.exe. Assuming you -have edited the `install_dir' variable in the Makefile, you may type -"make install-cvs" to put cvs.exe in the right place. + That should be all -- edit the makefile, do "make" and get +os2\cvs.exe. Assuming you have edited the `install_dir' variable in +the Makefile, you may type "make install-cvs" to put cvs.exe in the +right place. If the makefile has linefeeds only at the end of lines, make (at least the port of GNU make that I have) will interpret it diff --git a/gnu/usr.bin/cvs/os2/config.h b/gnu/usr.bin/cvs/os2/config.h index ea86c8077b9..37843623c2a 100644 --- a/gnu/usr.bin/cvs/os2/config.h +++ b/gnu/usr.bin/cvs/os2/config.h @@ -16,12 +16,6 @@ We just want to avoid a redefinition error message. */ #undef _ALL_SOURCE -/* Define if type char is unsigned and you are not using gcc. */ -/* We wrote a little test program whose output suggests that char is - signed on this system. Go back and check the verdict when CVS - is configured on floss... */ -#undef __CHAR_UNSIGNED__ - /* Define to empty if the keyword does not work. */ /* Const is working. */ #undef const @@ -48,10 +42,6 @@ /* Documentation says yup; haven't verified experimentally. */ #define HAVE_UTIME_NULL 1 -/* We don't appear to have inline functions, so just expand "inline" - to "". */ -#define inline - /* Define if on MINIX. */ /* Hah. */ #undef _MINIX @@ -322,14 +312,12 @@ extern void convert_file (char *INFILE, int INFLAGS, #define RSH_NEEDS_BINARY_FLAG 1 /* OS/2 doesn't really have user/group permissions, at least not - according to the C library manual pages. So we'll make decoys. */ + according to the C library manual pages. So we'll make decoys. + (This was partly introduced for an obsolete reason, now taken care + of by CHMOD_BROKEN, but I haven't carefully looked at every case + (in particular mode_to_string), so it might still be needed). */ #define NEED_DECOY_PERMISSIONS 1 /* see system.h */ -/* See client.c. Setting execute bits with chmod seems to lose under - OS/2, although in some places the documentation grudgingly admits - to the existence of execute bits. */ -#define EXECUTE_PERMISSION_LOSES 1 - /* For the access() function, for which OS/2 has no pre-defined @@ -345,7 +333,7 @@ extern void convert_file (char *INFILE, int INFLAGS, /* So "tcpip.h" gets included in lib/system.h: */ #define USE_OWN_TCPIP_H 1 /* The IBM TCP/IP library gets initialized in main(): */ -#define INITIALIZE_SOCKET_SUBSYSTEM init_sockets +#define SYSTEM_INITIALIZE(pargc,pargv) init_sockets() extern void init_sockets(); /* Under OS/2, we have our own popen() and pclose()... */ diff --git a/gnu/usr.bin/cvs/os2/filesubr.c b/gnu/usr.bin/cvs/os2/filesubr.c index fdd0753e032..6236a7415ab 100644 --- a/gnu/usr.bin/cvs/os2/filesubr.c +++ b/gnu/usr.bin/cvs/os2/filesubr.c @@ -22,17 +22,12 @@ file system semantics. */ #include <io.h> +#define INCL_DOSFILEMGR /* File Manager values */ +#define INCL_DOSERRORS +#include <os2.h> #include "cvs.h" -/* - * I don't know of a convenient way to test this at configure time, or else - * I'd certainly do it there. -JimB - */ -#if defined(NeXT) -#define LOSING_TMPNAM_FUNCTION -#endif - static int deep_remove_dir PROTO((const char *path)); /* @@ -266,6 +261,41 @@ make_directories (name) (void) mkdir (name); } +/* Create directory NAME if it does not already exist; fatal error for + other errors. Returns 0 if directory was created; 1 if it already + existed. */ +int +mkdir_if_needed (name) + char *name; +{ + if (mkdir (name) < 0) + { + /* Now, let me get this straight. In IBM C/C++ + under OS/2, the error string for EEXIST is: + + "The file already exists", + + and the error string for EACCESS is: + + "The file or directory specified is read-only". + + Nonetheless, mkdir() will set EACCESS if the + directory *exists*, according both to the + documentation and its actual behavior. + + I'm sure that this made sense, to someone, + somewhere, sometime. Just not me, here, now. */ + if (errno != EEXIST +#ifdef EACCESS + && errno != EACCESS +#endif + ) + error (1, errno, "cannot make directory %s", name); + return 1; + } + return 0; +} + /* * Change the mode of a file, either adding write permissions, or removing * all write permissions. Adding write permissions honors the current umask @@ -656,7 +686,7 @@ fncmp (const char *n1, const char *n2) == OS2_filename_classes[(unsigned char) *n2])) n1++, n2++; return (OS2_filename_classes[(unsigned char) *n1] - - OS2_filename_classes[(unsigned char) *n1]); + - OS2_filename_classes[(unsigned char) *n2]); } /* Fold characters in FILENAME to their canonical forms. @@ -672,7 +702,23 @@ fnfold (char *filename) } } - + +/* Generate a unique temporary filename. Returns a pointer to a newly + malloc'd string containing the name. Returns successfully or not at + all. */ +char * +cvs_temp_name () +{ + char value[L_tmpnam + 1]; + char *retval; + + /* FIXME: Does OS/2 have some equivalent to TMPDIR? */ + retval = tmpnam (value); + if (retval == NULL) + error (1, errno, "cannot generate temporary filename"); + return xstrdup (retval); +} + /* Return non-zero iff FILENAME is absolute. Trivial under Unix, but more complicated under other systems. */ int @@ -739,8 +785,7 @@ get_homedir () return getenv ("HOME"); } -/* See cvs.h for description. On OS/2 this does nothing, but it probably - should be expanding wildcards like on NT. */ +/* See cvs.h for description. */ void expand_wild (argc, argv, pargc, pargv) int argc; @@ -749,8 +794,87 @@ expand_wild (argc, argv, pargc, pargv) char ***pargv; { int i; - *pargc = argc; - *pargv = (char **) xmalloc (argc * sizeof (char *)); + int new_argc; + char **new_argv; + /* Allocated size of new_argv. We arrange it so there is always room for + one more element. */ + int max_new_argc; + + new_argc = 0; + /* Add one so this is never zero. */ + max_new_argc = argc + 1; + new_argv = (char **) xmalloc (max_new_argc * sizeof (char *)); for (i = 0; i < argc; ++i) - (*pargv)[i] = xstrdup (argv[i]); + { + HDIR FindHandle = 0x0001; + FILEFINDBUF3 FindBuffer; + ULONG FindCount = 1; + APIRET rc; /* Return code */ +#define ALL_FILES (FILE_ARCHIVED|FILE_DIRECTORY|FILE_SYSTEM|FILE_HIDDEN|FILE_READONLY) + + rc = DosFindFirst(argv[i], /* File pattern */ + &FindHandle, /* Directory search handle */ + ALL_FILES, /* Search attribute */ + (PVOID) &FindBuffer, /* Result buffer */ + sizeof(FindBuffer), /* Result buffer length */ + &FindCount, /* Number of entries to find */ + FIL_STANDARD); /* Return level 1 file info */ + + if (rc != 0) + { + if (rc == ERROR_FILE_NOT_FOUND) + { + /* No match. The file specified didn't contain a wildcard (in which case + we clearly should return it unchanged), or it contained a wildcard which + didn't match (in which case it might be better for it to be an error, + but we don't try to do that). */ + new_argv [new_argc++] = xstrdup (argv[i]); + if (new_argc == max_new_argc) + { + max_new_argc *= 2; + new_argv = xrealloc (new_argv, max_new_argc * sizeof (char *)); + } + } + else + { + error (1, rc, "cannot find %s", argv[i]); + } + } + else + { + while (1) + { + /* + * Don't match ".", "..", and files starting with '.' + * (unless pattern also starts with '.'). This is + * (more or less) what standard Unix globbing does. + */ + if ((strcmp(FindBuffer.achName, ".") != 0) && + (strcmp(FindBuffer.achName, "..") != 0) && + ((argv[i][0] == '.') || (FindBuffer.achName[0] != '.'))) + { + new_argv [new_argc++] = xstrdup (FindBuffer.achName); + if (new_argc == max_new_argc) + { + max_new_argc *= 2; + new_argv = xrealloc (new_argv, max_new_argc * sizeof (char *)); + } + } + + rc = DosFindNext(FindHandle, + (PVOID) &FindBuffer, + sizeof(FindBuffer), + &FindCount); + if (rc == ERROR_NO_MORE_FILES) + break; + else if (rc != NO_ERROR) + error (1, rc, "cannot find %s", argv[i]); + } + rc = DosFindClose(FindHandle); + if (rc != 0) + error (1, rc, "cannot close %s", argv[i]); + } + } + *pargc = new_argc; + *pargv = new_argv; } diff --git a/gnu/usr.bin/cvs/os2/options.h b/gnu/usr.bin/cvs/os2/options.h index f58b0becfce..1de53451f15 100644 --- a/gnu/usr.bin/cvs/os2/options.h +++ b/gnu/usr.bin/cvs/os2/options.h @@ -123,6 +123,17 @@ #endif /* + * The password-authenticating server creates a temporary checkout of + * the affected files. The variable TMPDIR_DFLT (or even better, the + * command-line option "-T" in the line for CVS in /etc/inetd.conf) + * can be used to specify the used directory. This directory will + * also be used for other temporary files. + */ +#ifndef TMPDIR_DFLT +#define TMPDIR_DFLT "c:\\temp" +#endif + +/* * The default editor to use, if one does not specify the "-e" option to cvs, * or does not have an EDITOR environment variable. I set this to just "vi", * and use the shell to find where "vi" actually is. This allows sites with diff --git a/gnu/usr.bin/cvs/src/ChangeLog b/gnu/usr.bin/cvs/src/ChangeLog index 99161b09557..fea7afaa183 100644 --- a/gnu/usr.bin/cvs/src/ChangeLog +++ b/gnu/usr.bin/cvs/src/ChangeLog @@ -1,3 +1,2217 @@ +Fri Oct 4 15:11:46 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * server.c (server_cleanup): Temporarily clear noexec when calling + unlink_file_dir. This is so we clean up the temp directory even + when the -n global option is specified. + +Wed Oct 2 10:47:33 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * client.c (send_repository): initialize some variables before + first usage + +Tue Oct 1 13:01:24 1996 Jim Blandy <jimb@floss.cyclic.com> + + Revert some of Greg's changes; they're welcome later, but we're + trying to keep CVS stable for pre-release testing at the moment. + * checkin.c, commit.c, cvs.h, diff.c, import.c, main.c, no_diff.c, + options.h.in, patch.c, rcs.c, rcs.h, rcscmds.c, sanity.sh, update.c: + Revert changes of Sep 29 and 30. + +Tue Oct 1 13:17:31 1996 Ian Lance Taylor <ian@cygnus.com> + + Make sure the server temporary directory is removed even if + Max-dotdot is used. + * server.c (orig_server_temp_dir): New static variable. + (serve_max_dotdot): Don't free server_temp_dir if it is the same + as orig_server_temp_dir. + (do_cvs_command): Use orig_server_temp_dir in error message. + (server_cleanup): Remove orig_server_temp_dir. + (server): Set orig_server_temp_dir. Remove incorrect indentation + of error message. + + * import.c (update_rcs_file): Restore new argument to + RCS_checkout, removed in last patch. + +Tue Oct 1 00:32:55 1996 Jim Blandy <jimb@floss.cyclic.com> + + * import.c: Revert Greg Woods' changes of Sep 30. We may want + them later, but not before 1.9. + +Mon Sep 30 23:31:01 1996 Jim Blandy <jimb@floss.cyclic.com> + + * log.c (log_fileproc): Now that we might actually find a "desc" + node in rcsfile->other, thanks to Ian's change below, we had + better deal correctly if we find a null pointer in it. + +Mon Sep 30 13:55:03 1996 Greg A. Woods <woods@most.weird.com> + + * main.c (main): don't set need_to_create_root for "cvs init" + either, just in case it's run from within a valid working + directory. + + * sanity.sh (testcvs): oops, forgot to comment out test version I + was using... + + * diff.c (diff_fileproc): use Diffbin instead of DIFF (3). + * patch.c (patch_fileproc): use Diffbin instead of DIFF. + * commit.c (check_fileproc): use Grepbin instead of GREP. + * rcscmds.c (RCS_merge): use Grepbin instead of GREP. + * update.c (patch_file): use Diffbin instead of DIFF. + (update_fileproc): use Grepbin instead of GREP. + * cvs.h (Diffbin): new declaration. + (Grepbin): new declaration. + (DIFFBIN_ENV): new manifest to name DIFFBIN environ var. + (GREPBIN_ENV): new manifest to name GREPBIN environ var. + * option.h.in (DIFFBIN_DFLT): renamed from DIFF. + (GREPBIN_DFLT): renamed from GREP. + * main.c (main): new variables diffbin_update_env and + grepbin_update_inv, ala rcsbin_update_env. + (main): new options -D diffbin and -g grepbin + (usg): describe new options -D diffbin and -g grepbin. + (Diffbin): new global variable for DIFF path. + (Grepfbin): new global variable for GREP path. + + * options.h.in (RCSBIN_DFLT): mention this needs to be set if + your PATH isn't set properly by rshd. + + * sanity.sh (rdiff): re-do Jim's change, but with the original + keywords I had intended (should be a bit more like real life), and + Jim's better RCS date and user matching form. + [I guess that's what I get for checking things in at 3am! ;-)] + +Mon Sep 30 17:00:20 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_reparsercsfile): Store desc field value in main RCS + node data, not in version specific data. + * sanity.sh: Enable log2 test (for local CVS only). + +Mon Sep 30 13:01:45 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (log2): New test, tests cvs add -m. Not yet enabled + in "tests" because CVS currently flunks this test. + + * sanity.sh (rdiff, basic2): Allow "cvs server" as well as "cvs + checkout" and friends in messages. In testing output of cvs + status, don't require a tab which isn't there for remote. Skip + test rdiff-9 for remote. In test basic2-64, add missing slash in + the pattern which gets used for remote. + + * sanity.sh (rdiff): Fix strings we were matching against which + got keyword-expanded in checking in sanity.sh. + +Mon Sep 30 03:21:37 1996 Greg A. Woods <woods@most.weird.com> + + * sanity.sh: change all regexpr literal '.' to '\.' + (basic2): why are tests 34 & 42 commented out (because + of 'diff -u'?)? + add tests 56[abc], 57a, and 58a to test import to the main + branch (i.e. branch '1'). + (rdiff): new test section for rdiff -K, etc. + (dotest): remove dotest.ex? before running a new test. + (dotest_fail): remove dotest.ex? before running a new test. + (dotest_internal): write expected output to dotest.exp, or if $4 + also used, to dotest.ex1 and dotest.ex2. + (patch): renamed this test to 'serverpatch'. + (dotest_lit): rename dotest.res to dotest.exp ala dotest(). + remove dotest.ex? before running a new test. + (DOTSTAR): mention the bug exists up to 1.12 + (ENDANCHOR): mention the bug exists up to 1.12 + (dotest_all_in_one): new function for debugging. + (dotest_line_by_line): new function for debugging. + (dotest_internal_debug): new function for debugging. + (dotest_internal): stop emulating the ancient tests and don't spew + the dotest.tmp contents onto $LOGFILE -- it's just too much + meaningless noise. Only do this if the test fails. Many tests + don't use dotest() yet, so this isn't quite so helpful as it might + otherwise be. + (TODO): mention CVS/* files, especially CVS/Root. + + * main.c (main): add a commented out piece of code to suggest that + there should be a function lookup_command_attribute() that could + tell us various things about internal commands, such as whether + they use CVS/Root, or if they're repository-only, or if they need + a working directory, etc.... + (main): don't set need_to_create_root if command doesn't use a + local working directory. + + * patch.c (patch): CLIENT_SUPPORT: send '-f' if NOT force_tag_match + + * error.c (fperror): protect declaration for un-defined __STDC__ + + * import.c (import): permit imports to a branch with zero dots, + i.e. the trunk. + (update_rcs_file): don't detect conflicts if importing to the + trunk. + (import): add hint that we should allow a module name, instead of + just a pathname relative to $CVSROOT. + (add_rcs_file): if importing to trunk, do it with ci(1). + + * import.c: XXX the following are all #if 0'ed out until a full + implementation can be designed.... + (cbranch): new variable to support conflict detection on another + branch set by -c. + (import): truncate -b and -c optarg if to fit in static storage. + (import_usage): describe -c + + * rcscmds.c (RCS_checkout): add new argument 'rcsver'. If rcsver + is set, turn on 'keywords' to force call to RCS_exec_checkout. + * rcs.c (RCS_exec_checkout): add new argument 'rcsver'. Pass + 'rcsver' to "co" with run_arg(). + * cvs.h: (RCS_checkout): add new argument 'rcsver' to prototype. + (RCS_exec_checkout): add new argument 'rcsver' to prototype. + * commit.c (remove_file): supply new argument to RCS_checkout. + * checkin.c (Checkin): supply new argument to RCS_checkout. + * diff.c (diff_fileproc): supply new argument to RCS_checkout. + (diff_file_nodiff): supply new argument to RCS_checkout. + * no_diff.c (No_Difference): supply new argument to RCS_checkout. + * update.c (checkout_file): supply new argument to RCS_checkout. + (patch_file): supply new argument to RCS_checkout. + (join_file): supply new argument to RCS_checkout. + + * patch.c: (o_options): new variable for -K + (rcsver): new variable for -V. + (patch): add -K flag which sets o_options, change -V to set + rcsver, send o_options and rcsver if in client mode. + (patch_fileproc): use RCS_checkout instead of RCS_fast_checkout in + order to ensure $Name is expanded, use o_options if set, or + options if set, or by default "-ko" when getting "old" file. + +Sun Sep 29 16:43:28 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rcscmds.c: Replace comment at top of file concerning RCS library + with a reworded version based on discussion between me, Ian, Paul + Eggert, and JimB. + +Sun Sep 29 13:09:45 1996 Noel Cragg <noel@kiva.rain.org> + + * main.c (main): don't create/update CVS/Root when doing the "cvs + login" command. Consider: if the user executes "cvs login" with + the working directory inside an already checked out module, we'd + incorrectly change the CVS/Root file to reflect the CVSROOT of the + "cvs login" command. + + * login.c (login): if we're re-logging into a server for which a + .cvspass entry already exists, copy the temporary file to its home + location rather than renaming. Renaming doesn't work between + filesystems. After copying, unlink the temporary file. + +Fri Sep 27 05:24:56 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * diff.c: Add comment about --brief option. + + * README-rm-add: Removed; the information which was here is now in + cvs.texinfo. + * Makefile.in (DISTFILES): Remove README-rm-add. + +Wed Sep 25 10:00:00 1996 Larry Jones <larry.jones@sdrc.com> + + * Makefile.in (cvsbug): Add dependency on version.c. + +Wed Sep 25 09:01:48 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (get_homedir), update.c (update): Reindent. + +Wed Sep 25 04:44:54 1996 Jim Blandy <jimb@totoro.cyclic.com> + + * version.c (version_string): Bump to 1.8.86. + +Wed Sep 25 05:17:50 1996 Jim Blandy <jimb@floss.cyclic.com> + + * update.c (update): Don't neglect to pass the -kmumble options + to the server. + * sanity.sh (binfiles-sticky): New tests for above. + + * cvsrc.c (read_cvsrc): Deal correctly with lines that specify a + command, but no options; don't corrupt argv. + + * sanity.sh: When testing rsh, use the program specified by + the CVS_RSH environment variable, if it's set. Move test to top + of file, so it runs before all other tests (it's really a + meta-test). + + * filesubr.c (get_homedir): Use getpwuid to find the home + directory, if the HOME environment variable isn't set. + * ignore.c (ign_add_file): Call get_homedir to find the user's + home directory; this is more portable than calling getpwuid. + +Tue Sep 24 09:08:17 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * log.c (log_tree): When walking through branches, follow the + ->prev field rather than following ->next which insures that the + loop only executes once and we only see the last branch. + * sanity.sh (multibranch): Test "cvs log" too; tests for above fix. + +Mon Sep 23 09:55:22 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * options.h.in: Fixed some typos in the comments and reindented + them. + +Sat Sep 21 02:33:26 1996 Jim Blandy <jimb@totoro.cyclic.com> + + * sanity.sh: If we're testing remote CVS, make sure rsh itself is + working before running any tests. It's confusing when basica-1 + fails just because you don't have the local host in your .rhosts + file. + + * version.c (version_string): Bump to 1.8.85. + +Thu Sep 19 09:15:41 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * options.h.in: Define SERVER_FLOWCONTROL, SERVER_HI_WATER, + SERVER_LO_WATER. Several large sites (FreeBSD, Cygnus) have been + pounding on this code without problems, and it doesn't seem to + have any significant downsides. + +Tue Sep 17 01:13:41 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * status.c (status_fileproc): Instead of a default case, set sstat + before the switch. This way gcc -Wall can detect a missed case. + Add explicit T_TITLE case. + +Tue Sep 17 00:09:44 1996 Assar Westerlund <assar@pdc.kth.se> + + * login.c (login): Print usage if argc < 0. + +Tue Sep 17 00:09:44 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * lock.c: In comment, mention one more function of readlocks + (fileattr not updated atomically). Note similarity between + solutions #2 and #5. + + * checkout.c (safe_location): Do not reject a location merely + because it textually starts with hardpath; insist that it be + hardpath or a subdirectory thereof. + +Mon Sep 16 11:46:36 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * server.c (server_cleanup): Add comment about ignoring errors + from unlink_file_dir. + +Mon Sep 16 10:31:48 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * main.c: Add support for -T <tmpdir> command line option. This + is needed for servers started via inetd. + (usg): Added line for -T. Improved -z documentation. + (main): Read default for tmpdir from the environment. Test for 'T' + in getopt loop. Use '/tmp' as ultimative fallback. Update + environment if possible. + + * cvs.h (TMPDIR_ENV): Added for -T <tmpdir> command line option. + + * options.h.in: Add TMPDIR_DFLT + + * import.c (update_rcs_file): Use global variable Tmpdir instead + of reading the environment. + + * server.c (server_cleanup): Use global variable Tmpdir instead of + reading the environment. Also, replace system("rm -rf") with + unlink_file_dir. + (server): Use global variable Tmpdir instead of reading the + environment. + +Thu Sep 12 1996 Jim Kingdon <kingdon@cyclic.com> + + * main.c (main): If ARGV0_NOT_PROGRAM_NAME, then just set + program_name to "cvs" rather than argv[0]. + +Thu Sep 12 12:06:56 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (update_entries): If we can't write the file, don't + make it a fatal error. + +Wed Sep 11 12:46:23 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (start_server): Move START_SERVER_RETURNS_SOCKET code + so that it is only run for server_method. It is wrong for + pserver_method (in which connect_to_pserver sets server_sock). + + * login.c (construct_cvspass_filename): If NO_SLASH_AFTER_HOME, + don't put a '/' between $HOME and .cvspass. Reindent function. + * build_src.com: Add zlib.c, login.c, and scramble.c. + + * rcs.c (RCS_deltas): When looking for our branch in ->branches, + check the branch number. + * sanity.sh (multibranch): New tests test for above fix. + + * commit.c (precommit_list_proc): Fix typo in last change + (->status to ->type). + +Tue Sep 10 23:05:41 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in (DISTFILES): Add build_src.com. + * build_src.com: Add buffer.c, buffer.obj, and zlib.olb. + +Tue Sep 10 20:35:23 1996 Juergen Renz <renz@conware.de> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * commit.c (precommit_list_proc): Update to reflect Jul 22 change + in which p->data was changed from a Ctype to a struct + logfile_info *. This means that commitinfo scripts again get + passed the file list like they should. + +Tue Sep 10 20:35:23 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (auth_server_port_number): Change name of service from + "cvs" to "cvspserver". The latter is what the manual has always + recommended, and it is also officially registered with IANA. + +Tue Sep 10 11:12:42 1996 Mark A. Solinski <markso@mcs.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (socket_buffer_output): Change ifdef VMS to ifdef + SEND_NEVER_PARTIAL. + (start_server): Change ifdef VMS to ifdef START_SERVER_RETURNS_SOCKET. + +Tue Sep 10 17:15:21 1996 Jim Blandy <jimb@totoro.cyclic.com> + + * client.c (auth_server_port_number): Look up "cvs" in the + services database, and use the value it returns; fall back to + CVS_AUTH_PORT if no entry is present. + (connect_to_pserver): Use the correct port number in any error + messages. + +Tue Sep 10 11:12:42 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (newb): New test newb-123j0 tests for another "cvs + status" case. + +Sun Sep 8 15:20:37 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_checkout): Clarify handling of options parameter. + + * rcs.c (RCS_checkout): Free buffer allocated by RCS_deltas. + +Sat Sep 7 21:28:27 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (struct cmd): Add comment concerning recognizing unique + abbreviations. + +Fri Sep 6 22:31:52 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rcs.c (RCS_checkout): Fix indentation. + +Fri Sep 6 11:48:08 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_checkout): Replace tag parameter with rev and nametag + parameters. Change all callers. + * rcs.h (RCS_checkout): Update declaration. + + * rcs.c (RCS_getversion): Replace return_both parameter with + simple_tag. Change all callers. + (RCS_gettag): Likewise. + * rcs.h (RCS_getversion, RCS_gettag): Update declarations. + * vers_ts.c (Version_TS): Simplify vn_tag initialization using new + simple_tag rather than old return_both. + * cvs.h (struct vers_ts): Clarify vn_tag comment a bit. + + * main.c (usg): Only mention -x if ENCRYPTION is defined. + (main): Mention ENCRYPTION define in comment for -x. + * client.h (krb_encrypt_buffer_initialize): Only declare if + ENCRYPTION is defined. + * client.c (start_server): Only encrypt if ENCRYPTION is defined. + * server.c (serve_kerberos_encrypt): Only define if ENCRYPTION is + defined. + (requests): Only include Kerberos-encrypt is ENCRYPTION is + defined. + (krb_encrypt_*): Only define if ENCRYPTION is defined. + +Thu Sep 5 17:32:39 1996 Ian Lance Taylor <ian@cygnus.com> + + * sanity.sh: When testing remote, use :ext: instead of :server: to + match change made earlier today. + +Thu Sep 5 13:57:47 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (start_tcp_server): Don't allow :kserver: to mean + "direct tcp" (root.c already takes care of this, but I want to + make it clear what is intended, and not intended, here). + (start_server): Handle ext_method (external rsh program) and + server_method (internal rsh client) separately. + * client.c: Take rsh_pid and start_rsh_server out of + RSH_NOT_TRANSPARENT ifdefs. It is useful for things like SSH on NT. + * cvs.h (CVSmethod), root.c (method_names): Add ext_method. + * root.c (parse_cvsroot): Recognize "ext" access method. + If access method is not specified and CVSROOT contains a colon, + use either ext_method or server_method depending on + RSH_NOT_TRANSPARENT. + +Thu Sep 5 00:09:49 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_checkout): Remove flags parameter, which was not + serving any useful purpose. Change all callers. + * rcscmds.c (RCS_exec_checkout): Likewise. + + * rcscmds.c (RCS_exec_checkout): Rename from RCS_checkout. Change + all callers. + * rcs.c (RCS_checkout): Rename from RCS_fast_checkout. Change all + callers. + +Wed Sep 4 14:42:28 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_fast_checkout): If tracing, output a message. If + noexec, and workfile is not NULL, just return immediately. Assert + that sout is RUN_TTY or workfile is NULL, rather than using it as + a conditional. Replace found variable with two variables--gothead + and keywords--reflecting what it actually means. + + * rcs.c (RCS_fast_checkout): Don't handle the case of workfile set + to "". + * rcscmds.c (RCS_checkout): Likewise. + * checkin.c (Checkin): Pass explicit file name, not "", to + RCS_fast_checkout. + * update.c (join_file): Likewise. + * commit.c (remove_file): Pass explicit file name to + RCS_fast_checkout and RCS_checkin. + + * rcs.c (RCS_reparsercsfile): Always continue after seeing + RCSSYMBOLS, even if the value is NULL. Clear the NODELTA flag + after setting delta_pos. + (free_rcsnode_contents): New static function. + (freercsnode): Call free_rcsnode_contents. + (RCS_fast_checkout): If NODELTA is set, reparse the RCS file. + (RCS_settag): New function. Change all callers to old function. + (RCS_deltag, RCS_setbranch): Likewise. + (RCS_lock, RCS_unlock): Likewise. + (RCS_deltas): If NODELTA is set, reparse the RCS file. + * rcs.h (NODELTA): Define. + (RCS_settag, RCS_deltag, RCS_setbranch): Declare. + (RCS_lock, RCS_unlock): Declare. + * rcscmds.c (RCS_exec_settag): Rename from RCS_settag. Don't + check tag against BASE or HEAD (now done in new RCS_settag). + (RCS_exec_deltag): Rename from RCS_deltag. + (RCS_exec_setbranch): Rename from RCS_setbranch. + (RCS_exec_lock): Rename from RCS_lock. + (RCS_exec_unlock): Rename from RCS_unlock. + * cvs.h: Update declarations of renamed functions. + * checkin.c (Checkin): Remove rcscopy variable (no longer needed + because of change in RCS_unlock call). + * commit.c: Include <assert.h>. + (remove_file): Update RCSNode path if the file is renamed. + (unblockrcs): Change rcs parameter to RCSNode. Change all + callers. + (fixbranch): Likewise. + (lock_RCS): Likewise. Don't call RCS_parsercsfile. + (checkaddfile): Update RCSNode path if the file is renamed. After + creating a new file, call RCS_parse. When stubbing a branch, use + the passed in RCSNode if there is one, rather than calling + RCS_Parse. Don't call RCS_Parse again after calling RCS_settag. + Free head and magicrev even if RCS_settag fails. + * import.c (add_rev): Change rcs parameter to RCSNode. Change all + callers. + (add_tag): Likewise. + + * rcs.c (RCS_fast_checkout): Amend last patch: if workfile is + NULL, but sout is not NULL, use sout in error message. + +Wed Sep 4 13:35:09 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * version.c: Increment version number to 1.8.8. + + * Version 1.8.7. + +Wed Sep 4 1996 Jim Kingdon <kingdon@cyclic.com> + + * client.c (send_file_names): Look for the name to send in + Entries even if the file doesn't exist; we should send the + name as it appears in Entries in the "rm foo; cvs update FOO" + case. + +Tue Sep 3 20:50:11 1996 William A. Hoffman <hoffman@albirio.crd.ge.com> + + * rcs.c (RCS_fast_checkout): If workfile is NULL, don't try to + include it in error message. + +Mon Aug 26 12:27:38 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * mkmodules.c (mkdir_if_needed): Move from here ... + * filesubr.c, cvs.h (mkdir_if_needed): ... to here. Have it + return a value saying whether the directory was created. + * client.c (call_in_directory), edit.c (edit_fileproc): Call it. + +Fri Aug 23 19:19:44 1996 Ian Lance Taylor <ian@cygnus.com> + + * checkin.c (Checkin): Copy rcs parameter in case it is freed when + finfo->rcs is freed. + +Fri Aug 23 14:55:41 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * remove.c (remove_fileproc): Revert change of 23 Aug to print + getwd and finfo->file in message. The latter is redundant with + fullname and the former is redundant with fullname and the working + directory when CVS was invoked. The implementation was also + lacking as the getwd call could overflow the buffer. + +Fri Aug 23 18:40:35 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * remove.c (cvsremove): fix remove -f for client/server + +Fri Aug 23 11:28:27 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * wrapper.c, cvs.h: Remove conflictHook field of WrapperEntry, + WRAP_CONFLICT in WrapMergeHas, and 'c' option in wrap_add; they + are never used. + +Fri Aug 23 11:41:46 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * server.c (switch_to_user): use #ifdef SETXID_SUPPORT instead of + #if SETXID_SUPPORT + +Thu Aug 22 14:18:43 1996 Ian Lance Taylor <ian@cygnus.com> + + * checkin.c (Checkin): Remove local variable xfinfo. Reparse the + RCS file after the checkin. Call RCS_fast_checkout rather than + RCS_checkout. + + * cvs.h (RCS_FLAGS_LOCK): Don't define. + (RCS_FLAGS_*): Adjust values to fill in hole left by removal of + RCS_FLAGS_LOCK. + * rcs.c (RCS_fast_checkout): Don't check for RCS_FLAGS_LOCK. + * rcscmds.c (RCS_checkout): Likewise. + * commit.c (commit_fileproc): Remove rcs local variable. If + status is T_MODIFIED, require that finfo->rcs be set, call + Lock_RCS directly, and don't call locate_rcs. If adding to a tag, + require that finfo->rcs be set, and don't call locate_rcs. + (remove_file): Remove rcs local variable. Require that finfo->rcs + be set. Don't call locate_rcs. Don't pass RCS_FLAGS_LOCK to + RCS_checkout; use RCS_lock instead. Call RCS_fast_checkout rather + than RCS_checkout. + (unlockrcs): Use a single rcs parameter rather than two parameters + for file and repository. Change all callers. Don't call + locate_rcs. + (fixbranch): Likewise. + (lockrcsfile): Remove; no more callers. + +Tue Aug 20 10:13:59 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * buffer.c, rcs.c: Don't use inline. It wasn't being used in a + loop or any such place where it would matter for performance, and + it was a (minor) portability hassle. + + * server.c (server): Change "Dummy argument 0" to "cvs server" and + add comment explaining why. + + * rcs.c (linevector_add): Add comment regarding changing \n to \0. + +Tue Aug 20 09:19:19 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * checkout.c (checkout_proc): Call RCS_parse to get the default + options from the RCS file. + + * sanity.sh (binfiles): Add tests 5.5b0 and 5.5b1 for the above fix + +Mon Aug 19 18:13:32 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (linevector_init): Make inline. Set lines_alloced to 0, + not 10. Set vector to NULL. + (linevector_add): Remove assertion that lines_alloced is greater + than zero. Initialize lines_alloced if necessary. + (linevector_copy): Initialize lines_alloced if necessary. + (linevector_free): Only free vector if it is not NULL. + (RCS_deltas): Always call linevector_init and linevector_free on + curlines, headlines, and trunklines. + (RCS_fast_checkout): Remove #if 0 around code that calls + RCS_deltas. + +Fri Aug 16 17:52:54 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (linevector_add): Handle zero length correctly. + (RCS_deltas): In RCS_FETCH case, the data is in headlines, not + curlines. + (RCS_fast_checkout): Update comment about RCS_deltas: the + testsuite now passes. + + * rcs.c (RCS_fully_parse): Use the length of the value, rather + than assuming that there are no embedded zero bytes. + (struct line): Add len field. + (linevector_add): Add len parameter. Change all callers. Use + len, rather than assuming that there are no embedded zero bytes. + Set the len field in new lines. + (RCS_deltas): Use the length of the value, rather than assuming + that there are no embedded zero bytes. Use the line length when + outputting it and when copying it. + (RCS_fast_checkout): Update comment about RCS_deltas to remove + note about supporting zero bytes correctly. + +Thu Aug 15 23:38:48 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * commit.c, import.c: Revise comments regarding the fact that we + call start_server before do_editor. + +Thu Aug 15 11:30:55 1996 Ian Lance Taylor <ian@cygnus.com> + + * server.c: Include <sys/socket.h> if AUTH_SERVER_SUPPORT. + (pserver_authenticate_connection): Set SO_KEEPALIVE on + STDIN_FILENO. + (kserver_authenticate_connection): Likewise. + +Thu Aug 15 10:26:41 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * server.c (switch_to_user): Fix previous patch to compile it for + both HAVE_KERBEROS and AUTH_SERVER_SUPPORT + +Wed Aug 14 14:02:00 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * server.c (check_password): if available use getspnam instead of + getpwnam when reading system passwords. This allows cvs pserver + to run on systems with shadow passwords. + (switch_to_user): new static function. Contains the extracted + common tail of kserver_authenticate_connection and + pserver_authenticate_connection. If compiled with SETXID_SUPPORT, + honor the setgid bit if it is set. + (check_repository_password): turn into a static function + (check_password): ditto + (pserver_authenticate_connection): little code cleanup + +Wed Aug 14 01:07:10 1996 Greg A. Woods <woods@most.weird.com> + + * history.c (history): apply fix posted by Steven Meyer + <steve@blacksmith.com> to info-cvs to correct handling of '-D' + argument. Message-Id: <9608122335.AA01385@nijel.blacksmith.com> + +Tue Aug 13 13:42:36 1996 Ian Lance Taylor <ian@cygnus.com> + + * log.c (cvslog): Remove comment about calling rlog. + * rcs.c (translate_symtag): Correct typo in comment (l ist -> + list). + * server.c (server_write_entries): Add omitted word (lists) in + comment. + +Tue Aug 13 14:01:49 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * wrapper.c (wrap_rcsoption): fix memory access error + + * rcs.c (RCS_fast_checkout): fix memory access error (triggered + by an empty option string) + +Mon Aug 12 17:45:15 1996 Jim Kingdon (unknown@beezley) + + * buffer.c, zlib.c: If EIO is not defined, try to define it. + +Mon Aug 12 10:33:27 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * import.c (comtable): Add comment concerning applicability with + RCS 5.7. + + * server.c (server): If TMPDIR is not an absolute pathname, give + an error. + +Mon Aug 12 10:34:43 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * main.c: add synonym "ann" for "annotate" again + +Sun Aug 11 17:54:11 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rcs.h (RCS_RLOG): Removed; no longer used. + +Fri Aug 9 20:16:20 1996 Ian Lance Taylor <ian@cygnus.com> + + * server.c (dirswitch): Open the Entries file with mode "a" rather + than "w+". + (server_write_entries): Open the Entries file with mode "a" rather + than "w". + * sanity.sh (modules): Add topfiles module and 155cN tests for + above patch. + +Fri Aug 9 12:11:25 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (cmd): Add comment regarding synonyms. + +Thu Aug 8 14:40:10 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c: Remove synonyms for "cvs annotate". Synonyms create + user confusion. + +Thu Aug 8 10:24:04 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * main.c: Revert (undocumented) change to rename the cvs history + alias "his" to "hist" + +Wed Aug 7 18:26:25 1996 Ian Lance Taylor <ian@cygnus.com> + + * server.c (cvs_output): Change str parameter to const char *. + Correct loop to print from p, not str. + (cvs_outerr): Likewise. + * cvs.h (cvs_output, cvs_outerr): Update declarations. + + * server.c (receive_partial_file): Read and discard remaining file + data on a write error. + (serve_modified): Discard data while size > 0, not >=. + +Wed Aug 7 15:11:40 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * main.c (cmds): Add some aliases for "annotate". + (usg): Improve usage message text + (cmd_synonyms): New function to print the command synonym list + (main): Add new option --help-synonyms + +Wed Aug 7 00:07:31 1996 Ian Lance Taylor <ian@cygnus.com> + + Keep track of subdirectories in the Entries file. + * cvs.h (enum ent_type): Define. + (struct entnode): Add type field. + (struct stickydirtag): Add subdirs field. + (Subdirs_Known, Subdir_Register, Subdir_Deregister): Declare. + (ignore_files): Update declaration for new parameter. + (FILESDONEPROC): Add entries parameter. + (DIRENTPROC, DIRLEAVEPROC): Likewise. + * entries.c (Entnode_Create): Add type parameter. Change all + callers. + (write_ent_proc): If closure is not NULL, treat it as a pointer to + an int, and set it to 1 if a node is seen which is not ENT_FILE. + (write_entries): If subdirectory information is known, but no + subdirectories were written, write an unadorned D to the file. + (Scratch_Entry): Write an R command to Entries.Log. Don't rewrite + the Entries file. + (Register): Set entfilename. Write an A command rather than an + unadorned entries line. + (fgetentent): Add cmd and sawdir parameters. Change all callers. + If CMD is not NULL, expect and return a single character command. + Handle an initial D by setting the type to ENT_SUBDIR. + (fputentent): Output an initial D for an ENT_SUBDIR entry. + (Entries_Open): Handle removal commands in Entries.Log. Record + whether subdirectory information is known in the list private + data. + (Subdirs_Known): New function. + (subdir_record): New static function. + (Subdir_Register, Subdir_Deregister): New functions. + * find_names.c (add_entries_proc): Skip entries that are not + ENT_FILE. + (add_subdir_proc): New static function. + (register_subdir_proc): New static function. + (Find_Directories): If the Entries file has subdirectory + information, get the directories out of it. Otherwise, call + find_dirs, and add the information to the Entries file. + * recurse.c (struct frame_and_entries): Define. + (do_recursion): Don't call Entries_Close until after processing + dirlist. Pass entries to filesdoneproc. Pass a frame_and_entries + structure to do_dir_proc via walklist. + (do_dir_proc): Expect a frame_and_entries structure in closure, + not a recursion_frame. Pass entries to direntproc and + dirleaveproc. + * ignore.c (ignore_files): Add entries parameter. Change all + callers. If we have subdirectory information, check for + directories in entries. + * add.c (add): If client_active, call Subdir_Register on each new + directory. + (add_directory): Add entries parameter. Change caller. Call + Subdir_Register. + * checkout.c (build_dirs_and_chdir): Call Subdir_Register. + * client.c (call_in_directory): Call Subdir_Register for newly + created directories. Call Subdirs_Known or Find_Directories after + calling Entries_Open. + (process_prune_candidates): Call Subdir_Deregister. + * commit.c (findmaxrev): Skip entries that are not ENT_FILE. + * server.c (dirswitch): Call Subdir_Register. + * update.c (update_dirent_proc): Call Subdir_Register. + (update_dirleave_proc): Call Subdir_Deregister. + * Several files: Change direntproc, dirleaveproc, and + filesdoneproc routines to expect an entries argument. + + * rcs.c (translate_symtag): New static function. + (RCS_gettag): Use translate_symtag rather than RCS_symbols. + (RCS_nodeisbranch, RCS_whatbranch): Likewise. + +Tue Aug 6 15:36:09 1996 Ian Lance Taylor <ian@cygnus.com> + + Finish the conversion of cvs log so that it never invokes rlog. + * log.c (struct log_data): Remove dorlog field. Add nameonly, + header, long_header, statelist, and authorlist fields. + (log_usage): Remove rlog-options. Add -R, -h, -t, -b, -s, -w. + (cvslog): Don't clear opterr. Handle -h, -R, -s, -t, -w. If an + unrecognized option is seen, call usage. + (log_parse_list): New static function. + (log_fileproc): Remove code that called rlog. Check nameonly, + header, and long_header fields in log_data. + (log_version_requested): Check statelist and authorlist. + + * log.c (struct datelist): Define. + (struct log_data): Add datelist and singledatelist fields. + (log_usage): Add -d. + (cvslog): Handle -d. + (log_parse_date): New static function. + (log_fileproc): Do special single date handling. + (log_version_requested): Check datelist and singledatelist. + (log_fix_singledate): New static function. + +Mon Aug 5 23:48:16 1996 Ian Lance Taylor <ian@cygnus.com> + + * log.c (struct option_revlist): Define. + (struct revlist): Define. + (struct log_data): Add default_branch and revlist fields. + (struct log_data_and_rcs): Define. + (log_usage): Add -N and -r. + (cvslog): Handle -N and -r. + (log_parse_revlist): New static function. + (log_fileproc): Call log_expand_revlist and log_free_revlist. + Pass log_data_and_rcs structure to log_count_print via walklist. + (log_expand_revlist, log_free_revlist): New static functions. + (log_version_requested): New static function. + (log_count_print): New static function. + (log_tree): Add log_data and revlist parameter. Change all + callers. + (log_abranch): Likewise. + (log_version): Likewise. Call log_version_requested. + (version_compare): New static function. + * sanity.sh (log): New tests for -r, -b, and -N options to log. + +Sun Aug 4 11:19:30 1996 Ian Lance Taylor <ian@cygnus.com> + + Handle simple cases of cvs log without invoking rlog. + * log.c (struct log_data): Define. + (cvslog): Use getopt to parse options. Set up a log_data + structure, and pass it to start_recursion. + (log_fileproc): Get arguments form callerdat rather than static + variables. In simple cases, print the log information directly, + rather than invoking rlog. + (log_symbol, log_count, log_tree): New static functions. + (log_abranch, log_version, log_branch): New static functions. + * rcs.h (struct rcsnode): Add other field. + (struct rcsversnode): Add other field. + (RCS_fully_parse): Declare. + * rcs.c (getrcsrev): Move declaration to start of file. + (RCS_reparsercsfile): Add all parameter. Change all callers. + (RCS_fully_parse): New function. + (freercsnode): Free other list. + (rcsvers_delproc): Free other list. + * hash.h (enum ntype): Add RCSFIELD. + * hash.c (nodetypestring): Handle RCSFIELD. + +Sat Aug 3 19:39:54 1996 Ian Lance Taylor <ian@cygnus.com> + + * log.c (cvslog): Correct position of CLIENT_SUPPORT #endif. + +Thu Jul 25 12:06:45 1996 Ian Lance Taylor <ian@cygnus.com> + + * update.c (join_file): If merging a branch, and the branch + revision does not exist, just return without doing anything. + * sanity.sh (join): Add cases file7 and file8 to test above + patch. + + * server.c (cvsencrypt): Rename from encrypt, to avoid conflict + with NetBSD unistd.h. Rename all uses. + + * server.c (krb_encrypt_buffer_output): Fix typo in comment (reply + -> replay). + +Thu Jul 25 10:37:32 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * server.c (krb_encrypt_buffer_output): Fix typo in comment + (krb_recv_auth -> krb_recvauth). + +Wed Jul 24 09:28:33 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * lock.c (set_lock): Adjust comment regarding why we call stat. + +Wed Jul 24 15:06:08 1996 Ian Lance Taylor <ian@cygnus.com> + + Add encryption support over a Kerberos connection. + * main.c (usg): Mention -x if CLIENT_SUPPORT. + (main): Handle -x. + * client.h (encrypt): Declare. + (krb_encrypt_buffer_initialize): Declare. + * client.c (kblock, sched): New static variables if + HAVE_KERBEROS. + (start_tcp_server): Remove sched local variable. Copy + cred.session into kblock. + (start_server): Turn on encryption if requested. + * server.c (kblock, sched): New static variables if + HAVE_KERBEROS. + (serve_kerberos_encrypt): New static function. + (requests): Add "Kerberos-encrypt" if HAVE_KERBEROS. + (kserver_authenticate_connection): Remove sched local variable. + Copy auth.session into kblock. + (encrypt): New global variable. + (struct krb_encrypt_buffer): Define. + (krb_encrypt_buffer_initialize): New function. + (krb_encrypt_buffer_input): New static function. + (krb_encrypt_buffer_output): New static function. + (krb_encrypt_buffer_flush): New static function. + (krb_encrypt_buffer_block): New static function. + (krb_encrypt_buffer_shutdown): New static function. + +Wed Jul 24 09:28:33 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * recurse.c (do_recursion): Add comment about calling + Name_Repository in !(which & W_LOCAL) case. + + * expand_path.c (expand_variable): Fix typo (varaible -> variable). + +Tue Jul 23 15:05:01 1996 Ian Lance Taylor <ian@cygnus.com> + + * update.c (update_fileproc): In T_REMOVE_ENTRY case, only call + server_scratch_entry_only if ts_user is NULL. + * sanity.sh (death2): Add death2-20 test for above patch. + + * diff.c (diff_fileproc): If a file is not in the working + directory, check that the tag is present before warning that no + comparison is possible. + * sanity.sh (death2): Add death2-diff-9 and death2-diff-10 tests + for above patch. + +Tue Jul 23 12:05:42 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * tag.c (tag_check_valid): Fix indentation. + + * client.c (handle_e): Flush stdout before writing to stderr. + (handle_m): Flush stderr before writing to stdout. + +Fri Jul 19 16:02:11 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * client.c: Added NO_CLIENT_GZIP_PROCESS to deal with the MacOS + client where Gzip-stream is supported, but "gzip-file-contents" is + not. + +Fri Jul 19 16:02:11 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * repos.c: Fixed recent patch which added plain fopen rather than + CVS_FOPEN + +Mon Jul 22 22:25:53 1996 Ian Lance Taylor <ian@cygnus.com> + + * logmsg.c (tag): New static variable. + (setup_tmpfile): Don't print the prefix before calling fmt_proc. + Free tag if it is set. + (find_type): Get type from logfile_info struct. + (fmt_proc): Likewise. Print tag information. Handle all prefix + printing. + (revision): Remove static variable. + (Update_Logfile): Remove xrevision parameter. Change all + callers. + (title_proc): Get type from logfile_info struct. + (logfile_write): Remove revision parameter. Change all callers. + * cvs.h (struct logfile_info): Define. + (Update_Logfile): Update prototype. + * commit.c (find_fileproc): Set logfile_info information. + (check_fileproc): Likewise. + (commit_filesdoneproc): Don't call ParseTag. + (update_delproc): Free logfile_info information. + * add.c (add_directory): Set logfile_info information. + * import.c (import): Likewise. + + * tag.c (tag_check_valid): The special BASE and HEAD tags are + always valid. + * sanity.sh (basica): Add basica-6.3 test for above patch. + +Mon Jul 22 14:41:20 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * update.c (merge_file): Pass 0 not NULL to checkout_file (20 Jul + 96 change changed other calls to checkout_file but missed this one). + +Sat Jul 20 00:21:54 1996 Ian Lance Taylor <ian@cygnus.com> + + * update.c (join_file): Check whether the target of the merge is + the same as the working file revision before checking whether the + file was added during the merge. + + * update.c (scratch_file): Remove existing parameters, and add a + single parameter of type struct file_info. Change all callers. + Warn if unlink_file fails. + (checkout_file): Remove resurrecting_out parameter. Add adding + parameter. Change all callers. Remove joining code. + (join_file): Remove resurrecting parameter. Rewrite to handle + joining dead or added revisions. + * classify.c (Classify_File): If there is no user file, and the + RCS file is dead, return T_UPTODATE rather than T_CHECKOUT. + * checkout.c (checkout_proc): Set W_ATTIC if there is a join tag. + * sanity.sh (join): New set of tests for above patches. + (death): Adjust tests 86, 89, 89a, 92.1c, 95 for above patches. + (import): Adjust test 113 for above patches. + +Thu Jul 18 19:24:08 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * lock.c: Add comment explaining what locks are for. Also discuss + various changes to locking which get proposed from time to time. + + * sanity.sh (death2): Change a number of test names from death-* + to death2-*. + + * wrapper.c (wrap_setup): Don't look in repository if client_active. + * wrapper.c, cvs.h (wrap_send): New function. + * update.c (update), import.c (import): Call it. + * sanity.sh (binwrap): Do binwrap tests for remote as well as + local; tests for above fixes. + + * wrapper.c: Add a few FIXME comments. + +Thu Jul 18 18:43:50 1996 Ian Lance Taylor <ian@cygnus.com> + + * sanity.sh (patch): Fix names of a couple of tests to say patch + rather than death2. + +Thu Jul 18 16:19:21 1996 Bill Bumgarner <bbum@friday.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * add.c (add), import.c (add_rcs_file): Check for options from + wrappers and use them if specified. + * cvs.h (WrapMergeHas): Add WRAP_RCSOPTION. + * wrapper.c (WrapperEntry): Add rcsOption field. + (wrap_add): Allow a single character argument to an option. + (wrap_add): Handle -k option. + (wrap_add_entry): Handle rcsOption field. + (wrap_name_has): Handle WRAP_RCSOPTION. + * wrapper.c, cvs.h (wrap_rcsoption): New function. + * add.c, import.c, wrapper.c: Minor beautification (mostly + removing trailing spaces). + * sanity.sh (binwrap): New tests test for this feature. + +Wed Jul 17 10:14:20 1996 Ian Lance Taylor <ian@cygnus.com> + + * checkout.c (checkout): Remove extraneous else accidentally + inserted in last checkin. + +Tue Jul 16 11:37:41 1996 Ian Lance Taylor <ian@cygnus.com> + + * sanity.sh (import): Use quoting to avoid expansion of RCS ID + strings. + + * sanity.sh (import): Use dotest to examine the output of test + 113, and the actual contents of the file in test 116. + + * update.c (join_file): Always skip rcsmerge if the two revisions + are the same (the old code always did the rcsmerge when two -j + options were specified). + + * checkout.c (history_name): New static variable. + (checkout): Permit both tag and date to be specified. Set + history_name. + (checkout_proc): Use history_name when calling history_write. + * rcs.c (RCS_getversion): If both tag and date are set, use + RCS_whatbranch to get the branch revision number of a symbolic + tag. + (RCS_getdatebranch): If the branch revision itself is early + enough, then use it if the first branch is not early enough. Add + comment for invalid RCS file. Don't bother to check for NULL + before calling xstrdup, since xstrdup checks anyhow. + + * client.h (file_gzip_level): Declare. + * client.c (file_gzip_level): Define. + (start_server): Don't set gzip_level to zero after sending + Gzip-stream command. Set file_gzip_level after sending + gzip-file-contents command. + (send_modified): Use file_gzip_level rather than gzip_level. + * server.c (server_updated): Likewise. + (serve_gzip_contents): Likewise. + + * sanity.sh (patch): New tests. Test remote CVS handling of + unpatchable files. + + * sanity.sh (death2): Accept a '.' in the temporary file name + printed by diff. + + * rcscmds.c (RCS_checkin): Remove noerr parameter. Change all + callers. + * cvs.h (RCS_checkin): Update declaration. + * commit.c (remove_file): Pass RCS_FLAGS_QUIET to RCS_checkin. + + * history.c (history): Cast sizeof to int to use correct type in + error printf string. + (report_hrecs): Cast strlen result to int to use correct type in + printf string. + + * server.c (cvs_flusherr): Correct typo in comment. + + * rcs.c (getrcskey): Hoist three constant strcmp calls out of the + value reading loop. + + * fileattr.c (fileattr_get): Change parameter types from char * to + const char *. + (fileattr_get0, fileattr_modify, fileattr_set): Likewise. + (fileattr_newfile): Likewise. + * fileattr.h (fileattr_get): Update declaration. + (fileattr_get0, fileattr_modify, fileattr_set): Likewise. + (fileattr_newfile): Likewise. + +Thu May 16 11:12:18 1996 Mark P. Immel <immel@radix.net> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.h, client.c, checkout.c (client_send_expansions): + Pass an additional parameter indicating where the checkout is + to occur, to avoid passing the wrong information to send_files(). + * sanity.sh (basicb): New test basicb-cod-1 tests for above fix. + +Mon Jul 15 18:26:56 1996 Ian Lance Taylor <ian@cygnus.com> + + * recurse.c (do_recursion): Require a repository before calling + Find_Names. + * repos.c (Name_Repository): Remove sanity checks which spend time + examining the filesystem. + +Mon Jul 15 1996 Jim Kingdon <kingdon@cyclic.com> + + * client.c (send_file_names): Send file names as they appear + in CVS/Entries, rather than as specified (in cases where they + might differ in case). + (send_fileproc): Use file name from CVS/Entries (vers->entdata->user) + rather than file name as specified (finfo->file) when available. + +Sun Jul 14 15:39:44 1996 Mark Eichin <eichin@cygnus.com> + and Ian Lance Taylor <ian@cygnus.com> + + Improve diff -N handling of nonexistent tags and removed files. + * diff.c (enum diff_file): New definition for whole file, moving + unnamed enum out of diff_fileproc, renaming DIFF_NEITHER to + DIFF_DIFFERENT, and adding DIFF_SAME. + (diff): Look through the repository even if only one revision is + given. + (diff_fileproc): Change empty_file to be enum diff_file. If there + is no user revision, but there is a repository file, treat it as a + removed file. Pass empty_file to diff_file_nodiff, and set it + from the return value. + (diff_file_nodiff): Change return type to enum diff_file. Replace + just_set_rev parameter with enum diff_file empty_file parameter. + Change handling of a missing tag to return an enum diff_file value + if empty_files is set, rather than reporting an error. Free tmp + if xcmp returns 0. + * sanity.sh (death2): Add tests for above patches. + +Sat Jul 13 19:11:32 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rcs.c (annotate): In sending options to server, reverse sense of + test so that we send -f iff -f was specified, rather than iff -f was + not specified. + +Fri Jul 12 20:23:54 1996 Greg A. Woods <woods@most.weird.com> + + * zlib.c (compress_buffer_input): add a couple of casts for + uses of z_stream's next_in and next_out + +Fri Jul 12 18:55:26 1996 Ian Lance Taylor <ian@cygnus.com> + + * zlib.c: New file. + * client.c (log_buffer_block): Call set_block and set_nonblock, + rather than lb->buf->block. + (log_buffer_shutdown): New static function. + (get_responses_and_close): Call buf_shutdown on to_server and + from_server. + (start_server): If "Gzip-stream" is supported, use it rather than + "gzip-file-contents". + * server.c (print_error): Call buf_flush rather than + buf_send_output. + (print_pending_error, serve_valid_responses): Likewise. + (serve_expand_modules, serve_valid_requests): Likewise. + (do_cvs_command): Call buf_flush rather than buf_send_output + before the fork, and in the parent after the child has completed. + In the child, set buf_to_net and buf_from_net to NULL. + (serve_gzip_stream): New static function. + (requests): Add "Gzip-stream". + (server_cleanup): Don't do anything with buf_to_net if it is + NULL. Call buf_flush rather than buf_send_output. Call + buf_shutdown on buf_to_net and buf_from_net. Call error for an + malloc failure rather than buf_output to buf_to_net. + * buffer.h (struct buffer): Add shutdown field. + (buf_initialize): Update declaration for new shutdown parameter. + (compress_buffer_initialize): Declare. + (buf_shutdown): Declare. + * buffer.c (buf_initialize): Add shutdown parameter. Change all + callers. + (buf_shutdown): New function. + * Makefile.in (SOURCES): Add zlib.c + (OBJECTS): Add zlib.o. + ($(PROGS)): Depend upon ../zlib/libz.a. + (cvs): Link against ../zlib/libz.a. + (zlib.o): New target. + +Fri Jul 12 1996 Jim Kingdon <kingdon@cyclic.com> + + * client.c (log_buffer_input, log_buffer_output): Use size_t + to avoid Visual C++ signed/unsigned warnings. + +Thu Jul 11 22:01:37 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (handle_f): Reindent. + + * client.c (mode_to_string, handle_m, handle_e, + auth_server_port_number, get_responses_and_close), server.c + (pserver_authenticate_connection, serve_modified, + serve_enable_unchanged, wait_sig, server_cleanup): Reindent. + * server.c: Remove #if 0'd block of code above + check_repository_password; it was yanked out of some unknown + context and didn't seem to be very useful. + +Thu Jul 11 20:10:21 1996 Ian Lance Taylor <ian@cygnus.com> + + * server.c (do_cvs_command): Pass new special parameter to + buf_copy_counted. If it gets set to -1, send an 'F' response if + the client supports it, and call cvs_flusherr. + (cvs_flusherr): New function. + * cvs.h (cvs_flusherr): Declare. + * client.c (handle_f): New static function. + (responses): Add "F". + * buffer.c (buf_send_special_count): New function. + (buf_copy_counted): Add special parameter. Handle negative counts + specially. + * buffer.h (buf_send_sepcial_count): Declare. + (buf_copy_counted): Update declaration. + * lock.c (lock_wait, lock_obtained): Call cvs_flusherr. + + Change the client to use the buffer data structure. + * client.c: Include "buffer.h". + (to_server): Change to be struct buffer *. + (to_server_fp): New static variable. + (from_server): Change to be struct buffer *. + (from_server_fp): New static variable. + (from_server_logfile, to_server_logfile): Remove. + (buf_memory_error): New static function. + (struct log_buffer): Define. + (log_buffer_initialize, log_buffer_input): New static functions. + (log_buffer_output, log_buffer_flush): New static functions. + (log_buffer_block): New static function. + (struct socket_buffer): Define if NO_SOCKET_TO_FD. + (socket_buffer_initialize): New static function if + NO_SOCKET_TO_FD. + (socket_buffer_input, socket_buffer_output): Likewise. + (socket_buffer_flush): Likewise. + (read_line): Rewrite to use buf_read_line. Remove eof_ok + parameter (it was always passed as 0); change all callers. + (send_to_server): Rewrite to use buf_output. + (try_read_from_server): Rewrite to use buf_read_data. + (get_responses_and_close): Use from_server_fp and to_server_fp for + the streams. Check buf_empty_p when checking for dying gasps. + (start_server): Don't set from_server_logfile and + to_server_logfile; instead, call log_buffer_initialize. If + NO_SOCKET_TO_FD and use_socket_style, call + socket_buffer_initialize; otherwise, call + stdio_buffer_initialize. + * buffer.c: Compile if CLIENT_SUPPORT is defined. + (buf_flush): Fix comment to describe return value. + (buf_read_line): Add lenp parameter. Change all callers. Look + for a line terminated by \012 rather than \n. + * buffer.h: Compile if CLIENT_SUPPORT is defined. + (buf_read_line): Update declaration. + + * server.c (server): Initialize buf_to_net, buf_from_net, + saved_output, and saved_outerr before setting error_use_protocol. + (pserver_authenticate_connection): Don't set error_use_protocol. + Errors before the authentication is complete aren't handled + cleanly anyhow. Change error call after authentication to use + printf. + +Thu Jul 11 1996 Jim Kingdon <kingdon@cyclic.com> + + * client.c (start_server): Open logfiles in binary, not text, mode. + +Wed Jul 10 19:24:22 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * server.c (print_pending_error, print_error): Remove comments + about deadlocks; they don't apply here. Add comments saying + that these functions must only be called when it is OK to + send output (which is why the deadlock concern doesn't apply). The + comments remain for server_cleanup and serve_valid_responses, + where they are an example of the "print a message and exit" + behavior which is noted in cvsclient.texi and which also exists + places like kserver_authenticate_connection. + +Wed Jul 10 18:24:46 1996 Ian Lance Taylor <ian@cygnus.com> + + * server.c (print_error): Add comment warning about potential + deadlock. + (print_pending_error, serve_valid_responses): Likewise. + (server_cleanup): Likewise. + (serve_directory): Don't call buf_send_output. + (serve_modified, serve_notify, server, cvs_outerr): Likewise. + (serve_expand_modules): Call buf_send_output. + (serve_valid_requests): Likewise. + +Wed Jul 10 15:51:29 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (main): Print a warning for rlog command. + +Wed Jul 10 15:00:55 1996 Ian Lance Taylor <ian@cygnus.com> + + Abstract the buffer data structure away from the underlying + communication medium. + * buffer.h (struct buffer): Remove fd and output fields. Add + input, output, flush, block, and closure fields. + (buf_initialize, buf_nonio_initialize): Declare. + (stdio_buffer_initialize, buf_flush): Declare. + (buf_read_line, buf_read_data): Declare. + * buffer.c: Include <assert.h>. Don't include <fcntl.h>. + (O_NONBLOCK, blocking_error): Don't define. + (buf_initialize, buf_nonio_initialize): New functions. + (buf_send_output): Use output function, rather than write. + (buf_flush): New function. + (set_nonblock, set_block): Use block function, rather than calling + fcntl. + (buf_send_counted): Don't check output. + (buf_input_data): Call input function, rather than read. + (buf_read_line, buf_read_data): New functions. + (buf_copy_lines, buf_copy_counted): Don't check output. + (stdio_buffer_initialize): New function. + (stdio_buffer_input, stdio_buffer_output): New static functions. + (stdio_bufer_flush): New static function. + * server.c: Include "getline.h". + (buf_to_net): Change to be a pointer. Change all uses. + (protocol, saved_output, saved_outerr): Likewise. + (buf_from_net): New static variable. + (no_mem_error, NO_MEM_ERROR, read_line): Remove. + (struct fd_buffer): Define. + (fd_buffer_initialize, fd_buffer_input): New static functions. + (fd_buffer_output, fd_buffer_flush): New static functions. + (fd_buffer_block): New static function. + (serve_directory): Call buf_read_line rather than read_line. + (serve_notify, server): Likewise. + (receive_partial_file): Call buf_read_data rather than fread. + (serve_modified): Call buf_read_line rather than read_line. Call + buf_read_data rather than fread. + (do_cvs_command): Initialize buffers with fd_buffer_initialize. + Change stdoutbuf, stderrbuf, and protocol_inbuf to be pointers. + (server): Initialize buffers using fd_buffer_initialize, + stdio_buffer_initialize, and buf_nonio_initialize. + (check_repository_password): Call getline rather than read_line. + +Wed Jul 10 15:51:29 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * commit.c (find_fileproc): Add comments describing a few cases + that we aren't handling. + +Tue Jul 9 04:33:03 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rcs.c (RCS_deltas): New function, created from guts of old + annotate_fileproc. + (annotate_fileproc): Call RCS_deltas. + (RCS_fast_checkout): Call it (commented out for now; see comment + for reasons). + + * cvs.h, recurse.c (start_recursion): Add callerdat argument. + * cvs.h: Add callerdat argument to recursion processor callbacks. + * recurse.c: add it to struct recursion_frame and pass it to all + the callbacks. + * admin.c, client.c, commit.c, diff.c, edit.c, lock.c, log.c, + patch.c, rcs.c, remove.c, rtag.c, status.c, tag.c, update.c, + watch.c: Update all the functions used as callbacks. Update calls + to start_recursion. + * commit.c (find_filesdoneproc, find_fileproc, find_dirent_proc, + commit), tag.c (val_fileproc, tag_check_valid): Use callerdat + instead of a static variable. + + * recurse.c (do_recursion): Make static and move declaration to here... + * cvs.h: ...from here. + * recurse.c (do_recursion): Replace plethora of arguments with + single struct recursion_frame *. Change callers. + * recurse.c: New structure frame_and_file. Use it and existing + struct recursion_frame structures to pass info to do_file_proc and + do_dir_proc. Remove globals fileproc, filesdoneproc, direntproc, + dirleaveproc, which, flags, aflag, readlock, and dosrcs. + +Tue Jul 9 11:13:29 1996 Ian Lance Taylor <ian@cygnus.com> + + * modules.c (do_module): Call cvs_outerr rather than fprintf. + +Mon Jul 8 1996 Jim Kingdon <kingdon@cyclic.com> + + * rcs.c (RCS_fast_checkout): If -kb is not in use, open the + working file in text, not binary, mode. + +Sun Jul 7 10:36:16 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rcscmds.c (RCS_settag): Add comment regarding moving check for + reserved tag names to RCS_check_tag. + + * rcscmds.c: Add comment regarding librarifying RCS and related + issues. This is a lightly edited version of a message I sent to + the CVS developers and didn't get flamed for, so it would appear + to be relatively uncontroversial. + + * rcs.c (annotate): Remove comment suggesting -r option and + related functionality; it is done. + +Fri Jul 5 17:19:57 1996 Ian Lance Taylor <ian@cygnus.com> + + * client.c (last_entries): Make file static, rather than function + static within call_in_directory. + (get_responses_and_close): If last_entries is not NULL, pass it to + Entries_Close. + + * server.c (server_pause_check): Check for errors when reading + from flowcontrol_pipe. + + * client.c (call_in_directory): If dir_name is ".", call + Create_Admin if there is no CVS directory. + (send_dirent_proc): If there is no CVS subdirectory, pretend that + the directory does not exist (i.e., don't try to send any files in + the directory). + * server.c (dirswitch): If dir is "." in the top level repository, + add "/." after the Repository entry. + * sanity.sh (modules): Add test 155b for above patches. + +Thu Jul 4 15:57:34 1996 Ian Lance Taylor <ian@cygnus.com> + + * server.c (buf_to_net): Move definition near top of file. + (read_line): Call buf_send_output rather than fflush. + (print_error): Output information to buf_to_net buffer rather than + stdout. + (print_pending_error, serve_valid_responses): Likewise. + (server_notify, do_cvs_command, server_co): Likewise. + (expand_proc, serve_expand_modules, server_prog): Likewise. + (serve_valid_requests, server_cleanup, server): Likewise. + (server_notify): Don't call fflush on stdout. + (do_cvs_command): Flush saved_output and saved_outerr to + buf_to_net before fork. Flush buf_to_net before fork. In child, + just initialize memory_error field of saved_output and + saved_outerr. + (server_cleanup): Flush buf_to_net. + (server): Initialize saved_output and saved_outerr. + (cvs_output): Add support for error_use_protocol case. + (cvs_outerr): Likewise. + * error.c (error): In HAVE_VPRINTF case, just call cvs_outerr. + + * buffer.c: New file; buffer support functions taken from + server.c. + * buffer.h: New file; declarations for buffer.c. + * server.c: Move buffer support functions into buffer.c and + buffer.h. Include "buffer.h". + * Makefile.in (SOURCES): Add buffer.c. + (OBJECTS): Add buffer.o. + (HEADERS): Add buffer.h. + +Thu Jul 4 00:12:45 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * version.c: Increment version number to 1.8.6. + +Wed Jul 3 22:31:16 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * version.c: Version 1.8.5. + +Wed Jul 3 21:51:23 1996 Ian Lance Taylor <ian@cygnus.com> + + * server.c (blocking_error): Define macro. + (buf_send_output, buf_input_data): Use blocking_error rather than + #ifdef EWOULDBLOCK. + +Tue Jul 2 20:38:41 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * add.c (add): Change message which said "version 1.2 of foo.c + will be resurrected"; the message was confusing because it made + people think that the old contents of the file would come back + instead of the contents in the working directory. + +Mon Jul 1 01:38:57 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * find_names.c (find_dirs): Add comment explaining why we bother + with the entries stuff. + +Sat Jun 29 20:23:50 1996 Ian Lance Taylor <ian@cygnus.com> + + * find_names.c (Find_Directories): Add entries parameter, and pass + it to find_dirs. + (find_dirs): Add entries parameter, and skip all files it names. + * cvs.h (Find_Directories): Update declaration. + * recurse.c (start_recursion): Pass NULL to Find_Directories. + (do_recursion): Pass entries to Find_Directories. + + * client.c (send_modified): Add trace output. + + * diff.c (diff_fileproc): Always call diff_file_nodiff. Handle + dead versions correctly. Handle diffs between a specified + revision to a dead file correctly. + (diff_file_nodiff): Add just_set_rev parameter. Change caller. + * patch.c (patch_fileproc): Check for dead versions. + * sanity.sh (death2): Add tests for above patches. + +Fri Jun 28 20:30:48 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + For reference, this takes CVS's text segment from 271136 bytes to + 270352 bytes, a saving of 784. Not as good as I had hoped (oh well, + the source *seems* simpler at least). + * checkin.c (Checkin), commit.c (finaladd, remove_file), update.c + (join_file, checkout_file, patch_file), no_diff.c + (No_Differences), server.c (server_updated), classify.c + (Classify_File), vers_ts.c (Version_TS), diff.c (diff_file_nodiff): + Use a single struct file_info * argument instead of a bunch of + separate arguments for each of its fields. Remove local fullname + emulations. Use fullname in error messages where file had + erroneously been used. + * cvs.h: Update declarations of above functions and move them to + after the struct file_info declaration. + * server.h: Update declarations. + * add.c, admin.c, checkin.c, checkout.c, classify.c, client.c, + commit.c, diff.c, history.c, import.c, update.c, status.c, + remove.c, rtag.c, tag.c: Change callers. + + * diff.c (diff): Remove -q and -Q command options. This somehow + slipped through the cracks of the general removal of -q and -Q + command options on Jul 21 1995. Note that there is no need to + accept and ignore these options in server mode, like there is for + some of the commands, because the client has never sent -q and -Q + command options for "cvs diff". + +Fri Jun 28 16:50:18 1996 Ian Lance Taylor <ian@cygnus.com> + + * add.c (add): Pass force_tag_match as 1 when calling Version_TS. + * sanity.sh (death2): Add test for above patch. Also add + commented out test for adding a file on a nonbranch tag, which CVS + currently, mistakenly, permits. + +Thu Jun 27 23:20:49 1996 Ian Lance Taylor <ian@cygnus.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * diff.c (longopts): New static array. + (diff): Handle long options and new short options in diff 2.7. + Fix arbitrary limit associated with the tmp variable. + * client.c (send_option_string): Parse options as space separated, + rather than requiring all options to be single characters. + * diff.c, options.h.in: Remove CVS_DIFFDATE; the need for it is gone + now that we have --ifdef (the new behavior is the behavior which + was the default, which is that -D specifies a date). + +Wed Jun 26 22:36:29 1996 Ian Lance Taylor <ian@cygnus.com> + + * commit.c (check_fileproc): If there is a tag, permit adding a + file even if the RCS file already exists. + (checkaddfile): If there is a tag, use the file in the regular + repository, rather than the Attic, if it exists. + * sanity.sh (death2): New set of tests for above patch. + +Tue Jun 25 23:34:13 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * update.c (checkout_file): Add comments about two cases which + seem fishy. + + * sanity.sh (basic2, death): Add comments encouraging people to + stop making these sections bigger and more complex. I'm not (yet + at least) trying to figure out the ideal size for a section (my + current best estimate is 10-20 tests), but surely these + two sections are pushing the limit, whatever it is. + +Tue Jun 25 19:52:02 1996 Ian Lance Taylor <ian@cygnus.com> + + * update.c (checkout_file): Rewrite handling of dead files when + joining. Avoid space leaks. Avoid unnecessary file + resurrections. + (join_file): Add checks to skip merging a dead revision onto a + dead revision, and to skip merging a common ancestor onto a dead + revision. Move check for non-existent working file after new + checks. + * sanity.sh (death): Use dotest for tests 86 and 95, and add test + death-file2-1, to test above changes. + +Mon Jun 24 11:27:37 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * update.c (merge_file): Replace file, repository, entries, and + update_dir arguments with finfo argument. Use fullname field + instead of locally emulating it. + (update_fileproc): Update caller. + (merge_file): If -kb is in effect, call it a conflict, leave + the two versions in the file and the backup file, and tell the + user to deal with it. The previous behavior was that the merge + would fail and then there was no way to do a checkin even once you + resolved the conflict (short of kludges like moving the file + aside, updating, and then moving it back). + * sanity.sh (binfiles): New tests binfiles-con* test for above + behavior. Adjust remaining tests to reflect changes in revision + numbers. + +Mon Jun 17 15:11:09 1996 Ian Lance Taylor <ian@cygnus.com> + + * sanity.sh (import): Remove sleep. Requiring it was a bug, and + it is fixed in the current sources. + +Mon Jun 17 1996 Ian Lance Taylor <ian@cygnus.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (TMPPWD): Set to real name of /tmp directory. + (basic2-64, conflicts-126.5): Use ${TMPPWD}. + +Mon Jun 17 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcscmds.c (RCS_checkout): Remove noerr parameter. Change all + callers. + * rcs.c (RCS_fast_checkout): Likewise. + +Mon Jun 17 1996 Ian Lance Taylor <ian@cygnus.com> + + Cleaner implementation of tag locking code added Jun 13 1996: + * cvs.h (tag_lockdir, tag_unlockdir): Declare. + * rtag.c (locked_dir, locked_list): Remove. + (rtag_fileproc): Don't lock here; just call tag_lockdir. + (rtag_filesdoneproc): Don't unlock here; just call tag_unlockdir. + * tag.c (locked_dir, locked_list): Move farther down in file. + (tag_fileproc): Don't lock here; just call tag_lockdir. + (tag_filesdoneproc): Don't unlock here; just call tag_unlockdir. + (tag_lockdir, tag_unlockdir): New functions. + +Wed Jun 15 07:52:22 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * client.c (send_modified, update_entries): Fixed bug which didn't + handle binary file transfers in BROKEN_READWRITE_CONVERSION. + +Thu Jun 13 1996 Ian Lance Taylor <ian@cygnus.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * update.c (checkout_file): Call server_scratch_entry_only when a + non-pertinent file is found that does not exist. + * sanity.sh (newb): Add test case for above patch. + +Thu Jun 13 1996 Ian Lance Taylor <ian@cygnus.com> + + * update.c (update_fileproc): Call server_scratch_entry_only when + handling T_REMOVE_ENTRY on the server. + * sanity.sh (conflicts2): Remove special case for remote server + bug fixed by above patch. + +Thu Jun 13 21:16:26 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (basica-9): Update to reflect change to "sufficient + access" message. + +Thu Jun 13 20:13:55 1996 Ian Lance Taylor <ian@cygnus.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * recurse.c, cvs.h (start_recursion): Remove wd_is_repos argument; + add comment about meaning of which argument. Use !(which & + W_LOCAL) instead of wd_is_repos. + * admin.c, client.c, commit.c, diff.c, edit.c, lock.c, log.c, + patch.c, rcs.c, remove.c, rtag.c, status.c, tag.c, update.c, + watch.c: Change callers. This is a semantic change in only two + cases: (1) tag_check_valid, where repository was not "", and (2) + the pipeout case in checkout_proc. In both of those cases the + previous setting of wd_is_repos did not reflect whether we + actually were cd'd into the repository. + * recurse.c (start_recursion): Only check for the CVS subdirectory + if which & W_LOCAL. + * sanity.sh (devcom): Add test case fixed by above patch. + +Thu Jun 13 1996 Ian Lance Taylor <ian@cygnus.com> + + * ignore.c (ignore_files): Skip based on the file name before + calling lstat. + + * client.c (last_register_time): New static variable. + (update_entries): Set last_register_time when calling Register. + (get_responses_and_close): If the current time is the same as + last_register_time, sleep for a section to avoid timestamp races. + +Thu Jun 13 17:24:38 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (supported_request): Reindent. + +Thu Jun 13 1996 Mark H. Wilkinson <mhw@minster.york.ac.uk> + + * options.h.in, mkmodules.c: Corrections to allow compilation of + non-client-server version. + +Thu Jun 13 1996 Ian Lance Taylor <ian@cygnus.com> + + * tag.c (tag_check_valid_join): New function. + * cvs.h (tag_check_valid_join): Declare. + * checkout.c (join_tags_validated): New static variable. + (checkout_proc): Check validity of join tags. + * update.c (update): Likewise. + + * tag.c (tag_check_valid): Correct sizeof CVSROOTADM_HISTORY to + use CVSROOTADM_VALTAGS. + + * lock.c (Writer_Lock): If we called lock_wait to wait for a lock, + then call lock_obtained when we get it. + (set_lock): Likewise. + (lock_obtained): New static function. + +Thu Jun 13 13:55:38 1996 Ian Lance Taylor <ian@cygnus.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (main): If we can't read cvs root, don't say "you don't + have sufficient access"; just print the message from errno. It + might be "No such file or directory" or something else for which + "you don't have sufficient access" doesn't make any sense. + +Thu Jun 13 1996 Ian Lance Taylor <ian@cygnus.com> + + * commit.c (remove_file): Pass noerr as 0 to RCS_checkout. + +Thu Jun 13 12:55:56 1996 Ian Lance Taylor <ian@cygnus.com> + + * patch.c: Initialize rev1_validated and rev2_validated to 0, not 1. + +Thu Jun 13 12:55:56 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * rtag.c (locked_dir): Revise comments regarding locking; the rtag + and tag situations are different (changing from readlocking one + directory at a time to writelocking one directory at a time does + not do everything we might want, but it does fix simultaneous tags + and it doesn't make anything worse). + +Thu Jun 13 1996 Ian Lance Taylor <ian@cygnus.com> + + Prevent simultaneous tag operations from interfering with each + other. + * rtag.c (rtag_proc): Pass rtag_filesdoneproc to start_recursion, + and pass readlock as 0. + (locked_dir, locked_list): New static variables. + (rtag_fileproc): Write lock the repository if it is not already + locked. + (rtag_filesdoneproc): New static function to unlock the + repository. + * tag.c (tag): Pass tag_filesdoneproc to start_recursion, and pass + readlock as 0. + (locked_dir, locked_list): New static variables. + (tag_fileproc): Write lock the repository if it is not already + locked. + (tag_filesdoneproc): New static function. + +Thu Jun 13 11:42:25 1996 Mike Sutton <mws115@llcoolj.dayton.saic.com> + + * sanity.sh: Allow digits in usernames. + +Wed Jun 12 16:23:03 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (send_modified, update_entries): Reindent and add + comments to BROKEN_READWRITE_CONVERSION code. + +Wed Jun 12 16:23:03 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * client.c (send_modified, update_entries): Add + BROKEN_READWRITE_CONVERSION code. + +Mon Jun 10 20:03:16 1996 J.T. Conklin <jtc@cygnus.com> + + * rcs.c (RCS_gettag): No longer set p to NULL if rcs is also NULL. + rcs will never be null, thanks to the assertion at top of function. + +Mon Jun 10 16:28:14 1996 Ian Lance Taylor <ian@cygnus.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (main): Ignore CVS/Root file when doing an import. + +Fri Jun 7 18:20:01 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * status.c (status_fileproc, tag_list_proc): Use cvs_output rather + than writing to stdout directly. + +Wed Jun 5 13:54:57 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (force_tag_match, tag, date): New static variables. + (annotate_fileproc): Redo the loop to look for the version + specified by tag/date/force_tag_match, and handle branches + correctly. + (annotate_usage): Mention -f, -r, and -D. + (annotate): Handle -f, -r, and -D. + +Tue Jun 4 13:38:17 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (annotate_fileproc): Skip unrelated branch deltas. + +Fri Jun 7 13:04:01 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (main): Change INITIALIZE_SOCKET_SUBSYSTEM to + SYSTEM_INITIALIZE and pass it pointers to argc and argv. Rename + CLEANUP_SOCKET_SUBSYSTEM to SYSTEM_CLEANUP. + +Wed Jun 05 10:07:29 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * import.c (add_rcs_file): make buf char[] not unsigned char[] + +Wed Jun 05 10:07:29 1996 Mike Ladwig <mike@twinpeaks.prc.com> + and Jim Kingdon <kingdon@cyclic.com> + + * main.c (main): Add CLEANUP_SOCKET_SUBSYSTEM hook at end. Revise + comments regarding INITIALIZE_SOCKET_SUBSYSTEM. + +Wed Jun 05 10:07:29 1996 Mike Ladwig <mike@twinpeaks.prc.com> + and Jim Kingdon <kingdon@cyclic.com> + + * main.c (main): Don't mess with signals if DONT_USE_SIGNALS is + defined. + +Thu Jun 6 15:32:41 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * modules.c (cat_module): Always format for 80 columns rather than + trying to determine how wide the screen is. The code we had for + the latter didn't cover all cases, was a portability headache, and + didn't work client/server. + +Wed Jun 05 10:07:29 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * error.c: Don't declare strerror if it is #defined. + +Wed Jun 05 10:07:29 1996 Mike Ladwig <mike@twinpeaks.prc.com> + and Jim Kingdon <kingdon@cyclic.com> + + * cvs.h: If ENUMS_CAN_BE_TROUBLE, typedef Dtype to int not an enum. + +Wed Jun 05 10:07:29 1996 Mike Ladwig <mike@twinpeaks.prc.com> + and Jim Kingdon <kingdon@cyclic.com> + + * update.c (update): If DONT_USE_PATCH, don't request patches. + Also call supported_request rather than reimplementing it. + +Wed Jun 05 10:07:29 1996 Mike Ladwig <mike@twinpeaks.prc.com> + + * client.c (read_line): Changed an occurence of '\n' to '\012'. + +Wed Jun 5 17:18:46 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * add.c (add_directory): Don't create the directory if noexec. + * sanity.sh (basica): New tests basica-1a10, basica-1a11 test for + above fix. + * sanity.sh (basicb): New tests basicb-2a10, basicb-2a11, + basicb-3a1 test for analogous situation with files rather than + directories. + +Tue Jun 4 13:38:17 1996 Ian Lance Taylor <ian@cygnus.com> + + * sanity.sh: When doing a remote check, use :server: in CVSROOT. + +Wed Jun 5 13:32:40 1996 Larry Jones <larry.jones@sdrc.com> + and Jim Kingdon <kingdon@cyclic.com> + + * ignore.c: Set ign_hold to -1 when not holding instead of 0 so + that holding an empty list works correctly. + * sanity.sh (ignore): New tests 190 & 191 for above fix. + +Wed Jun 5 1996 Jim Kingdon <kingdon@cyclic.com> + + Visual C++ lint: + * client.c (update_entries): Copy the size to an unsigned variable + before comparing it with unsigned variables. + (handle_created, handle_update_existing): Prototype. + +Tue Jun 4 10:02:44 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (responses): Add Created and Update-existing responses. + * server.c (server_updated): If they are supported, use them + instead of Updated. + * client.c (struct update_entries_data): Add existp field. + (handle_checked_in, handle_updated, handle_new_entry, + handle_merged, handle_patched): Set it. + (handle_update_existing, handle_created): New functions, + for new responses. + (update_entries): Based on existp, check for + existence/nonexistence of file. + (try_read_from_server): Expand comment. + * server.c, server.h (server_updated): New argument vers. + * checkin.c (Checkin), commit.c (commit_fileproc), update.c + (update_fileproc, merge_file, join_file): Pass it. + * cvs.h: Move include of server.h after Vers_TS declaration. + * sanity.sh (conflicts2): New tests conflicts2-142d* test for + above fix. + + * sanity.sh (ignore): Fix typo in comment. + + * tag.c (tag_check_valid): Add comment clarifying when val-tags + entries are created. + +Mon Jun 3 07:26:35 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * version.c: Increment version number to 1.8.4. + +Mon Jun 3 02:20:30 1996 Noel Cragg <noel@gargle.rain.org> + + * version.c: version 1.8.3. + +Thu May 30 10:07:24 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (cmds): Fix typo ("bdif" -> "dif") which was accidentally + introduced 24 May 96. + + * main.c (main_cleanup): Add comment stating default case will + never be reached. + +Wed May 29 21:43:43 1996 noel <noel@BOAT_ANCHOR> + + * main.c (main_cleanup): check to see if SIGHUP, SIGINT, SIGQUIT, + SIGPIPE, and SIGTERM are defined before using them. Also add a + default case to print out those errors numerically which are not + found. + +Wed May 29 18:43:45 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * expand_path.c (expand_path): Document LINE == 0 and allocation + of return value. + * modules.c (do_module): Pass 0, not -1, to indicate line number + not known. Free value returned from expand_path. Deal with NULL + return from expand_path. + +Wed May 29 15:56:47 1996 Greg A. Woods <woods@most.weird.com> + + * modules.c (do_module): call expand_path() on the program name + specfied by one of '-o', '-t', or '-e' in the modules file before + passing it to run_setup(). This makes it possible to use $CVSROOT + (or indeed ~user or any other user-specified variable) to specify + pathnames for programs not installed in the normal execution path. + +Sun May 26 21:57:09 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (start_server): Don't include %s in error message; + there is no argument to go with it. Do include "internal error" + in error message since that might not be clear to the user otherwise. + +Sun May 26 11:58:13 1996 Greg A. Woods <woods@most.weird.com> + + * root.c (set_local_cvsroot): enforce a wee bit of portability + (parse_cvsroot): same.... + (DEBUG main): same, plus style guidelines + (DEBUG error): deleted -- not necessary here (use fprintf instead) + + * mkmodules.c (modules_contents): updated notes about what must be + done if you change any of the options for a module. + (loginfo_contents): fixed grammar, re-pargraphed, and added 'echo + %s;' to the example. + (editinfo_contents): minor grammar fix. + +Sun May 26 17:51:18 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * vers_ts.c (Version_TS): Remove case where we get options from + sdtp->options. Whatever case that was intended to handle is + probably lost in the mists of time, but sdtp->options isn't set + anywhere, and I think that has been true for a long time. + * cvs.h (struct stickydirtag): remove options field. + * entries.c (freesdt): Don't free ->options. + * sanity.sh (binfiles): New tests binfiles-13a* test for above fix. + + * tag.c (check_fileproc): Use fullname not file in error message. + Say "locally modified" not "up-to-date"; the file need not match + the head revision it only need match some revision. + +Sun May 26 16:57:02 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * tag.c: added support for new option -c to make sure all tagged + files are up-to-date + (tag): check for option and set check_uptodate + (check_fileproc): check status of file if check_uptodate is set + +Sat May 25 15:22:26 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (main): Revert change to look for a -H command option; + command option parsing should be up to each subcommand and the -H + global option works fine. + +Mon May 23 1996 Ian Lance Taylor <ian@cygnus.com> + + * client.c (process_prune_candidates): Set prune_candidates to + NULL at the end of the function. + +Mon May 23 1996 Ian Lance Taylor <ian@cygnus.com> + + * checkout.c (checkout): In code to handle multiple arguments, + pass preload_update_dir, not where, to Create_Admin. + (checkout_proc): Pass preload_update_dir, not where, to + Create_Admin. + +Thu May 23 19:14:35 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * server.c (server_set_sticky): Assert that update_dir != NULL. + * sanity.sh (basicb): New test; tests for Ian's fix to checkout.c + above. + +Thu May 23 1996 Ian Lance Taylor <ian@cygnus.com> + + * patch.c (patch_fileproc): Don't ignore a file just because it is + in the Attic directory. + +Thu May 23 10:40:24 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (death): New tests death-{72a,76a0,76a1} test for bug + fixed by Ian's patch_fileproc change above. + + * sanity.sh (death): Remove "temporary hack" in test 89. + + * rcs.c (RCS_fast_checkout): If error closing file, and workfile + is NULL, use sout in error message instead of workfile. + +Thu May 23 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_fast_checkout): Do a fast checkout in the case where + workfile is NULL and sout is a file name. + +Wed May 22 19:06:23 1996 Mark Immel <immel@centerline.com> + + * update.c (checkout_file): New arg resurrecting_out, to provide + resurrecting flag to caller. + (join_file): New arg resurrecting. Register with "0" if we are + the server and are resurrecting. + (update_fileproc): Pass the flag from checkout_file to join_file. + +Wed May 22 19:06:23 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (death): Test for above fix, in test 89 and new test 89a. + +Tue May 21 09:49:04 1996 Greg A. Woods <woods@most.weird.com> + + * update.c (update_usage): oops -- fix my spelling typo. + +Mon May 20 10:53:14 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * commit.c (find_fileproc): Call freevers_ts. + + * commit.c (find_*): Keep an ignlist, like update.c and client.c do. + * commit.c (commit): Process the files from the ignlists, once we + are connected to the server. + * sanity.sh (ignore): New tests 189e and 189f test for new + commit.c behavior (and client.c behavior, which is unchanged). + * sanity.sh (conflicts): Remove dir1 and sdir in parts of the test + where we aren't prepared for "? dir1" and similar output. + +Mon May 20 13:23:36 1996 Greg A. Woods <woods@most.weird.com> + + * main.c (cmd_usage): minor corrections to descriptions of status, + rtag, tag, and rdiff. Sort alphabetically by command name. + +Mon May 20 10:36:07 1996 Ian Lance Taylor <ian@cygnus.com> + + * client.c (call_in_directory): Move the call to Entries_Close + before the call to chdir, since Entries_Close examines files in + the current directory. + +Fri May 17 12:13:09 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * client.c (start_tcp_server, start_server, start_rsh_server, + read_line, filter_through_gzip, filter_through_gunzip, + call_in_directory): Reindent as needed. + + * main.c (main): Add missing #endif. Use indentation to indicate + nesting. + +Thu May 16 17:15:01 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (cmd_usage): Add "init" command. + +Thu May 16 16:45:51 1996 Noel Cragg <noel@gargle.rain.org> + + * client.c (start_tcp_server): Error message modified to tell the + user to use ":server:" instead of setting CVS_CLIENT_PORT to a + negative number. + + * main.c (main): Add #ifdefs for turning off buffering of + stdio/stderr, so we don't get it by default. + +Thu May 16 01:29:47 1996 noel <noel@BOAT_ANCHOR> + + * commit.c (commit_filesdoneproc): Print the repository and root + directories as part of the error message. + + * main.c (main): Don't buffer stdout or stderr. It's inefficient, + but it then produces the right output for sanity.sh. + +Thu May 16 09:44:47 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * fileattr.c (fileattr_set): In the case where we are about to + call delproc, don't free ->data; delproc does that. + * sanity.sh (devcom): New tests devcom-b* test for this fix. + + * sanity.sh (conflicts): Remove redundant clean up from previous + tests at the beginning of the test. Use dotest a few more places. + (conflicts2): New test, tests for Ian's fix to Classify_File. + + * client.c (remove_entry_and_file): Add comment about + existence_error's. + +Sat May 16 1996 Ian Lance Taylor <ian@cygnus.com> + + * update.c (update_dirleave_proc): Don't try to chdir .. and check + for an empty directory if there is a slash in the directory name. + +Thu May 16 09:02:59 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (deep): New tests deep-4a* test for Ian's fix to + update_dirleave_proc. + +Sat May 16 1996 Ian Lance Taylor <ian@cygnus.com> + + * main.c (main_cleanup): Report signal name before dying. + +Wed May 15 23:47:59 1996 Noel Cragg <noel@gargle.rain.org> + + * main.c (usg): revert usage strings for `-H' flag change. + +Sat May 15 1996 Ian Lance Taylor <ian@cygnus.com> + + * server.c (serve_static_directory): Return immediately if there + is a pending error. + (serve_sticky): Likewise. + (serve_modified): Read the file data even if there is a pending + error. + +Wed May 15 14:26:32 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (main): If -d and CVS/Root both specified, after writing + the value from -d into CVS/Root, use the value from -d, not the + old value from CVS/Root. Don't write CVS/Root with value from -d + until we have verified that it works. + * sanity.sh: Reenable test basica-9 and adjust for new behavior. + +Tue May 14 1996 Jim Kingdon <kingdon@cyclic.com> + + * logmsg.c (do_editor): If user aborts the commit, still remove the + temporary file. + +Tue May 14 11:45:41 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c, cvs.h (cvs_temp_name): New function. Move L_tmpnam + define from cvs.h to filesubr.c. + * client.c, diff.c, import.c, login.c, logmsg.c, no_diff.c, + patch.c, wrapper.c: Call cvs_temp_name not tmpnam. + * login.c (login): Reindent function. + +Tue May 14 10:56:56 1996 Ian Lance Taylor <ian@cygnus.com> + + * rcs.c (RCS_fast_checkout): If workfile is NULL, don't call chmod. + +Mon May 13 10:52:10 1996 Greg A. Woods <woods@most.weird.com> + + * checkout.c (export_usage): note which options cause a sticky + version to be set, and which option avoids this. + * update.c (update_usage): likewise + +Sat May 11 18:57:07 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh: Comment out test basica-9 until I get around to + actually fixing it (the -d vs. CVS/Root change broke it). + +Fri May 10 09:39:49 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c (main): -d now overrides CVS/Root. + +Thu May 9 19:45:24 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * main.c: Remove comment listing commands at beginning. It was + out of date and redundant with the help. + +Thu May 9 09:33:55 1996 Greg A. Woods <woods@most.weird.com> + + * main.c: add 'init' to opening comment listing commands + + * mkmodules.c (init): fix to recognize argc==-1 as hint to call + usage() [should make "cvs init -H" work as expected] + +Wed May 8 15:02:49 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh: Set EXPR in the case that the expr in the path is the + one that we want. + +Wed May 8 14:06:24 1996 Greg A. Woods <woods@most.weird.com> + + * sanity.sh (test): - convert all '[' to test ala GCD + +Wed May 8 13:46:56 1996 Greg A. Woods <woods@most.weird.com> + + * sanity.sh (expr): - make a valiant attempt to find GNU expr + - Patch from Larry Jones: + sanity test deep-4 failed with "expr: arg list too long" + sanity test 56 failed because the stderr and stdout output was not + interleaved as expected. + sanity test modules-155a4 failed with "ls: illegal option -- 1" + + * main.c (main): - Patch from Larry Jones for SysV setvbuf + +Tue May 7 16:41:16 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * version.c: Increment version number to 1.8.2 to work around fact + that CVS 1.8 (confusingly) calls itself 1.8.1 not 1.8. + +Tue May 7 10:44:20 MET DST 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * rcs.c (rcsvers_delproc): fix memory leak by freeing author + field. + +Mon May 6 10:40:05 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * sanity.sh (conflicts): New test conflicts-126.5 tests for bug + which Ian fixed May 5 in update.c + +Mon May 6 06:00:10 1996 Benjamin J. Lee <benjamin@cyclic.com> + + * Version 1.8.1 + Sun May 5 21:39:02 1996 Jim Kingdon <kingdon@harvey.cyclic.com> * vers_ts.c (Version_TS): If sdtp is NULL, go ahead and check @@ -18,6 +2232,31 @@ Sun May 5 17:38:21 1996 Benjamin J. Lee <benjamin@cyclic.com> repository which will be checked out to the same name as the directory. +Sat May 4 12:33:02 1996 Ian Lance Taylor <ian@cygnus.com> + + Extract the head revision directly from the RCS file when + possible, rather than execing co. + * rcs.c (RCS_reparsercsfile): Set delta_pos field. + (getrcskey): Add lenp parameter. Change all callers. + (RCS_fast_checkout): New function. + (annotate_fileproc): If PARTIAL is not set, just fseek to + delta_pos. + * rcs.h (struct rcsnode): Add delta_pos field. + (RCS_fast_checkout): Declare. + * diff.c (diff_file_nodiff): Call RCS_fast_checkout rather than + RCS_checkout. + * import.c (update_rcs_file): Likewise. + * no_diff.c (No_Difference): Likewise. + * patch.c (patch_fileproc): Likewise. + * update.c (checkout_file): Likewise. + (patch_file): Likewise. + (join_file): Likewise. + +Sat May 4 12:33:02 1996 Ian Lance Taylor <ian@cygnus.com> + + * classify.c (Classify_File): Don't report a conflict for a + pending remove if somebody else has already removed the file. + Thu May 2 13:34:37 1996 Benjamin J. Lee <benjamin@cyclic.com> * Version 1.7.88 @@ -28,6 +2267,18 @@ Thu May 2 01:40:55 1996 Benjamin J. Lee <benjamin@cyclic.com> located by configure, in the event a system has crypt(), but no initgroups() +Wed May 01 21:08:21 1996 noel <noel@BOAT_ANCHOR> + + * client.c (filter_through_gunzip): use "gzip -d" instead of + "gunzip," since there's no good reason (on NT at least) to have an + extra copy of gzip.exe copied to gunzip.exe (Arrrrgh! No symbolic + links!). + + * mkmodules.c (init): check to see that we have the correct number + of arguments or print out the usage message (used to be argc > 1, + should be argc != 1, because help forces argc == -1 as a special + case). + Wed May 1 18:05:02 1996 Jim Kingdon <kingdon@harvey.cyclic.com> * sanity.sh (basica): When testing rejection of reserved tag name, @@ -57,11 +2308,198 @@ Tue Apr 30 15:46:03 1996 Jim Kingdon <kingdon@harvey.cyclic.com> * server.c (check_password): Don't use ANSI string concatenation. Reindent function. +Mon Apr 29 10:48:38 1996 Noel Cragg <noel@gargle> + + * root.c (parse_cvsroot): removed "rsh" as an alias to "server" in + the method section. + + * main.c (main): new variable help so we can support the `cvs -H + cmd' convention. Reverts change of 26 Apr 96 which removed this + feature. + +Sun Apr 28 14:57:38 1996 Noel Cragg <noel@gargle> + + * main.c (main): update error message if parse_cvsroot fails. + * server.c (serve_root): same. + (serve_init): same. + + * client.c (start_tcp_server): get rid of the "fall through" + stuff, now that we have access methods. + (start_server): switch off the access method to choose routine + that starts the server. + (start_tcp_server): tofd wasn't getting set to -1 early enough, + because a call to error for bind or gethostbyname might fail and + the subsequent error check to see if the connection had been made + would fail. + + * root.c: new variable method_names for error reporting purposes. + +Sun Apr 28 17:22:15 1996 Noel Cragg <noel@occs.cs.oberlin.edu> + + * server.c: moved kerberos #includes from main.c for the + kserver_authenticate_connection routine. + +Fri Apr 26 07:59:44 1996 Noel Cragg <noel@gargle> + + * server.c (serve_init): use the new return value from + parse_cvsroot. + (serve_root): same. + * main.c (main): same. + + * root.c (parse_cvsroot): fix indentation, add a return value + which tells whether the command succeeded or failed. + + * main.c (main): move the setting of the UMASK environment + variable inside the stuff that gets done if the user is NOT asking + for help, so we don't signal any errors prematurely (don't want to + give an error because we can't parse an environment variable + correctly if the user asks for help). Similar mods for the code + that tries to get the working directory. + + Also make CVSADM_Root a local variable instead of a global, since + its scope is only about 20 lines here! + + * server.c (kserver_authenticate_connection): moved code from + main.c to clean up MAIN. Makes sense, since we already have a + pserver_authenticate_connection. + (pserver_authenticate_connection): rename from + authenticate_connection. + + * main.c (main): reorganized the routine to eliminate variables + help, help_commands, and version_flag. Now the routine is much + clearer, since we don't have to be checking to see if these + variables are set. One behavior that was a bug/feature which is + now gone is an invocation like "cvs -H rtag" -- previously this + would give usage for rtag, but now gives usage for cvs itself. + The first behavior didn't make sense, especially since we say in + the docs that command-line flags are position-specific. *Reverted + Above* + +Thu Apr 25 20:05:10 1996 Noel Cragg <noel@gargle> + + * main.c (main): make sure we have a valid command name before we + do anything else (moved the thing that looks for a command in CMDS + to right after the GETOPT loop). Added `kserver' and `pserver' to + the table so they will be recognized; set their functions to + SERVER so that help will be given when asked for. + + * expand_path.c (expand_variable): return CVSroot_original rather + than CVSroot_directory. + + * main.c (main): save CVSroot in the env rather than + CVSroot_original, since we might not have called PARSE_CVSROOT + (this can happen if we use the -H option to a command). + + * root.c (parse_cvsroot): the parsing method was bogus for + guessing when we had hostnames vs. directories specified. Any + ambiguity should be removed by having the user specify the access + method. If the access method isn't specified, choose + server_method if the string contains a colon or local_method + otherwise. + + * Changed CVSroot_remote back to client_active since the code + reads better. + Wed Apr 24 17:27:53 1996 Norbert Kiesel <nk@col.sw-ley.de> * vers_ts.c (Version_TS): xmalloc enough space (1 more byte). Thanks to purify! +Mon Apr 22 00:38:08 1996 Noel Cragg <noel@gargle> + + * create_adm.c (Create_Admin): pass CVSroot_original instead of + CVSroot_directory (oops!). + * update.c (update_filesdone_proc): same. + + * server.c (serve_root): modify to use parse_cvsroot rather than + goofing around with other variables. Will need to fix + parse_cvsroot to have a return value so we can return an error and + quit gracefully if in server mode. + (serve_init): same. + + * main.c: modify command table to remove client_* routines, since + they no longer exist. + (main): don't try to switch off non-existent field in command + table! ;-) + + * client.h (client_*): removed prototypes for now non-existent + functions. + + * client.c: remove proto for get_cvs_password, since it is now in + cvs.h. Modify routines to use new globals that describe CVSROOT + rather than client_active, server_host, server_user, and + server_cvsroot. + (parse_cvsroot): removed function, since a more generic version + now lives in root.c. + (connect_to_pserver): remove call to parse_cvsroot, since main.c + has already done it for us. + (client_*): removed all of these routines, since they only call + parse_cvsroot and then their respective operation functions. + Since main.c has already called parse_cvsroot, we shouldn't bother + with the extra function call, since client-server diffs are + already handled in the core routines themselves. + + * main.c: remove CVSroot as a global variable. Remove + use_authenticating_server variable since we have a new + `CVSroot_method' variable instead. + (main): add `CVSroot' as a local variable. Call parse_cvsroot + after we're sure we have the right setting for `CVSroot.' + + * login.c (login): update to use new global variables. Instead of + old behavior which let the user type in user@host when prompted, + it makes them do it in CVSROOT proper. The routine still lets the + user type the password, however. + (get_cvs_password): make sure that CVSROOT is fully qualified + before trying to find the entry in the .cvspass file. + * cvs.h: add prototype for get_cvs_password. + + * add.c: use new globals that describe CVSROOT. + * admin.c: same. + * checkout.c: same. + * commit.c: same. + * create_adm.c: same. + * diff.c: same. + * edit.c: same. + * expand_path.c: same. + * history.c: same. + * ignore.c: same. + * import.c: same. + * log.c: same. + * mkmodules.c: same. + * modules.c: same. + * parseinfo.c: same. + * patch.c: same. + * rcs.c: same. + * recurse.c: same. + * release.c: same. + * remove.c: same. + * repos.c: same. + * rtag.c: same. + * status.c: same. + * tag.c: same. + * update.c: same. + * watch.c: same. + * wrapper.c: same. + + * root.c (Name_Root): remove error message that reports missing + CVSROOT, since new code in main.c will catch it and also print out + an error. + (parse_cvsroot): new function -- takes a CVSROOT string and breaks + it up into its component parts -- method, hostname, username, and + repository directory. Sets new global variables that describe the + repository location more precisely: CVSroot_original, + CVSroot_remote, CVSroot_method, CVSroot_username, + CVSroot_hostname, CVSroot_directory for use by all other + functions. Checks for obvious errors in format of string. + (main): a short routine to test parse_cvsroot from the command + line. + * cvs.h: add prototype for parse_cvsroot and extern definitions + for new globals. + + * cvs.h: removed CVSroot variable, since we don't want other + routines using the raw CVSROOT (also helped to find all of the + refs to the variable!). + Fri Apr 19 11:22:35 1996 Benjamin J. Lee <benjamin@cyclic.com> * Version 1.7.86 diff --git a/gnu/usr.bin/cvs/src/add.c b/gnu/usr.bin/cvs/src/add.c index 82efefe71ca..08f6acc58af 100644 --- a/gnu/usr.bin/cvs/src/add.c +++ b/gnu/usr.bin/cvs/src/add.c @@ -27,7 +27,7 @@ #include "cvs.h" #include "savecwd.h" -static int add_directory PROTO((char *repository, char *dir)); +static int add_directory PROTO((char *repository, List *, char *dir)); static int build_entry PROTO((char *repository, char *user, char *options, char *message, List * entries, char *tag)); @@ -115,6 +115,8 @@ add (argc, argv) sprintf (rcsdir, "%s/%s", repository, argv[i]); + strip_trailing_slashes (argv[i]); + Create_Admin (argv[i], argv[i], rcsdir, tag, date); if (tag) @@ -122,6 +124,19 @@ add (argc, argv) if (date) free (date); free (rcsdir); + + if (strchr (argv[i], '/') == NULL) + Subdir_Register ((List *) NULL, (char *) NULL, argv[i]); + else + { + char *cp, *b; + + cp = xstrdup (argv[i]); + b = strrchr (cp, '/'); + *b++ = '\0'; + Subdir_Register ((List *) NULL, cp, b); + free (cp); + } } send_file_names (argc, argv, SEND_EXPAND_WILD); send_files (argc, argv, 0, 0); @@ -137,6 +152,7 @@ add (argc, argv) { int begin_err = err; int begin_added_files = added_files; + struct file_info finfo; user = argv[i]; strip_trailing_slashes (user); @@ -148,8 +164,19 @@ add (argc, argv) continue; } - vers = Version_TS (repository, options, (char *) NULL, (char *) NULL, - user, 0, 0, entries, (RCSNode *) NULL); + memset (&finfo, 0, sizeof finfo); + finfo.file = user; + finfo.update_dir = ""; + finfo.fullname = user; + finfo.repository = repository; + finfo.entries = entries; + finfo.rcs = NULL; + + /* We pass force_tag_match as 1. If the directory has a + sticky branch tag, and there is already an RCS file which + does not have that tag, then the head revision is + meaningless to us. */ + vers = Version_TS (&finfo, options, NULL, NULL, 1, 0); if (vers->vn_user == NULL) { /* No entry available, ts_rcs is invalid */ @@ -180,11 +207,25 @@ add (argc, argv) error (1, 0, "illegal filename overlap"); } + if (vers->options == NULL || *vers->options == '\0') + { + /* No options specified on command line (or in + rcs file if it existed, e.g. the file exists + on another branch). Check for a value from + the wrapper stuff. */ + if (wrap_name_has (user, WRAP_RCSOPTION)) + { + if (vers->options) + free (vers->options); + vers->options = wrap_rcsoption (user, 1); + } + } + /* 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 + else { added_files++; if (!quiet) @@ -219,8 +260,12 @@ scheduling %s `%s' for addition on branch `%s'", error (0, 0, "file `%s' will be added on branch `%s' from version %s", user, vers->tag, vers->vn_rcs); else - error (0, 0, "version %s of `%s' will be resurrected", - vers->vn_rcs, user); + /* 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; @@ -316,7 +361,7 @@ scheduling %s `%s' for addition on branch `%s'", && isdir (user) && !wrap_name_has (user, WRAP_TOCVS)) { - err += add_directory (repository, user); + err += add_directory (repository, entries, user); continue; } #ifdef SERVER_SUPPORT @@ -344,8 +389,9 @@ scheduling %s `%s' for addition on branch `%s'", * Returns 1 on failure, 0 on success. */ static int -add_directory (repository, dir) +add_directory (repository, entries, dir) char *repository; + List *entries; char *dir; { char rcsdir[PATH_MAX]; @@ -371,7 +417,7 @@ add_directory (repository, dir) /* now, remember where we were, so we can get back */ if (save_cwd (&cwd)) return (1); - if (chdir (dir) < 0) + if ( CVS_CHDIR (dir) < 0) { error (0, errno, "cannot chdir to %s", dir); return (1); @@ -413,6 +459,7 @@ add_directory (repository, dir) mode_t omask; Node *p; List *ulist; + struct logfile_info *li; #if 0 char line[MAXLINELEN]; @@ -429,14 +476,17 @@ add_directory (repository, dir) } #endif - omask = umask (cvsumask); - if (CVS_MKDIR (rcsdir, 0777) < 0) + if (!noexec) { - error (0, errno, "cannot mkdir %s", rcsdir); + omask = umask (cvsumask); + if (CVS_MKDIR (rcsdir, 0777) < 0) + { + error (0, errno, "cannot mkdir %s", rcsdir); + (void) umask (omask); + goto out; + } (void) umask (omask); - goto out; } - (void) umask (omask); /* * Set up an update list with a single title node for Update_Logfile @@ -446,9 +496,12 @@ add_directory (repository, dir) p->type = UPDATE; p->delproc = update_delproc; p->key = xstrdup ("- New directory"); - p->data = (char *) T_TITLE; + li = (struct logfile_info *) xmalloc (sizeof (struct logfile_info)); + li->type = T_TITLE; + li->tag = xstrdup (tag); + p->data = (char *) li; (void) addnode (ulist, p); - Update_Logfile (rcsdir, message, (char *) NULL, (FILE *) NULL, ulist); + Update_Logfile (rcsdir, message, (FILE *) NULL, ulist); dellist (&ulist); } @@ -463,7 +516,16 @@ add_directory (repository, dir) if (date) free (date); + if (restore_cwd (&cwd, NULL)) + exit (EXIT_FAILURE); + free_cwd (&cwd); + + Subdir_Register (entries, (char *) NULL, dir); + (void) printf ("%s", message); + + return (0); + out: if (restore_cwd (&cwd, NULL)) exit (EXIT_FAILURE); diff --git a/gnu/usr.bin/cvs/src/buffer.c b/gnu/usr.bin/cvs/src/buffer.c new file mode 100644 index 00000000000..8baa021fbb9 --- /dev/null +++ b/gnu/usr.bin/cvs/src/buffer.c @@ -0,0 +1,1294 @@ +/* Code for the buffer data structure. */ + +#include <assert.h> +#include "cvs.h" +#include "buffer.h" + +#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) + +/* OS/2 doesn't have EIO. FIXME: this whole notion of turning + a different error into EIO strikes me as pretty dubious. */ +#if !defined (EIO) +#define EIO EBADPOS +#endif + +/* Linked list of available buffer_data structures. */ +static struct buffer_data *free_buffer_data; + +/* Local functions. */ +static void allocate_buffer_datas PROTO((void)); +static struct buffer_data *get_buffer_data PROTO((void)); + +/* Initialize a buffer structure. */ + +struct buffer * +buf_initialize (input, output, flush, block, shutdown, memory, closure) + int (*input) PROTO((void *, char *, int, int, int *)); + int (*output) PROTO((void *, const char *, int, int *)); + int (*flush) PROTO((void *)); + int (*block) PROTO((void *, int)); + int (*shutdown) PROTO((void *)); + void (*memory) PROTO((struct buffer *)); + void *closure; +{ + struct buffer *buf; + + buf = (struct buffer *) xmalloc (sizeof (struct buffer)); + buf->data = NULL; + buf->last = NULL; + buf->nonblocking = 0; + buf->input = input; + buf->output = output; + buf->flush = flush; + buf->block = block; + buf->shutdown = shutdown; + buf->memory_error = memory; + buf->closure = closure; + return buf; +} + +/* Initialize a buffer structure which is not to be used for I/O. */ + +struct buffer * +buf_nonio_initialize (memory) + void (*memory) PROTO((struct buffer *)); +{ + return (buf_initialize + ((int (*) PROTO((void *, char *, int, int, int *))) NULL, + (int (*) PROTO((void *, const char *, int, int *))) NULL, + (int (*) PROTO((void *))) NULL, + (int (*) PROTO((void *, int))) NULL, + (int (*) PROTO((void *))) NULL, + memory, + (void *) NULL)); +} + +/* Allocate more buffer_data structures. */ + +static void +allocate_buffer_datas () +{ + struct buffer_data *alc; + char *space; + int i; + + /* Allocate buffer_data structures in blocks of 16. */ +#define ALLOC_COUNT (16) + + alc = ((struct buffer_data *) + malloc (ALLOC_COUNT * sizeof (struct buffer_data))); + space = (char *) valloc (ALLOC_COUNT * BUFFER_DATA_SIZE); + if (alc == NULL || space == NULL) + return; + for (i = 0; i < ALLOC_COUNT; i++, alc++, space += BUFFER_DATA_SIZE) + { + alc->next = free_buffer_data; + free_buffer_data = alc; + alc->text = space; + } +} + +/* Get a new buffer_data structure. */ + +static struct buffer_data * +get_buffer_data () +{ + struct buffer_data *ret; + + if (free_buffer_data == NULL) + { + allocate_buffer_datas (); + if (free_buffer_data == NULL) + return NULL; + } + + ret = free_buffer_data; + free_buffer_data = ret->next; + return ret; +} + +/* See whether a buffer is empty. */ + +int +buf_empty_p (buf) + struct buffer *buf; +{ + struct buffer_data *data; + + for (data = buf->data; data != NULL; data = data->next) + if (data->size > 0) + return 0; + return 1; +} + +#ifdef SERVER_FLOWCONTROL +/* + * Count how much data is stored in the buffer.. + * Note that each buffer is a malloc'ed chunk BUFFER_DATA_SIZE. + */ + +int +buf_count_mem (buf) + struct buffer *buf; +{ + struct buffer_data *data; + int mem = 0; + + for (data = buf->data; data != NULL; data = data->next) + mem += BUFFER_DATA_SIZE; + + return mem; +} +#endif /* SERVER_FLOWCONTROL */ + +/* Add data DATA of length LEN to BUF. */ + +void +buf_output (buf, data, len) + struct buffer *buf; + const char *data; + int len; +{ + if (buf->data != NULL + && (((buf->last->text + BUFFER_DATA_SIZE) + - (buf->last->bufp + buf->last->size)) + >= len)) + { + memcpy (buf->last->bufp + buf->last->size, data, len); + buf->last->size += len; + return; + } + + while (1) + { + struct buffer_data *newdata; + + newdata = get_buffer_data (); + if (newdata == NULL) + { + (*buf->memory_error) (buf); + return; + } + + if (buf->data == NULL) + buf->data = newdata; + else + buf->last->next = newdata; + newdata->next = NULL; + buf->last = newdata; + + newdata->bufp = newdata->text; + + if (len <= BUFFER_DATA_SIZE) + { + newdata->size = len; + memcpy (newdata->text, data, len); + return; + } + + newdata->size = BUFFER_DATA_SIZE; + memcpy (newdata->text, data, BUFFER_DATA_SIZE); + + data += BUFFER_DATA_SIZE; + len -= BUFFER_DATA_SIZE; + } + + /*NOTREACHED*/ +} + +/* Add a '\0' terminated string to BUF. */ + +void +buf_output0 (buf, string) + struct buffer *buf; + const char *string; +{ + buf_output (buf, string, strlen (string)); +} + +/* Add a single character to BUF. */ + +void +buf_append_char (buf, ch) + struct buffer *buf; + int ch; +{ + if (buf->data != NULL + && (buf->last->text + BUFFER_DATA_SIZE + != buf->last->bufp + buf->last->size)) + { + *(buf->last->bufp + buf->last->size) = ch; + ++buf->last->size; + } + else + { + char b; + + b = ch; + buf_output (buf, &b, 1); + } +} + +/* + * Send all the output we've been saving up. Returns 0 for success or + * errno code. If the buffer has been set to be nonblocking, this + * will just write until the write would block. + */ + +int +buf_send_output (buf) + struct buffer *buf; +{ + if (buf->output == NULL) + abort (); + + while (buf->data != NULL) + { + struct buffer_data *data; + + data = buf->data; + + if (data->size > 0) + { + int status, nbytes; + + status = (*buf->output) (buf->closure, data->bufp, data->size, + &nbytes); + if (status != 0) + { + /* Some sort of error. Discard the data, and return. */ + + buf->last->next = free_buffer_data; + free_buffer_data = buf->data; + buf->data = NULL; + buf->last = NULL; + + return status; + } + + if (nbytes != data->size) + { + /* Not all the data was written out. This is only + permitted in nonblocking mode. Adjust the buffer, + and return. */ + + assert (buf->nonblocking); + + data->size -= nbytes; + data->bufp += nbytes; + + return 0; + } + } + + buf->data = data->next; + data->next = free_buffer_data; + free_buffer_data = data; + } + + buf->last = NULL; + + return 0; +} + +/* + * Flush any data queued up in the buffer. If BLOCK is nonzero, then + * if the buffer is in nonblocking mode, put it into blocking mode for + * the duration of the flush. This returns 0 on success, or an error + * code. + */ + +int +buf_flush (buf, block) + struct buffer *buf; + int block; +{ + int nonblocking; + int status; + + if (buf->flush == NULL) + abort (); + + nonblocking = buf->nonblocking; + if (nonblocking && block) + { + status = set_block (buf); + if (status != 0) + return status; + } + + status = buf_send_output (buf); + if (status == 0) + status = (*buf->flush) (buf->closure); + + if (nonblocking && block) + { + int blockstat; + + blockstat = set_nonblock (buf); + if (status == 0) + status = blockstat; + } + + return status; +} + +/* + * Set buffer BUF to nonblocking I/O. Returns 0 for success or errno + * code. + */ + +int +set_nonblock (buf) + struct buffer *buf; +{ + int status; + + if (buf->nonblocking) + return 0; + if (buf->block == NULL) + abort (); + status = (*buf->block) (buf->closure, 0); + if (status != 0) + return status; + buf->nonblocking = 1; + return 0; +} + +/* + * Set buffer BUF to blocking I/O. Returns 0 for success or errno + * code. + */ + +int +set_block (buf) + struct buffer *buf; +{ + int status; + + if (! buf->nonblocking) + return 0; + if (buf->block == NULL) + abort (); + status = (*buf->block) (buf->closure, 1); + if (status != 0) + return status; + buf->nonblocking = 0; + return 0; +} + +/* + * Send a character count and some output. Returns errno code or 0 for + * success. + * + * Sending the count in binary is OK since this is only used on a pipe + * within the same system. + */ + +int +buf_send_counted (buf) + struct buffer *buf; +{ + int size; + struct buffer_data *data; + + size = 0; + for (data = buf->data; data != NULL; data = data->next) + size += data->size; + + data = get_buffer_data (); + if (data == NULL) + { + (*buf->memory_error) (buf); + return ENOMEM; + } + + data->next = buf->data; + buf->data = data; + if (buf->last == NULL) + buf->last = data; + + data->bufp = data->text; + data->size = sizeof (int); + + *((int *) data->text) = size; + + return buf_send_output (buf); +} + +/* + * Send a special count. COUNT should be negative. It will be + * handled speciallyi by buf_copy_counted. This function returns 0 or + * an errno code. + * + * Sending the count in binary is OK since this is only used on a pipe + * within the same system. + */ + +int +buf_send_special_count (buf, count) + struct buffer *buf; + int count; +{ + struct buffer_data *data; + + data = get_buffer_data (); + if (data == NULL) + { + (*buf->memory_error) (buf); + return ENOMEM; + } + + data->next = buf->data; + buf->data = data; + if (buf->last == NULL) + buf->last = data; + + data->bufp = data->text; + data->size = sizeof (int); + + *((int *) data->text) = count; + + return buf_send_output (buf); +} + +/* Append a list of buffer_data structures to an buffer. */ + +void +buf_append_data (buf, data, last) + struct buffer *buf; + struct buffer_data *data; + struct buffer_data *last; +{ + if (data != NULL) + { + if (buf->data == NULL) + buf->data = data; + else + buf->last->next = data; + buf->last = last; + } +} + +/* + * Copy the contents of file F into buffer_data structures. We can't + * copy directly into an buffer, because we want to handle failure and + * succeess differently. Returns 0 on success, or -2 if out of + * memory, or a status code on error. Since the caller happens to + * know the size of the file, it is passed in as SIZE. On success, + * this function sets *RETP and *LASTP, which may be passed to + * buf_append_data. + */ + +int +buf_read_file (f, size, retp, lastp) + FILE *f; + long size; + struct buffer_data **retp; + struct buffer_data **lastp; +{ + int status; + + *retp = NULL; + *lastp = NULL; + + while (size > 0) + { + struct buffer_data *data; + int get; + + data = get_buffer_data (); + if (data == NULL) + { + status = -2; + goto error_return; + } + + if (*retp == NULL) + *retp = data; + else + (*lastp)->next = data; + data->next = NULL; + *lastp = data; + + data->bufp = data->text; + data->size = 0; + + if (size > BUFFER_DATA_SIZE) + get = BUFFER_DATA_SIZE; + else + get = size; + + errno = EIO; + if (fread (data->text, get, 1, f) != 1) + { + status = errno; + goto error_return; + } + + data->size += get; + size -= get; + } + + return 0; + + error_return: + if (*retp != NULL) + { + (*lastp)->next = free_buffer_data; + free_buffer_data = *retp; + } + return status; +} + +/* + * Copy the contents of file F into buffer_data structures. We can't + * copy directly into an buffer, because we want to handle failure and + * succeess differently. Returns 0 on success, or -2 if out of + * memory, or a status code on error. On success, this function sets + * *RETP and *LASTP, which may be passed to buf_append_data. + */ + +int +buf_read_file_to_eof (f, retp, lastp) + FILE *f; + struct buffer_data **retp; + struct buffer_data **lastp; +{ + int status; + + *retp = NULL; + *lastp = NULL; + + while (!feof (f)) + { + struct buffer_data *data; + int get, nread; + + data = get_buffer_data (); + if (data == NULL) + { + status = -2; + goto error_return; + } + + if (*retp == NULL) + *retp = data; + else + (*lastp)->next = data; + data->next = NULL; + *lastp = data; + + data->bufp = data->text; + data->size = 0; + + get = BUFFER_DATA_SIZE; + + errno = EIO; + nread = fread (data->text, 1, get, f); + if (nread == 0 && !feof (f)) + { + status = errno; + goto error_return; + } + + data->size = nread; + } + + return 0; + + error_return: + if (*retp != NULL) + { + (*lastp)->next = free_buffer_data; + free_buffer_data = *retp; + } + return status; +} + +/* Return the number of bytes in a chain of buffer_data structures. */ + +int +buf_chain_length (buf) + struct buffer_data *buf; +{ + int size = 0; + while (buf) + { + size += buf->size; + buf = buf->next; + } + return size; +} + +/* + * Read an arbitrary amount of data into an input buffer. The buffer + * will be in nonblocking mode, and we just grab what we can. Return + * 0 on success, or -1 on end of file, or -2 if out of memory, or an + * error code. If COUNTP is not NULL, *COUNTP is set to the number of + * bytes read. + */ + +int +buf_input_data (buf, countp) + struct buffer *buf; + int *countp; +{ + if (buf->input == NULL) + abort (); + + if (countp != NULL) + *countp = 0; + + while (1) + { + int get; + int status, nbytes; + + if (buf->data == NULL + || (buf->last->bufp + buf->last->size + == buf->last->text + BUFFER_DATA_SIZE)) + { + struct buffer_data *data; + + data = get_buffer_data (); + if (data == NULL) + { + (*buf->memory_error) (buf); + return -2; + } + + if (buf->data == NULL) + buf->data = data; + else + buf->last->next = data; + data->next = NULL; + buf->last = data; + + data->bufp = data->text; + data->size = 0; + } + + get = ((buf->last->text + BUFFER_DATA_SIZE) + - (buf->last->bufp + buf->last->size)); + + status = (*buf->input) (buf->closure, + buf->last->bufp + buf->last->size, + 0, get, &nbytes); + if (status != 0) + return status; + + buf->last->size += nbytes; + if (countp != NULL) + *countp += nbytes; + + if (nbytes < get) + { + /* If we did not fill the buffer, then presumably we read + all the available data. */ + return 0; + } + } + + /*NOTREACHED*/ +} + +/* + * Read a line (characters up to a \012) from an input buffer. (We + * use \012 rather than \n for the benefit of non Unix clients for + * which \n means something else). This returns 0 on success, or -1 + * on end of file, or -2 if out of memory, or an error code. If it + * succeeds, it sets *LINE to an allocated buffer holding the contents + * of the line. The trailing \012 is not included in the buffer. If + * LENP is not NULL, then *LENP is set to the number of bytes read; + * strlen may not work, because there may be embedded null bytes. + */ + +int +buf_read_line (buf, line, lenp) + struct buffer *buf; + char **line; + int *lenp; +{ + if (buf->input == NULL) + abort (); + + *line = NULL; + + while (1) + { + int len, finallen; + struct buffer_data *data; + char *nl; + + /* See if there is a newline in BUF. */ + len = 0; + for (data = buf->data; data != NULL; data = data->next) + { + nl = memchr (data->bufp, '\012', data->size); + if (nl != NULL) + { + finallen = nl - data->bufp; + len += finallen; + break; + } + len += data->size; + } + + /* If we found a newline, copy the line into a memory buffer, + and remove it from BUF. */ + if (data != NULL) + { + char *p; + struct buffer_data *nldata; + + p = malloc (len + 1); + if (p == NULL) + return -2; + *line = p; + + nldata = data; + data = buf->data; + while (data != nldata) + { + struct buffer_data *next; + + memcpy (p, data->bufp, data->size); + p += data->size; + next = data->next; + data->next = free_buffer_data; + free_buffer_data = data; + data = next; + } + + memcpy (p, data->bufp, finallen); + p[finallen] = '\0'; + + data->size -= finallen + 1; + data->bufp = nl + 1; + buf->data = data; + + if (lenp != NULL) + *lenp = len; + + return 0; + } + + /* Read more data until we get a newline. */ + while (1) + { + int size, status, nbytes; + char *mem; + + if (buf->data == NULL + || (buf->last->bufp + buf->last->size + == buf->last->text + BUFFER_DATA_SIZE)) + { + data = get_buffer_data (); + if (data == NULL) + { + (*buf->memory_error) (buf); + return -2; + } + + if (buf->data == NULL) + buf->data = data; + else + buf->last->next = data; + data->next = NULL; + buf->last = data; + + data->bufp = data->text; + data->size = 0; + } + + mem = buf->last->bufp + buf->last->size; + size = (buf->last->text + BUFFER_DATA_SIZE) - mem; + + /* We need to read at least 1 byte. We can handle up to + SIZE bytes. This will only be efficient if the + underlying communication stream does its own buffering, + or is clever about getting more than 1 byte at a time. */ + status = (*buf->input) (buf->closure, mem, 1, size, &nbytes); + if (status != 0) + return status; + + buf->last->size += nbytes; + + /* Optimize slightly to avoid an unnecessary call to + memchr. */ + if (nbytes == 1) + { + if (*mem == '\012') + break; + } + else + { + if (memchr (mem, '\012', nbytes) != NULL) + break; + } + } + } +} + +/* + * Extract data from the input buffer BUF. This will read up to WANT + * bytes from the buffer. It will set *RETDATA to point at the bytes, + * and set *GOT to the number of bytes to be found there. Any buffer + * call which uses BUF may change the contents of the buffer at *DATA, + * so the data should be fully processed before any further calls are + * made. This returns 0 on success, or -1 on end of file, or -2 if + * out of memory, or an error code. + */ + +int +buf_read_data (buf, want, retdata, got) + struct buffer *buf; + int want; + char **retdata; + int *got; +{ + if (buf->input == NULL) + abort (); + + while (buf->data != NULL && buf->data->size == 0) + { + struct buffer_data *next; + + next = buf->data->next; + buf->data->next = free_buffer_data; + free_buffer_data = buf->data; + buf->data = next; + if (next == NULL) + buf->last = NULL; + } + + if (buf->data == NULL) + { + struct buffer_data *data; + int get, status, nbytes; + + data = get_buffer_data (); + if (data == NULL) + { + (*buf->memory_error) (buf); + return -2; + } + + buf->data = data; + buf->last = data; + data->next = NULL; + data->bufp = data->text; + data->size = 0; + + if (want < BUFFER_DATA_SIZE) + get = want; + else + get = BUFFER_DATA_SIZE; + status = (*buf->input) (buf->closure, data->bufp, get, + BUFFER_DATA_SIZE, &nbytes); + if (status != 0) + return status; + + data->size = nbytes; + } + + *retdata = buf->data->bufp; + if (want < buf->data->size) + { + *got = want; + buf->data->size -= want; + buf->data->bufp += want; + } + else + { + *got = buf->data->size; + buf->data->size = 0; + } + + return 0; +} + +/* + * Copy lines from an input buffer to an output buffer. This copies + * all complete lines (characters up to a newline) from INBUF to + * OUTBUF. Each line in OUTBUF is preceded by the character COMMAND + * and a space. + */ + +void +buf_copy_lines (outbuf, inbuf, command) + struct buffer *outbuf; + struct buffer *inbuf; + int command; +{ + while (1) + { + struct buffer_data *data; + struct buffer_data *nldata; + char *nl; + int len; + + /* See if there is a newline in INBUF. */ + nldata = NULL; + nl = NULL; + for (data = inbuf->data; data != NULL; data = data->next) + { + nl = memchr (data->bufp, '\n', data->size); + if (nl != NULL) + { + nldata = data; + break; + } + } + + if (nldata == NULL) + { + /* There are no more lines in INBUF. */ + return; + } + + /* Put in the command. */ + buf_append_char (outbuf, command); + buf_append_char (outbuf, ' '); + + if (inbuf->data != nldata) + { + /* + * Simply move over all the buffers up to the one containing + * the newline. + */ + for (data = inbuf->data; data->next != nldata; data = data->next) + ; + data->next = NULL; + buf_append_data (outbuf, inbuf->data, data); + inbuf->data = nldata; + } + + /* + * If the newline is at the very end of the buffer, just move + * the buffer onto OUTBUF. Otherwise we must copy the data. + */ + len = nl + 1 - nldata->bufp; + if (len == nldata->size) + { + inbuf->data = nldata->next; + if (inbuf->data == NULL) + inbuf->last = NULL; + + nldata->next = NULL; + buf_append_data (outbuf, nldata, nldata); + } + else + { + buf_output (outbuf, nldata->bufp, len); + nldata->bufp += len; + nldata->size -= len; + } + } +} + +/* + * Copy counted data from one buffer to another. The count is an + * integer, host size, host byte order (it is only used across a + * pipe). If there is enough data, it should be moved over. If there + * is not enough data, it should remain on the original buffer. A + * negative count is a special case. if one is seen, *SPECIAL is set + * to the (negative) count value and no additional data is gathered + * from the buffer; normally *SPECIAL is set to 0. This function + * returns the number of bytes it needs to see in order to actually + * copy something over. + */ + +int +buf_copy_counted (outbuf, inbuf, special) + struct buffer *outbuf; + struct buffer *inbuf; + int *special; +{ + *special = 0; + + while (1) + { + struct buffer_data *data; + int need; + union + { + char intbuf[sizeof (int)]; + int i; + } u; + char *intp; + int count; + struct buffer_data *start; + int startoff; + struct buffer_data *stop; + int stopwant; + + /* See if we have enough bytes to figure out the count. */ + need = sizeof (int); + intp = u.intbuf; + for (data = inbuf->data; data != NULL; data = data->next) + { + if (data->size >= need) + { + memcpy (intp, data->bufp, need); + break; + } + memcpy (intp, data->bufp, data->size); + intp += data->size; + need -= data->size; + } + if (data == NULL) + { + /* We don't have enough bytes to form an integer. */ + return need; + } + + count = u.i; + start = data; + startoff = need; + + if (count < 0) + { + /* A negative COUNT is a special case meaning that we + don't need any further information. */ + stop = start; + stopwant = 0; + } + else + { + /* + * We have an integer in COUNT. We have gotten all the + * data from INBUF in all buffers before START, and we + * have gotten STARTOFF bytes from START. See if we have + * enough bytes remaining in INBUF. + */ + need = count - (start->size - startoff); + if (need <= 0) + { + stop = start; + stopwant = count; + } + else + { + for (data = start->next; data != NULL; data = data->next) + { + if (need <= data->size) + break; + need -= data->size; + } + if (data == NULL) + { + /* We don't have enough bytes. */ + return need; + } + stop = data; + stopwant = need; + } + } + + /* + * We have enough bytes. Free any buffers in INBUF before + * START, and remove STARTOFF bytes from START, so that we can + * forget about STARTOFF. + */ + start->bufp += startoff; + start->size -= startoff; + + if (start->size == 0) + start = start->next; + + if (stop->size == stopwant) + { + stop = stop->next; + stopwant = 0; + } + + while (inbuf->data != start) + { + data = inbuf->data; + inbuf->data = data->next; + data->next = free_buffer_data; + free_buffer_data = data; + } + + /* If COUNT is negative, set *SPECIAL and get out now. */ + if (count < 0) + { + *special = count; + return 0; + } + + /* + * We want to copy over the bytes from START through STOP. We + * only want STOPWANT bytes from STOP. + */ + + if (start != stop) + { + /* Attach the buffers from START through STOP to OUTBUF. */ + for (data = start; data->next != stop; data = data->next) + ; + inbuf->data = stop; + data->next = NULL; + buf_append_data (outbuf, start, data); + } + + if (stopwant > 0) + { + buf_output (outbuf, stop->bufp, stopwant); + stop->bufp += stopwant; + stop->size -= stopwant; + } + } + + /*NOTREACHED*/ +} + +/* Shut down a buffer. This returns 0 on success, or an errno code. */ + +int +buf_shutdown (buf) + struct buffer *buf; +{ + if (buf->shutdown) + return (*buf->shutdown) (buf->closure); + return 0; +} + +/* The simplest type of buffer is one built on top of a stdio FILE. + For simplicity, and because it is all that is required, we do not + implement setting this type of buffer into nonblocking mode. The + closure field is just a FILE *. */ + +static int stdio_buffer_input PROTO((void *, char *, int, int, int *)); +static int stdio_buffer_output PROTO((void *, const char *, int, int *)); +static int stdio_buffer_flush PROTO((void *)); + +/* Initialize a buffer built on a stdio FILE. */ + +struct buffer +*stdio_buffer_initialize (fp, input, memory) + FILE *fp; + int input; + void (*memory) PROTO((struct buffer *)); +{ + return buf_initialize (input ? stdio_buffer_input : NULL, + input ? NULL : stdio_buffer_output, + input ? NULL : stdio_buffer_flush, + (int (*) PROTO((void *, int))) NULL, + (int (*) PROTO((void *))) NULL, + memory, + (void *) fp); +} + +/* The buffer input function for a buffer built on a stdio FILE. */ + +static int +stdio_buffer_input (closure, data, need, size, got) + void *closure; + char *data; + int need; + int size; + int *got; +{ + FILE *fp = (FILE *) closure; + int nbytes; + + /* Since stdio does its own buffering, we don't worry about + getting more bytes than we need. */ + + if (need == 0 || need == 1) + { + int ch; + + ch = getc (fp); + + if (ch == EOF) + { + if (feof (fp)) + return -1; + else if (errno == 0) + return EIO; + else + return errno; + } + + *data = ch; + *got = 1; + return 0; + } + + nbytes = fread (data, 1, need, fp); + + if (nbytes == 0) + { + *got = 0; + if (feof (fp)) + return -1; + else if (errno == 0) + return EIO; + else + return errno; + } + + *got = nbytes; + + return 0; +} + +/* The buffer output function for a buffer built on a stdio FILE. */ + +static int +stdio_buffer_output (closure, data, have, wrote) + void *closure; + const char *data; + int have; + int *wrote; +{ + FILE *fp = (FILE *) closure; + + *wrote = 0; + + while (have > 0) + { + int nbytes; + + nbytes = fwrite (data, 1, have, fp); + + if (nbytes != have) + { + if (errno == 0) + return EIO; + else + return errno; + } + + *wrote += nbytes; + have -= nbytes; + data += nbytes; + } + + return 0; +} + +/* The buffer flush function for a buffer built on a stdio FILE. */ + +static int +stdio_buffer_flush (closure) + void *closure; +{ + FILE *fp = (FILE *) closure; + + if (fflush (fp) != 0) + { + if (errno == 0) + return EIO; + else + return errno; + } + + return 0; +} + +#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */ diff --git a/gnu/usr.bin/cvs/src/buffer.h b/gnu/usr.bin/cvs/src/buffer.h new file mode 100644 index 00000000000..d3d52bdcc47 --- /dev/null +++ b/gnu/usr.bin/cvs/src/buffer.h @@ -0,0 +1,136 @@ +/* Declarations concerning the buffer data structure. */ + +#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) + +/* + * We must read data from a child process and send it across the + * network. We do not want to block on writing to the network, so we + * store the data from the child process in memory. A BUFFER + * structure holds the status of one communication, and uses a linked + * list of buffer_data structures to hold data. + */ + +struct buffer +{ + /* Data. */ + struct buffer_data *data; + + /* Last buffer on data chain. */ + struct buffer_data *last; + + /* Nonzero if the buffer is in nonblocking mode. */ + int nonblocking; + + /* Functions must be provided to transfer data in and out of the + buffer. Either the input or output field must be set, but not + both. */ + + /* Read data into the buffer DATA. There is room for up to SIZE + bytes. At least NEED bytes must be read (NEED may be 0). This + should return 0 on success, or -1 on end of file, or an errno + code. It should set the number of bytes read in *GOT. */ + int (*input) PROTO((void *closure, char *data, int need, int size, + int *got)); + + /* Write data. This should write up to HAVE bytes from DATA. + This should return 0 on success, or an errno code. It should + set the number of bytes written in *WROTE. */ + int (*output) PROTO((void *closure, const char *data, int have, + int *wrote)); + + /* Flush any data which may be buffered up after previous calls to + OUTPUT. This should return 0 on success, or an errno code. */ + int (*flush) PROTO((void *closure)); + + /* Change the blocking mode of the underlying communication + stream. If BLOCK is non-zero, it should be placed into + blocking mode. Otherwise, it should be placed into + non-blocking mode. This should return 0 on success, or an + errno code. */ + int (*block) PROTO ((void *closure, int block)); + + /* Shut down the communication stream. This does not mean that it + should be closed. It merely means that no more data will be + read or written, and that any final processing that is + appropriate should be done at this point. This may be NULL. + It should return 0 on success, or an errno code. This entry + point exists for the compression code. */ + int (*shutdown) PROTO((void *closure)); + + /* This field is passed to the INPUT, OUTPUT, and BLOCK functions. */ + void *closure; + + /* Function to call if we can't allocate memory. */ + void (*memory_error) PROTO((struct buffer *)); +}; + +/* Data is stored in lists of these structures. */ + +struct buffer_data +{ + /* Next buffer in linked list. */ + struct buffer_data *next; + + /* + * A pointer into the data area pointed to by the text field. This + * is where to find data that has not yet been written out. + */ + char *bufp; + + /* The number of data bytes found at BUFP. */ + int size; + + /* + * Actual buffer. This never changes after the structure is + * allocated. The buffer is BUFFER_DATA_SIZE bytes. + */ + char *text; +}; + +/* The size we allocate for each buffer_data structure. */ +#define BUFFER_DATA_SIZE (4096) + +extern struct buffer *buf_initialize PROTO((int (*) (void *, char *, int, + int, int *), + int (*) (void *, const char *, + int, int *), + int (*) (void *), + int (*) (void *, int), + int (*) (void *), + void (*) (struct buffer *), + void *)); +extern struct buffer *buf_nonio_initialize PROTO((void (*) (struct buffer *))); +extern struct buffer *stdio_buffer_initialize + PROTO((FILE *, int, void (*) (struct buffer *))); +extern struct buffer *compress_buffer_initialize + PROTO((struct buffer *, int, int, void (*) (struct buffer *))); +extern int buf_empty_p PROTO((struct buffer *)); +extern void buf_output PROTO((struct buffer *, const char *, int)); +extern void buf_output0 PROTO((struct buffer *, const char *)); +extern void buf_append_char PROTO((struct buffer *, int)); +extern int buf_send_output PROTO((struct buffer *)); +extern int buf_flush PROTO((struct buffer *, int)); +extern int set_nonblock PROTO((struct buffer *)); +extern int set_block PROTO((struct buffer *)); +extern int buf_send_counted PROTO((struct buffer *)); +extern int buf_send_special_count PROTO((struct buffer *, int)); +extern void buf_append_data PROTO((struct buffer *, + struct buffer_data *, + struct buffer_data *)); +extern int buf_read_file PROTO((FILE *, long, struct buffer_data **, + struct buffer_data **)); +extern int buf_read_file_to_eof PROTO((FILE *, struct buffer_data **, + struct buffer_data **)); +extern int buf_input_data PROTO((struct buffer *, int *)); +extern int buf_read_line PROTO((struct buffer *, char **, int *)); +extern int buf_read_data PROTO((struct buffer *, int, char **, int *)); +extern void buf_copy_lines PROTO((struct buffer *, struct buffer *, int)); +extern int buf_copy_counted PROTO((struct buffer *, struct buffer *, int *)); +extern int buf_chain_length PROTO((struct buffer_data *)); +extern int buf_shutdown PROTO((struct buffer *)); + +#ifdef SERVER_FLOWCONTROL +extern int buf_count_mem PROTO((struct buffer *)); +#endif /* SERVER_FLOWCONTROL */ + +#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */ diff --git a/gnu/usr.bin/cvs/src/build_src.com b/gnu/usr.bin/cvs/src/build_src.com new file mode 100644 index 00000000000..784adb5e415 --- /dev/null +++ b/gnu/usr.bin/cvs/src/build_src.com @@ -0,0 +1,68 @@ +$ CC :== CC/NOOPT/DEB/STANDARD=VAXC/DEFINE=HAVE_CONFIG_H- +/INCLUDE_DIR=([-],[-.VMS],[-.LIB])/PREFIX=ALL +$ CC add.c +$ CC admin.c +$ CC buffer.c +$ CC checkin.c +$ CC checkout.c +$ CC classify.c +$ CC client.c +$ CC commit.c +$ CC create_adm.c +$ CC cvsrc.c +$ CC diff.c +$ CC edit.c +$ CC entries.c +$ CC error.c +$ CC expand_path.c +$ CC fileattr.c +$ CC find_names.c +$ CC hash.c +$ CC history.c +$ CC ignore.c +$ CC import.c +$ CC lock.c +$ CC log.c +$ CC login.c +$ CC logmsg.c +$ CC main.c +$ CC mkmodules.c +$ CC modules.c +$ CC myndbm.c +$ CC no_diff.c +$ CC parseinfo.c +$ CC patch.c +$ CC rcs.c +$ CC rcscmds.c +$ CC recurse.c +$ CC release.c +$ CC remove.c +$ CC repos.c +$ CC root.c +$ CC rtag.c +$ CC run.c +$ CC scramble.c +$ CC server.c +$ CC status.c +$ CC subr.c +$ CC tag.c +$ CC update.c +$ CC version.c +$ CC vers_ts.c +$ CC watch.c +$ CC wrapper.c +$ CC/INCLUDE_DIR=([-],[-.VMS],[-.LIB],[-.zlib]) zlib.c +$ LIBRARY/CREATE cvslib.olb add.obj,admin.obj,buffer.obj,checkin.obj,- +checkout.obj,- +classify.obj,client.obj,commit.obj,create_adm.obj,cvsrc.obj,- +diff.obj,edit.obj,entries.obj,error.obj,expand_path.obj,fileattr.obj,- +find_names.obj,hash.obj,history.obj,ignore.obj,import.obj,- +lock.obj,log.obj,login.obj,logmsg.obj,mkmodules.obj,modules.obj,myndbm.obj,- +no_diff.obj,- +parseinfo.obj,patch.obj,rcs.obj,rcscmds.obj,recurse.obj,release.obj,- +remove.obj,repos.obj,root.obj,rtag.obj,run.obj,scramble.obj,server.obj,- +status.obj,- +subr.obj,tag.obj,update.obj,version.obj,vers_ts.obj,watch.obj,wrapper.obj,- +zlib.obj +$ link/nodeb/exe=cvs.exe main.obj,cvslib.olb/lib,[-.lib]gnulib.olb/lib,- +[-.vms]openvmslib.olb/lib,[-.zlib]zlib.olb/lib diff --git a/gnu/usr.bin/cvs/src/checkin.c b/gnu/usr.bin/cvs/src/checkin.c index e1ce9cbcbde..50e309e273a 100644 --- a/gnu/usr.bin/cvs/src/checkin.c +++ b/gnu/usr.bin/cvs/src/checkin.c @@ -20,34 +20,22 @@ #include "edit.h" int -Checkin (type, file, update_dir, repository, - rcs, rev, tag, options, message, entries) +Checkin (type, finfo, rcs, rev, tag, options, message) int type; - char *file; - char *update_dir; - char *repository; + struct file_info *finfo; char *rcs; char *rev; char *tag; char *options; char *message; - List *entries; { char fname[PATH_MAX]; Vers_TS *vers; int set_time; - char *fullname; - char *tocvsPath = NULL; - fullname = xmalloc (strlen (update_dir) + strlen (file) + 10); - if (update_dir[0] == '\0') - strcpy (fullname, file); - else - sprintf (fullname, "%s/%s", update_dir, file); - - (void) printf ("Checking in %s;\n", fullname); - (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file); + (void) printf ("Checking in %s;\n", finfo->fullname); + (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file); /* * Move the user file to a backup file, so as to preserve its @@ -55,25 +43,25 @@ Checkin (type, file, update_dir, repository, * for the checkin and checkout. */ - tocvsPath = wrap_tocvs_process_file (fullname); + tocvsPath = wrap_tocvs_process_file (finfo->fullname); if (!noexec) { if (tocvsPath) { copy_file (tocvsPath, fname); - if (unlink_file_dir (file) < 0) + if (unlink_file_dir (finfo->file) < 0) if (! existence_error (errno)) - error (1, errno, "cannot remove %s", file); - copy_file (tocvsPath, file); + error (1, errno, "cannot remove %s", finfo->fullname); + copy_file (tocvsPath, finfo->file); } else { - copy_file (file, fname); + copy_file (finfo->file, fname); } } - switch (RCS_checkin (rcs, NULL, message, rev, 0, 0)) + switch (RCS_checkin (rcs, NULL, message, rev, 0)) { case 0: /* everything normal */ @@ -89,13 +77,20 @@ Checkin (type, file, update_dir, repository, if (strcmp (options, "-V4") == 0) /* upgrade to V5 now */ options[0] = '\0'; + /* Reparse the RCS file, so that we can safely call + RCS_checkout. FIXME: We could probably calculate + all the changes. */ + freercsnode (&finfo->rcs); + finfo->rcs = RCS_parse (finfo->file, finfo->repository); + /* FIXME: should be checking for errors. */ - (void) RCS_checkout (rcs, "", rev, options, RUN_TTY, 0, 0); + (void) RCS_checkout (finfo->rcs, finfo->file, rev, + (char *) NULL, options, RUN_TTY); - xchmod (file, 1); - if (xcmp (file, fname) == 0) + xchmod (finfo->file, 1); + if (xcmp (finfo->file, fname) == 0) { - rename_file (fname, file); + rename_file (fname, finfo->file); /* the time was correct, so leave it alone */ set_time = 0; } @@ -107,24 +102,23 @@ Checkin (type, file, update_dir, repository, set_time = 1; } - wrap_fromcvs_process_file (file); + wrap_fromcvs_process_file (finfo->file); /* * If we want read-only files, muck the permissions here, before * getting the file time-stamp. */ - if (cvswrite == FALSE || fileattr_get (file, "_watched")) - xchmod (file, 0); + if (cvswrite == FALSE || fileattr_get (finfo->file, "_watched")) + xchmod (finfo->file, 0); - /* re-register with the new data */ - vers = Version_TS (repository, (char *) NULL, tag, (char *) NULL, - file, 1, set_time, entries, (RCSNode *) NULL); + /* Re-register with the new data. */ + vers = Version_TS (finfo, NULL, tag, NULL, 1, set_time); if (strcmp (vers->options, "-V4") == 0) vers->options[0] = '\0'; - Register (entries, file, vers->vn_rcs, vers->ts_user, + Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_user, vers->options, vers->tag, vers->date, (char *) 0); - history_write (type, (char *) 0, vers->vn_rcs, file, repository); - freevers_ts (&vers); + history_write (type, NULL, vers->vn_rcs, + finfo->file, finfo->repository); if (tocvsPath) if (unlink_file_dir (tocvsPath) < 0) @@ -139,7 +133,7 @@ Checkin (type, file, update_dir, repository, if (!noexec) error (1, errno, "could not check in %s -- fork failed", - fullname); + finfo->fullname); return (1); default: /* ci failed */ @@ -154,8 +148,8 @@ Checkin (type, file, update_dir, repository, if (!noexec) { - rename_file (fname, file); - error (0, 0, "could not check in %s", fullname); + rename_file (fname, finfo->file); + error (0, 0, "could not check in %s", finfo->fullname); } return (1); } @@ -167,7 +161,7 @@ Checkin (type, file, update_dir, repository, */ if (rev) { - (void) RCS_unlock (rcs, NULL, 1); + (void) RCS_unlock (finfo->rcs, NULL, 1); } #ifdef SERVER_SUPPORT @@ -175,14 +169,15 @@ Checkin (type, file, update_dir, repository, { if (set_time) /* Need to update the checked out file on the client side. */ - server_updated (file, update_dir, repository, SERVER_UPDATED, + server_updated (finfo, vers, SERVER_UPDATED, NULL, NULL); else - server_checked_in (file, update_dir, repository); + server_checked_in (finfo->file, finfo->update_dir, finfo->repository); } else #endif - mark_up_to_date (file); + mark_up_to_date (finfo->file); + freevers_ts (&vers); return (0); } diff --git a/gnu/usr.bin/cvs/src/classify.c b/gnu/usr.bin/cvs/src/classify.c index 924314b2099..c591b1e7867 100644 --- a/gnu/usr.bin/cvs/src/classify.c +++ b/gnu/usr.bin/cvs/src/classify.c @@ -21,34 +21,23 @@ static void sticky_ck PROTO((char *file, int aflag, Vers_TS * vers, List * entri * Classify the state of a file */ Ctype -Classify_File (file, tag, date, options, force_tag_match, aflag, repository, - entries, rcsnode, versp, update_dir, pipeout) - char *file; +Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp, + pipeout) + struct file_info *finfo; char *tag; char *date; char *options; int force_tag_match; int aflag; - char *repository; - List *entries; - RCSNode *rcsnode; Vers_TS **versp; - char *update_dir; int pipeout; { Vers_TS *vers; Ctype ret; - char *fullname; - - fullname = xmalloc (strlen (update_dir) + strlen (file) + 10); - if (update_dir[0] == '\0') - strcpy (fullname, file); - else - sprintf (fullname, "%s/%s", update_dir, file); /* get all kinds of good data about the file */ - vers = Version_TS (repository, options, tag, date, file, - force_tag_match, 0, entries, rcsnode); + vers = Version_TS (finfo, options, tag, date, + force_tag_match, 0); if (vers->vn_user == NULL) { @@ -61,7 +50,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository, /* there is no user file */ if (!force_tag_match || !(vers->tag || vers->date)) if (!really_quiet) - error (0, 0, "nothing known about %s", fullname); + error (0, 0, "nothing known about %s", finfo->fullname); ret = T_UNKNOWN; } else @@ -70,24 +59,18 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository, if (!force_tag_match || !(vers->tag || vers->date)) if (!really_quiet) error (0, 0, "use `cvs add' to create an entry for %s", - fullname); + finfo->fullname); ret = T_UNKNOWN; } } else if (RCS_isdead (vers->srcfile, vers->vn_rcs)) { if (vers->ts_user == NULL) - /* - * Logically seems to me this should be T_UPTODATE. - * But the joining code in update.c seems to expect - * T_CHECKOUT, and that is what has traditionally been - * returned for this case. - */ - ret = T_CHECKOUT; + ret = T_UPTODATE; else { error (0, 0, "use `cvs add' to create an entry for %s", - fullname); + finfo->fullname); ret = T_UNKNOWN; } } @@ -115,13 +98,12 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository, * conflict list, only if it is indeed different from what we * plan to extract */ - else if (No_Difference (file, vers, entries, - repository, update_dir)) + else if (No_Difference (finfo, vers)) { /* the files were different so it is a conflict */ if (!really_quiet) error (0, 0, "move away %s; it is in the way", - fullname); + finfo->fullname); ret = T_CONFLICT; } else @@ -141,7 +123,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository, * entry */ if (!really_quiet) - error (0, 0, "warning: new-born %s has disappeared", fullname); + error (0, 0, "warning: new-born %s has disappeared", finfo->fullname); ret = T_REMOVE_ENTRY; } else @@ -166,7 +148,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository, error (0, 0, "\ conflict: %s has been added, but already exists", - fullname); + finfo->fullname); } else { @@ -178,7 +160,7 @@ conflict: %s has been added, but already exists", error (0, 0, "\ conflict: %s created independently by second party", - fullname); + finfo->fullname); } ret = T_CONFLICT; } @@ -196,7 +178,8 @@ conflict: %s created independently by second party", (void) sprintf (tmp, "-%s", vers->vn_rcs ? vers->vn_rcs : ""); - if (vers->vn_rcs == NULL) + if (vers->vn_rcs == NULL + || RCS_isdead (vers->srcfile, vers->vn_rcs)) { /* @@ -222,7 +205,7 @@ conflict: %s created independently by second party", if (!really_quiet) error (0, 0, "conflict: removed %s was modified by second party", - fullname); + finfo->fullname); ret = T_CONFLICT; } } @@ -231,7 +214,7 @@ conflict: %s created independently by second party", /* The user file shouldn't be there */ if (!really_quiet) error (0, 0, "%s should be removed and is still there", - fullname); + finfo->fullname); ret = T_REMOVED; } } @@ -247,7 +230,7 @@ conflict: %s created independently by second party", /* There is no user file, so just remove the entry */ if (!really_quiet) error (0, 0, "warning: %s is not (any longer) pertinent", - fullname); + finfo->fullname); ret = T_REMOVE_ENTRY; } else if (strcmp (vers->ts_user, vers->ts_rcs) == 0) @@ -259,7 +242,7 @@ conflict: %s created independently by second party", */ if (!really_quiet) error (0, 0, "%s is no longer in the repository", - fullname); + finfo->fullname); ret = T_REMOVE_ENTRY; } else @@ -268,14 +251,13 @@ conflict: %s created independently by second party", * The user file has been modified and since it is no longer * in the repository, a conflict is raised */ - if (No_Difference (file, vers, entries, - repository, update_dir)) + if (No_Difference (finfo, vers)) { /* they are different -> conflict */ if (!really_quiet) error (0, 0, "conflict: %s is modified but no longer in the repository", - fullname); + finfo->fullname); ret = T_CONFLICT; } else @@ -284,7 +266,7 @@ conflict: %s created independently by second party", if (!really_quiet) error (0, 0, "warning: %s is not (any longer) pertinent", - fullname); + finfo->fullname); ret = T_REMOVE_ENTRY; } } @@ -302,7 +284,7 @@ conflict: %s created independently by second party", */ if (strcmp (command_name, "update") == 0) if (!really_quiet) - error (0, 0, "warning: %s was lost", fullname); + error (0, 0, "warning: %s was lost", finfo->fullname); ret = T_CHECKOUT; } else if (strcmp (vers->ts_user, vers->ts_rcs) == 0) @@ -320,10 +302,10 @@ conflict: %s created independently by second party", else { #ifdef SERVER_SUPPORT - sticky_ck (file, aflag, vers, entries, - repository, update_dir); + sticky_ck (finfo->file, aflag, vers, finfo->entries, + finfo->repository, finfo->update_dir); #else - sticky_ck (file, aflag, vers, entries); + sticky_ck (finfo->file, aflag, vers, finfo->entries); #endif ret = T_UPTODATE; } @@ -335,8 +317,7 @@ conflict: %s created independently by second party", * The user file appears to have been modified, but we call * No_Difference to verify that it really has been modified */ - if (No_Difference (file, vers, entries, - repository, update_dir)) + if (No_Difference (finfo, vers)) { /* @@ -352,10 +333,10 @@ conflict: %s created independently by second party", #else ret = T_MODIFIED; #ifdef SERVER_SUPPORT - sticky_ck (file, aflag, vers, entries, - repository, update_dir); + sticky_ck (finfo->file, aflag, vers, finfo->entries, + finfo->repository, finfo->update_dir); #else - sticky_ck (file, aflag, vers, entries); + sticky_ck (finfo->file, aflag, vers, finfo->entries); #endif /* SERVER_SUPPORT */ #endif } @@ -390,7 +371,7 @@ conflict: %s created independently by second party", if (strcmp (command_name, "update") == 0) if (!really_quiet) - error (0, 0, "warning: %s was lost", fullname); + error (0, 0, "warning: %s was lost", finfo->fullname); ret = T_CHECKOUT; } else if (strcmp (vers->ts_user, vers->ts_rcs) == 0) @@ -413,8 +394,7 @@ conflict: %s created independently by second party", } else { - if (No_Difference (file, vers, entries, - repository, update_dir)) + if (No_Difference (finfo, vers)) /* really modified, needs to merge */ ret = T_NEEDS_MERGE; #ifdef SERVER_SUPPORT @@ -442,8 +422,6 @@ conflict: %s created independently by second party", else freevers_ts (&vers); - free (fullname); - /* return the status of the file */ return (ret); } diff --git a/gnu/usr.bin/cvs/src/client.h b/gnu/usr.bin/cvs/src/client.h index b238c322b09..d68412628f7 100644 --- a/gnu/usr.bin/cvs/src/client.h +++ b/gnu/usr.bin/cvs/src/client.h @@ -5,45 +5,27 @@ extern char *mode_to_string PROTO((mode_t)); extern int change_mode PROTO((char *, char *)); extern int gzip_level; +extern int file_gzip_level; extern int filter_through_gzip PROTO((int, int, int, pid_t *)); extern int filter_through_gunzip PROTO((int, int, pid_t *)); -#ifdef CLIENT_SUPPORT -/* - * Functions to perform CVS commands via the protocol. argc and argv - * are the arguments and the return value is the exit status (zero success - * nonzero failure). - */ -extern int client_commit PROTO((int argc, char **argv)); -extern int client_update PROTO((int argc, char **argv)); -extern int client_checkout PROTO((int argc, char **argv)); -extern int client_diff PROTO((int argc, char **argv)); -extern int client_log PROTO((int argc, char **argv)); -extern int client_add PROTO((int argc, char **argv)); -extern int client_remove PROTO((int argc, char **argv)); -extern int client_status PROTO((int argc, char **argv)); -extern int client_rdiff PROTO((int argc, char **argv)); -extern int client_tag PROTO((int argc, char **argv)); -extern int client_rtag PROTO((int argc, char **argv)); -extern int client_import PROTO((int argc, char **argv)); -extern int client_admin PROTO((int argc, char **argv)); -extern int client_export PROTO((int argc, char **argv)); -extern int client_history PROTO((int argc, char **argv)); -extern int client_release PROTO((int argc, char **argv)); -extern int client_watch PROTO((int argc, char **argv)); -extern int client_watchers PROTO((int argc, char **argv)); -extern int client_editors PROTO((int argc, char **argv)); -extern int client_edit PROTO((int argc, char **argv)); -extern int client_unedit PROTO((int argc, char **argv)); -extern int client_init PROTO ((int argc, char **argv)); -extern int client_annotate PROTO ((int argc, char **argv)); +#if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) -/* - * Flag variable for seeing whether common code is running as a client - * or to do a local operation. - */ -extern int client_active; +extern int cvsencrypt; + +#ifdef ENCRYPTION +#ifdef HAVE_KERBEROS +/* We can't declare the arguments without including krb.h, and I don't + want to do that in every file. */ +extern struct buffer *krb_encrypt_buffer_initialize (); + +#endif /* HAVE_KERBEROS */ +#endif /* ENCRYPTION */ + +#endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */ + +#ifdef CLIENT_SUPPORT /* * Flag variable for seeing whether the server has been started yet. * As of this writing, only edit.c:notify_check() uses it. @@ -62,7 +44,11 @@ int connect_to_pserver PROTO((int *tofdp, int* fromfdp, int verify_only)); #endif /* AUTH_CLIENT_SUPPORT */ #ifdef AUTH_SERVER_SUPPORT -extern void authenticate_connection PROTO ((void)); +extern void pserver_authenticate_connection PROTO ((void)); +#endif + +#if defined (SERVER_SUPPORT) && defined (HAVE_KERBEROS) +extern void kserver_authenticate_connection PROTO ((void)); #endif /* Talking to the server. */ @@ -174,7 +160,7 @@ extern struct response responses[]; extern void client_senddate PROTO((const char *date)); extern void client_expand_modules PROTO((int argc, char **argv, int local)); -extern void client_send_expansions PROTO((int local)); +extern void client_send_expansions PROTO((int local, char *where)); extern void client_nonexpanded_setup PROTO((void)); extern void send_init_command PROTO ((void)); diff --git a/gnu/usr.bin/cvs/src/create_adm.c b/gnu/usr.bin/cvs/src/create_adm.c index fd7fd4d7c0b..01d38f90bf8 100644 --- a/gnu/usr.bin/cvs/src/create_adm.c +++ b/gnu/usr.bin/cvs/src/create_adm.c @@ -53,12 +53,12 @@ Create_Admin (dir, update_dir, repository, tag, date) /* record the current cvs root for later use */ - Create_Root (dir, CVSroot); + Create_Root (dir, CVSroot_original); if (dir != NULL) (void) sprintf (tmp, "%s/%s", dir, CVSADM_REP); else (void) strcpy (tmp, CVSADM_REP); - fout = fopen (tmp, "w+"); + fout = CVS_FOPEN (tmp, "w+"); if (fout == NULL) { if (update_dir[0] == '\0') @@ -74,11 +74,11 @@ Create_Admin (dir, update_dir, repository, tag, date) * If the Repository file is to hold a relative path, try to strip off * the leading CVSroot argument. */ - if (CVSroot != NULL) + if (CVSroot_directory != NULL) { char path[PATH_MAX]; - (void) sprintf (path, "%s/", CVSroot); + (void) sprintf (path, "%s/", CVSroot_directory); if (strncmp (repository, path, strlen (path)) == 0) cp = repository + strlen (path); } @@ -104,7 +104,7 @@ Create_Admin (dir, update_dir, repository, tag, date) (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENT); else (void) strcpy (tmp, CVSADM_ENT); - fout = fopen (tmp, "w+"); + fout = CVS_FOPEN (tmp, "w+"); if (fout == NULL) { if (update_dir[0] == '\0') diff --git a/gnu/usr.bin/cvs/src/error.c b/gnu/usr.bin/cvs/src/error.c index 8a10cc7c0db..48452d71fdd 100644 --- a/gnu/usr.bin/cvs/src/error.c +++ b/gnu/usr.bin/cvs/src/error.c @@ -61,7 +61,9 @@ void exit (); #endif /* __STDC__ */ #endif /* STDC_HEADERS */ +#ifndef strerror extern char *strerror (); +#endif extern int vasprintf (); @@ -95,19 +97,9 @@ error (status, errnum, message, va_alist) va_dcl #endif { - FILE *out = stderr; -#ifdef HAVE_VPRINTF - va_list args; -#endif - - if (error_use_protocol) - { - out = stdout; - printf ("E "); - } - #ifdef HAVE_VPRINTF { + va_list args; char *mess = NULL; char *entire; size_t len; @@ -157,10 +149,7 @@ error (status, errnum, message, va_alist) free (mess); } } - if (error_use_protocol) - fputs (entire ? entire : "out of memory", out); - else - cvs_outerr (entire ? entire : "out of memory", 0); + cvs_outerr (entire ? entire : "out of memory", 0); if (entire != NULL) free (entire); } @@ -169,38 +158,49 @@ error (status, errnum, message, va_alist) /* I think that all relevant systems have vprintf these days. But just in case, I'm leaving this code here. */ - if (command_name && *command_name) { - if (status) - fprintf (out, "%s [%s aborted]: ", program_name, command_name); + FILE *out = stderr; + + if (error_use_protocol) + { + out = stdout; + printf ("E "); + } + + if (command_name && *command_name) + { + if (status) + fprintf (out, "%s [%s aborted]: ", program_name, command_name); + else + fprintf (out, "%s %s: ", program_name, command_name); + } else - fprintf (out, "%s %s: ", program_name, command_name); - } - else - fprintf (out, "%s: ", program_name); + fprintf (out, "%s: ", program_name); #ifdef HAVE_VPRINTF - VA_START (args, message); - vfprintf (out, message, args); - va_end (args); + VA_START (args, message); + vfprintf (out, message, args); + va_end (args); #else #ifdef HAVE_DOPRNT - _doprnt (message, &args, out); + _doprnt (message, &args, out); #else - fprintf (out, message, a1, a2, a3, a4, a5, a6, a7, a8); + fprintf (out, message, a1, a2, a3, a4, a5, a6, a7, a8); #endif #endif - if (errnum) - fprintf (out, ": %s", strerror (errnum)); - putc ('\n', out); + if (errnum) + fprintf (out, ": %s", strerror (errnum)); + putc ('\n', out); -#endif /* No HAVE_VPRINTF */ + /* In the error_use_protocol case, this probably does + something useful. In most other cases, I suspect it is a + noop (either stderr is line buffered or we haven't written + anything to stderr) or unnecessary (if stderr is not line + buffered, maybe there is a reason....). */ + fflush (out); + } - /* In the error_use_protocol case, this probably does something useful. - In most other cases, I suspect it is a noop (either stderr is line - buffered or we haven't written anything to stderr) or unnecessary - (if stderr is not line buffered, maybe there is a reason....). */ - fflush (out); +#endif /* No HAVE_VPRINTF */ if (status) { @@ -216,7 +216,7 @@ error (status, errnum, message, va_alist) Exit with status EXIT_FAILURE if STATUS is nonzero. */ /* VARARGS */ void -#if defined (HAVE_VPRINTF) && __STDC__ +#if defined (HAVE_VPRINTF) && ((__STDC__ - 0) > 0) 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/expand_path.c b/gnu/usr.bin/cvs/src/expand_path.c index 98980510e44..ab093512955 100644 --- a/gnu/usr.bin/cvs/src/expand_path.c +++ b/gnu/usr.bin/cvs/src/expand_path.c @@ -81,10 +81,12 @@ variable_set (nameval) } /* This routine will expand the pathname to account for ~ and $ - characters as described above. If an error occurs, an error - message is printed via error() and NULL is returned. FILE and - LINE are the filename and linenumber to include in the error - message. */ + characters as described above. Returns a pointer to a newly + malloc'd string. If an error occurs, an error message is printed + via error() and NULL is returned. FILE and LINE are the filename + and linenumber to include in the error message. FILE must point + to something; LINE can be zero to indicate the line number is not + known. */ char * expand_path (name, file, line) char *name; @@ -181,7 +183,7 @@ expand_variable (name, file, line) int line; { if (strcmp (name, CVSROOT_ENV) == 0) - return CVSroot; + return CVSroot_original; else if (strcmp (name, RCSBIN_ENV) == 0) return Rcsbin; else if (strcmp (name, EDITOR1_ENV) == 0) @@ -231,10 +233,10 @@ expand_variable (name, file, line) that various crazy syntaxes might be invented for inserting information about revisions, branches, etc. */ if (line != 0) - error (0, 0, "%s:%d: unrecognized varaible syntax %s", + error (0, 0, "%s:%d: unrecognized variable syntax %s", file, line, name); else - error (0, 0, "%s: unrecognized varaible syntax %s", + error (0, 0, "%s: unrecognized variable syntax %s", file, name); return NULL; } diff --git a/gnu/usr.bin/cvs/src/fileattr.h b/gnu/usr.bin/cvs/src/fileattr.h index c24c0359088..27cc30df285 100644 --- a/gnu/usr.bin/cvs/src/fileattr.h +++ b/gnu/usr.bin/cvs/src/fileattr.h @@ -66,11 +66,12 @@ extern void fileattr_startdir PROTO ((char *repos)); by '\0' or ';'. Return NULL if said file lacks said attribute. If FILENAME is NULL, return default attributes (attributes for files created in the future). */ -extern char *fileattr_get PROTO ((char *filename, char *attrname)); +extern char *fileattr_get PROTO ((const char *filename, const char *attrname)); /* Like fileattr_get, but return a pointer to a newly malloc'd string terminated by '\0' (or NULL if said file lacks said attribute). */ -extern char *fileattr_get0 PROTO ((char *filename, char *attrname)); +extern char *fileattr_get0 PROTO ((const char *filename, + const char *attrname)); /* This is just a string manipulation function; it does not manipulate file attributes as such. @@ -100,20 +101,20 @@ extern char *fileattr_get0 PROTO ((char *filename, char *attrname)); => "abc=v1;def=val;ghi=v3" */ -extern char *fileattr_modify PROTO ((char *list, char *attrname, - char *attrval, int namevalsep, +extern char *fileattr_modify PROTO ((char *list, const char *attrname, + const char *attrval, int namevalsep, int entsep)); /* Set attribute ATTRNAME for file FILENAME to ATTRVAL. If ATTRVAL is NULL, the attribute is removed. Changes are not written to disk until the next call to fileattr_write. If FILENAME is NULL, set attributes for files created in the future. If ATTRVAL is NULL, remove that attribute. */ -extern void fileattr_set PROTO ((char *filename, char *attrname, - char *attrval)); +extern void fileattr_set PROTO ((const char *filename, const char *attrname, + const char *attrval)); /* Set the attributes for file FILENAME in whatever manner is appropriate for a newly created file. */ -extern void fileattr_newfile PROTO ((char *filename)); +extern void fileattr_newfile PROTO ((const char *filename)); /* Write out all modified attributes. */ extern void fileattr_write PROTO ((void)); diff --git a/gnu/usr.bin/cvs/src/find_names.c b/gnu/usr.bin/cvs/src/find_names.c index 48854377a75..9143a6cd08d 100644 --- a/gnu/usr.bin/cvs/src/find_names.c +++ b/gnu/usr.bin/cvs/src/find_names.c @@ -18,8 +18,11 @@ #include "cvs.h" -static int find_dirs PROTO((char *dir, List * list, int checkadm)); +static int find_dirs PROTO((char *dir, List * list, int checkadm, + List *entries)); static int find_rcs PROTO((char *dir, List * list)); +static int add_subdir_proc PROTO((Node *, void *)); +static int register_subdir_proc PROTO((Node *, void *)); static List *filelist; @@ -32,8 +35,13 @@ add_entries_proc (node, closure) Node *node; void *closure; { + Entnode *entnode; Node *fnode; + entnode = (Entnode *) node->data; + if (entnode->type != ENT_FILE) + return (0); + fnode = getnode (); fnode->type = FILES; fnode->key = xstrdup (node->key); @@ -106,12 +114,55 @@ Find_Names (repository, which, aflag, optentries) } /* + * Add an entry from the subdirs list to the directories list. This + * is called via walklist. + */ + +static int +add_subdir_proc (p, closure) + Node *p; + void *closure; +{ + List *dirlist = (List *) closure; + Entnode *entnode; + Node *dnode; + + entnode = (Entnode *) p->data; + if (entnode->type != ENT_SUBDIR) + return 0; + + dnode = getnode (); + dnode->type = DIRS; + dnode->key = xstrdup (entnode->user); + if (addnode (dirlist, dnode) != 0) + freenode (dnode); + return 0; +} + +/* + * Register a subdirectory. This is called via walklist. + */ + +/*ARGSUSED*/ +static int +register_subdir_proc (p, closure) + Node *p; + void *closure; +{ + List *entries = (List *) closure; + + Subdir_Register (entries, (char *) NULL, p->key); + return 0; +} + +/* * create a list of directories to traverse from the current directory */ List * -Find_Directories (repository, which) +Find_Directories (repository, which, entries) char *repository; int which; + List *entries; { List *dirlist; @@ -121,16 +172,53 @@ Find_Directories (repository, which) /* find the local ones */ if (which & W_LOCAL) { - /* look only for CVS controlled sub-directories */ - if (find_dirs (".", dirlist, 1) != 0) - error (1, errno, "cannot open current directory"); + List *tmpentries; + struct stickydirtag *sdtp; + + /* Look through the Entries file. */ + + if (entries != NULL) + tmpentries = entries; + else if (isfile (CVSADM_ENT)) + tmpentries = Entries_Open (0); + else + tmpentries = NULL; + + if (tmpentries != NULL) + sdtp = (struct stickydirtag *) tmpentries->list->data; + + /* If we do have an entries list, then if sdtp is NULL, or if + sdtp->subdirs is nonzero, all subdirectory information is + recorded in the entries list. */ + if (tmpentries != NULL && (sdtp == NULL || sdtp->subdirs)) + walklist (tmpentries, add_subdir_proc, (void *) dirlist); + else + { + /* This is an old working directory, in which subdirectory + information is not recorded in the Entries file. Find + the subdirectories the hard way, and, if possible, add + it to the Entries file for next time. */ + if (find_dirs (".", dirlist, 1, tmpentries) != 0) + error (1, errno, "cannot open current directory"); + if (tmpentries != NULL) + { + if (! list_isempty (dirlist)) + walklist (dirlist, register_subdir_proc, + (void *) tmpentries); + else + Subdirs_Known (tmpentries); + } + } + + if (entries == NULL && tmpentries != NULL) + Entries_Close (tmpentries); } /* look for sub-dirs in the repository */ if ((which & W_REPOS) && repository) { /* search the repository */ - if (find_dirs (repository, dirlist, 0) != 0) + if (find_dirs (repository, dirlist, 0, entries) != 0) error (1, errno, "cannot open directory %s", repository); #ifdef ATTIC_DIR_SUPPORT /* XXX - FIXME */ @@ -140,7 +228,7 @@ Find_Directories (repository, which) char dir[PATH_MAX]; (void) sprintf (dir, "%s/%s", repository, CVSATTIC); - (void) find_dirs (dir, dirlist, 0); + (void) find_dirs (dir, dirlist, 0, entries); } #endif } @@ -165,7 +253,7 @@ find_rcs (dir, list) DIR *dirp; /* set up to read the dir */ - if ((dirp = opendir (dir)) == NULL) + if ((dirp = CVS_OPENDIR (dir)) == NULL) return (1); /* read the dir, grabbing the ,v files */ @@ -189,15 +277,18 @@ find_rcs (dir, list) } /* - * Finds all the subdirectories of the argument dir and adds them to the - * specified list. Sub-directories without a CVS administration directory - * are optionally ignored Returns 0 for success or 1 on error. + * Finds all the subdirectories of the argument dir and adds them to + * the specified list. Sub-directories without a CVS administration + * directory are optionally ignored. If ENTRIES is not NULL, all + * files on the list are ignored. Returns 0 for success or 1 on + * error. */ static int -find_dirs (dir, list, checkadm) +find_dirs (dir, list, checkadm, entries) char *dir; List *list; int checkadm; + List *entries; { Node *p; char tmp[PATH_MAX]; @@ -205,7 +296,7 @@ find_dirs (dir, list, checkadm) DIR *dirp; /* set up to read the dir */ - if ((dirp = opendir (dir)) == NULL) + if ((dirp = CVS_OPENDIR (dir)) == NULL) return (1); /* read the dir, grabbing sub-dirs */ @@ -218,6 +309,12 @@ find_dirs (dir, list, checkadm) strcmp (dp->d_name, CVSREP) == 0) continue; + /* findnode() is going to be significantly faster than stat() + because it involves no system calls. That is why we bother + with the entries argument, and why we check this first. */ + if (entries != NULL && findnode (entries, dp->d_name) != NULL) + continue; + #ifdef DT_DIR if (dp->d_type != DT_DIR) { diff --git a/gnu/usr.bin/cvs/src/hash.c b/gnu/usr.bin/cvs/src/hash.c index 2197db07f8a..229b588bf3d 100644 --- a/gnu/usr.bin/cvs/src/hash.c +++ b/gnu/usr.bin/cvs/src/hash.c @@ -400,6 +400,7 @@ nodetypestring (type) case NDBMNODE: return("NDBMNODE"); case FILEATTR: return("FILEATTR"); case VARIABLE: return("VARIABLE"); + case RCSFIELD: return("RCSFIELD"); } return("<trash>"); diff --git a/gnu/usr.bin/cvs/src/hash.h b/gnu/usr.bin/cvs/src/hash.h index dd83665c4c8..92b25493862 100644 --- a/gnu/usr.bin/cvs/src/hash.h +++ b/gnu/usr.bin/cvs/src/hash.h @@ -20,7 +20,7 @@ enum ntype { UNKNOWN, HEADER, ENTRIES, FILES, LIST, RCSNODE, RCSVERS, DIRS, UPDATE, LOCK, NDBMNODE, FILEATTR, - VARIABLE + VARIABLE, RCSFIELD }; typedef enum ntype Ntype; diff --git a/gnu/usr.bin/cvs/src/myndbm.c b/gnu/usr.bin/cvs/src/myndbm.c index 527f7eee9cb..cae27e7cacd 100644 --- a/gnu/usr.bin/cvs/src/myndbm.c +++ b/gnu/usr.bin/cvs/src/myndbm.c @@ -31,7 +31,7 @@ mydbm_open (file, flags, mode) FILE *fp; DBM *db; - fp = fopen (file, FOPEN_BINARY_READ); + fp = CVS_FOPEN (file, FOPEN_BINARY_READ); if (fp == NULL && !(existence_error (errno) && (flags & O_CREAT))) return ((DBM *) 0); @@ -71,7 +71,7 @@ mydbm_close (db) if (db->modified) { FILE *fp; - fp = fopen (db->name, FOPEN_BINARY_WRITE); + fp = CVS_FOPEN (db->name, FOPEN_BINARY_WRITE); if (fp == NULL) error (1, errno, "cannot write %s", db->name); walklist (db->dbm_list, write_item, (void *)fp); diff --git a/gnu/usr.bin/cvs/src/no_diff.c b/gnu/usr.bin/cvs/src/no_diff.c index a0d00f5a861..31ef057417f 100644 --- a/gnu/usr.bin/cvs/src/no_diff.c +++ b/gnu/usr.bin/cvs/src/no_diff.c @@ -17,15 +17,12 @@ #include "cvs.h" int -No_Difference (file, vers, entries, repository, update_dir) - char *file; +No_Difference (finfo, vers) + struct file_info *finfo; Vers_TS *vers; - List *entries; - char *repository; - char *update_dir; { Node *p; - char tmp[L_tmpnam+1]; + char *tmp; int ret; char *ts, *options; int retcode = 0; @@ -39,33 +36,34 @@ No_Difference (file, vers, entries, repository, update_dir) else options = xstrdup (""); - retcode = RCS_checkout (vers->srcfile->path, NULL, vers->vn_user, options, - tmpnam (tmp), 0, 0); + tmp = cvs_temp_name (); + retcode = RCS_checkout (vers->srcfile, (char *) NULL, vers->vn_user, + (char *) NULL, options, tmp); 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 (file)) /* fix the modes as a side effect */ - xchmod (file, 1); + if (!iswritable (finfo->file)) /* fix the modes as a side effect */ + xchmod (finfo->file, 1); #endif - tocvsPath = wrap_tocvs_process_file (file); + tocvsPath = wrap_tocvs_process_file (finfo->file); /* do the byte by byte compare */ - if (xcmp (tocvsPath == NULL ? file : tocvsPath, tmp) == 0) + 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 (file, 0); + xchmod (finfo->file, 0); #endif /* no difference was found, so fix the entries file */ - ts = time_stamp (file); - Register (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 @@ -73,13 +71,13 @@ No_Difference (file, vers, entries, repository, update_dir) { /* We need to update the entries line on the client side. */ server_update_entries - (file, update_dir, repository, SERVER_UPDATED); + (finfo->file, finfo->update_dir, finfo->repository, SERVER_UPDATED); } #endif free (ts); /* update the entdata pointer in the vers_ts structure */ - p = findnode (entries, file); + p = findnode (finfo->entries, finfo->file); vers->entdata = (Entnode *) p->data; ret = 0; @@ -98,20 +96,15 @@ No_Difference (file, vers, entries, repository, update_dir) ' ', #endif tocvsPath); - if (unlink (tocvsPath) < 0) + if ( CVS_UNLINK (tocvsPath) < 0) error (0, errno, "could not remove %s", tocvsPath); } } else { - if (update_dir[0] == '\0') - error (0, retcode == -1 ? errno : 0, - "could not check out revision %s of %s", - vers->vn_user, file); - else - error (0, retcode == -1 ? errno : 0, - "could not check out revision %s of %s/%s", - vers->vn_user, update_dir, file); + 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 */ } @@ -122,8 +115,9 @@ No_Difference (file, vers, entries, repository, update_dir) #else (void) fprintf (stderr, "-> unlink (%s)\n", tmp); #endif - if (unlink (tmp) < 0) + if (CVS_UNLINK (tmp) < 0) error (0, errno, "could not remove %s", tmp); + free (tmp); free (options); return (ret); } diff --git a/gnu/usr.bin/cvs/src/options.h.in b/gnu/usr.bin/cvs/src/options.h.in index 7cb58dcd944..0f6374b8b5a 100644 --- a/gnu/usr.bin/cvs/src/options.h.in +++ b/gnu/usr.bin/cvs/src/options.h.in @@ -16,65 +16,68 @@ */ /* - * CVS provides the most features when used in conjunction with the Version-5 - * release of RCS. Thus, it is the default. This also assumes that GNU diff - * Version-1.15 is being used as well -- you will have to configure your RCS - * V5 release separately to make this the case. If you do not have RCS V5 and - * GNU diff V1.15, comment out this define. You should not try mixing and - * matching other combinations of these tools. + * CVS provides the most features when used in conjunction with the + * Version-5 release of RCS. Thus, it is the default. This also + * assumes that GNU diff Version-1.15 is being used as well -- you + * will have to configure your RCS V5 release separately to make this + * the case. If you do not have RCS V5 and GNU diff V1.15, comment out + * this define. You should not try mixing and matching other + * combinations of these tools. */ #ifndef HAVE_RCS5 #define HAVE_RCS5 #endif /* - * If, before installing this version of CVS, you were running RCS V4 AND you - * are installing this CVS and RCS V5 and GNU diff 1.15 all at the same time, - * you should turn on the following define. It only exists to try to do - * reasonable things with your existing checked out files when you upgrade to - * RCS V5, since the keyword expansion formats have changed with RCS V5. + * If, before installing this version of CVS, you were running RCS V4 + * AND you are installing this CVS and RCS V5 and GNU diff 1.15 all at + * the same time, you should turn on the following define. It only + * exists to try to do reasonable things with your existing checked + * out files when you upgrade to RCS V5, since the keyword expansion + * formats have changed with RCS V5. * - * If you already have been running with RCS5, or haven't been running with CVS - * yet at all, or are sticking with RCS V4 for now, leave the commented out. + * If you already have been running with RCS5, or haven't been running + * with CVS yet at all, or are sticking with RCS V4 for now, leave the + * commented out. */ #ifndef HAD_RCS4 /* #define HAD_RCS4 */ #endif /* - * For portability and heterogeneity reasons, CVS is shipped by default using - * my own text-file version of the ndbm database library in the src/myndbm.c - * file. If you want better performance and are not concerned about - * heterogeneous hosts accessing your modules file, turn this option off. + * For portability and heterogeneity reasons, CVS is shipped by + * default using my own text-file version of the ndbm database library + * in the src/myndbm.c file. If you want better performance and are + * not concerned about heterogeneous hosts accessing your modules + * file, turn this option off. */ #ifndef MY_NDBM #define MY_NDBM #endif /* - * The "diff" program to execute when creating patch output. This "diff" - * must support the "-c" option for context diffing. Specify a full - * pathname if your site wants to use a particular diff. Note that unlike - * the diff used with RCS, you *must not* supply -a here (doing so will cause - * the server to generate patches which patch cannot handle in some cases). + * The "diff" program to execute when creating patch output. This + * "diff" must support the "-c" option for context diffing. Specify a + * full pathname if your site wants to use a particular diff. Note + * that unlike the diff used with RCS, you *must not* supply -a here + * (doing so will cause the server to generate patches which patch + * cannot handle in some cases). * * NOTE: this program is only used for the ``patch'' sub-command (and * for ``update'' if you are using the server). The other commands * use rcsdiff which will use whatever version of diff was specified * when rcsdiff was built on your system. */ - #ifndef DIFF #define DIFF "diff" #endif /* - * The "grep" program to execute when checking to see if a merged file had - * any conflicts. This "grep" must support a standard basic - * regular expression as an argument. Specify a full pathname if your site - * wants to use a particular grep. + * The "grep" program to execute when checking to see if a merged file + * had any conflicts. This "grep" must support a standard basic + * regular expression as an argument. Specify a full pathname if your + * site wants to use a particular grep. */ - #ifndef GREP #define GREP "grep" #endif @@ -89,13 +92,13 @@ #endif /* - * By default, RCS programs are executed with the shell or through execlp(), - * so the user's PATH environment variable is searched. If you'd like to - * bind all RCS programs to a certain directory (perhaps one not in most - * people's PATH) then set the default in RCSBIN_DFLT. Note that setting - * this here will cause all RCS programs to be executed from this directory, - * unless the user overrides the default with the RCSBIN environment variable - * or the "-b" option to CVS. + * By default, RCS programs are executed with the shell or through + * execlp(), so the user's PATH environment variable is searched. If + * you'd like to bind all RCS programs to a certain directory (perhaps + * one not in most people's PATH) then set the default in RCSBIN_DFLT. + * Note that setting this here will cause all RCS programs to be + * executed from this directory, unless the user overrides the default + * with the RCSBIN environment variable or the "-b" option to CVS. * * If you use the password-authenticating server, then you need to * make sure that the server can find the RCS programs to invoke them. @@ -104,12 +107,16 @@ * complete. But no actual shell is ever started by that user, so the * PATH environment variable may not contain the directory with the * RCS binaries, even though if that user logged in normally, PATH - * would include the directory. + * would include the directory. * * One way to solve this problem is to set RCSBIN_DFLT here. An * alternative is to make sure that root has the right directory in * its path already. Another, probably better alternative is to - * specify -b in /etc/inetd.conf. + * specify -b in /etc/inetd.conf. + * + * You may also have to set RCSBIN_DFLT here if there's no global + * start-up script run for users by rshd and your RCS programs are not + * in a directory in the default PATH assigned by rshd. * * This define should be either the empty string ("") or a full * pathname to the directory containing all the installed programs @@ -120,11 +127,22 @@ #endif /* - * The default editor to use, if one does not specify the "-e" option to cvs, - * or does not have an EDITOR environment variable. I set this to just "vi", - * and use the shell to find where "vi" actually is. This allows sites with - * /usr/bin/vi or /usr/ucb/vi to work equally well (assuming that your PATH - * is reasonable). + * The password-authenticating server creates a temporary checkout of + * the affected files. The variable TMPDIR_DFLT (or even better, the + * command-line option "-T" in the line for CVS in /etc/inetd.conf) + * can be used to specify the used directory. This directory will + * also be used for other temporary files. + */ +#ifndef TMPDIR_DFLT +#define TMPDIR_DFLT "/tmp" +#endif + +/* + * The default editor to use, if one does not specify the "-e" option + * to cvs, or does not have an EDITOR environment variable. I set + * this to just "vi", and use the shell to find where "vi" actually + * is. This allows sites with /usr/bin/vi or /usr/ucb/vi to work + * equally well (assuming that your PATH is reasonable). */ #ifndef EDITOR_DFLT #define EDITOR_DFLT "vi" @@ -147,22 +165,23 @@ * The cvs admin command is restricted to the members of the group * CVS_ADMIN_GROUP. If this group does not exist, all users are * allowed to run cvs admin. To disable the cvs admin for all users, - * create an empty group CVS_ADMIN_GROUP. To disable access control for - * cvs admin, comment out the define below. + * create an empty group CVS_ADMIN_GROUP. To disable access control + * for cvs admin, comment out the define below. */ #ifndef CVS_ADMIN_GROUP #define CVS_ADMIN_GROUP "cvsadmin" #endif /* - * The Repository file holds the path to the directory within the source - * repository that contains the RCS ,v files for each CVS working directory. - * This path is either a full-path or a path relative to CVSROOT. + * The Repository file holds the path to the directory within the + * source repository that contains the RCS ,v files for each CVS + * working directory. This path is either a full-path or a path + * relative to CVSROOT. * - * The only advantage that I can see to having a relative path is that One can - * change the physical location of the master source repository, change one's - * CVSROOT environment variable, and CVS will work without problems. I - * recommend using full-paths. + * The only advantage that I can see to having a relative path is that + * one can change the physical location of the master source + * repository, change one's CVSROOT environment variable, and CVS will + * work without problems. I recommend using full-paths. */ #ifndef RELATIVE_REPOS /* #define RELATIVE_REPOS */ @@ -170,25 +189,28 @@ /* * When committing or importing files, you must enter a log message. - * Normally, you can do this either via the -m flag on the command line or an - * editor will be started for you. If you like to use logging templates (the - * rcsinfo file within the $CVSROOT/CVSROOT directory), you might want to - * force people to use the editor even if they specify a message with -m. - * Enabling FORCE_USE_EDITOR will cause the -m message to be appended to the - * temp file when the editor is started. + * Normally, you can do this either via the -m flag on the command + * line or an editor will be started for you. If you like to use + * logging templates (the rcsinfo file within the $CVSROOT/CVSROOT + * directory), you might want to force people to use the editor even + * if they specify a message with -m. Enabling FORCE_USE_EDITOR will + * cause the -m message to be appended to the temp file when the + * editor is started. */ #ifndef FORCE_USE_EDITOR /* #define FORCE_USE_EDITOR */ #endif /* - * When locking the repository, some sites like to remove locks and assume - * the program that created them went away if the lock has existed for a long - * time. This used to be the default for previous versions of CVS. CVS now - * attempts to be much more robust, so lock files should not be left around - * by mistake. The new behaviour will never remove old locks (they must now - * be removed by hand). Enabling CVS_FUDGELOCKS will cause CVS to remove - * locks that are older than CVSLCKAGE seconds. + * When locking the repository, some sites like to remove locks and + * assume the program that created them went away if the lock has + * existed for a long time. This used to be the default for previous + * versions of CVS. CVS now attempts to be much more robust, so lock + * files should not be left around by mistake. The new behaviour will + * never remove old locks (they must now be removed by hand). + * Enabling CVS_FUDGELOCKS will cause CVS to remove locks that are + * older than CVSLCKAGE seconds. + * * Use of this option is NOT recommended. */ #ifndef CVS_FUDGELOCKS @@ -197,73 +219,65 @@ /* * When committing a permanent change, CVS and RCS make a log entry of - * who committed the change. If you are committing the change logged in - * as "root" (not under "su" or other root-priv giving program), CVS/RCS - * cannot determine who is actually making the change. + * who committed the change. If you are committing the change logged + * in as "root" (not under "su" or other root-priv giving program), + * CVS/RCS cannot determine who is actually making the change. * * As such, by default, CVS disallows changes to be committed by users - * logged in as "root". You can disable this option by commenting - * out the lines below. + * logged in as "root". You can disable this option by commenting out + * the lines below. */ #ifndef CVS_BADROOT #define CVS_BADROOT #endif /* - * The "cvs diff" command accepts all the single-character options that GNU - * diff (1.15) accepts. Except -D. GNU diff uses -D as a way to put - * cpp-style #define's around the output differences. CVS, by default, uses - * -D to specify a free-form date (like "cvs diff -D '1 week ago'"). If - * you would prefer that the -D option of "cvs diff" work like the GNU diff - * option, then comment out this define. + * Define this to enable the SETXID support. The way to use this is + * to create a group with no users in it (except perhaps cvs + * administrators), set the cvs executable to setgid that group, chown + * all the repository files to that group, and change all directory + * permissions in the repository to 770. The last person to modify a + * file will own it, but as long as directory permissions are set + * right that won't matter. You'll need a system which inherits file + * groups from the parent directory. I don't know how carefully this + * has been inspected for security holes. */ -#ifndef CVS_DIFFDATE -#define CVS_DIFFDATE -#endif - -/* Define this to enable the SETXID support. The way to use this is - to create a group with no users in it (except perhaps cvs - administrators), set the cvs executable to setgid that group, chown - all the repository files to that group, and change all directory - permissions in the repository to 770. The last person to modify a - file will own it, but as long as directory permissions are set - right that won't matter. You'll need a system which inherits file - groups from the parent directory. I don't know how carefully this - has been inspected for security holes. */ - #ifndef SETXID_SUPPORT /* #define SETXID_SUPPORT */ #endif -/* Should we build the password-authenticating client? Whether to - include the password-authenticating _server_, on the other hand, is - set in config.h. */ +/* + * Should we build the password-authenticating client? Whether to + * include the password-authenticating _server_, on the other hand, is + * set in config.h. + */ +#ifdef CLIENT_SUPPORT #define AUTH_CLIENT_SUPPORT 1 +#endif /* - * If you are working with a large remote repository and a 'cvs checkout' is - * swamping your network and memory, define these to enable flow control. - * You will end up with even less guarantees of a consistant checkout, - * but that may be better than no checkout at all. The master server process - * will monitor how far it is getting behind, if it reaches the high water - * mark, it will signal the child process to stop generating data when - * convenient (ie: no locks are held, currently at the beginning of a - * new directory). Once the buffer has drained sufficiently to reach the - * low water mark, it will be signalled to start again. - * -- EXPERIMENTAL! -- A better solution may be in the works. - * You may override the default hi/low watermarks here too. + * If you are working with a large remote repository and a 'cvs + * checkout' is swamping your network and memory, define these to + * enable flow control. You will end up with even less probability of + * a consistent checkout (see Concurrency in cvs.texinfo), but CVS + * doesn't try to guarantee that anyway. The master server process + * will monitor how far it is getting behind, if it reaches the high + * water mark, it will signal the child process to stop generating + * data when convenient (ie: no locks are held, currently at the + * beginning of a new directory). Once the buffer has drained + * sufficiently to reach the low water mark, it will be signalled to + * start again. You may override the default hi/low watermarks here + * too. */ -#ifndef SERVER_FLOWCONTROL -/* #define SERVER_FLOWCONTROL */ -/* #define SERVER_HI_WATER (2 * 1024 * 1024) */ -/* #define SERVER_LO_WATER (1 * 1024 * 1024) */ -#endif +#define SERVER_FLOWCONTROL +#define SERVER_HI_WATER (2 * 1024 * 1024) +#define SERVER_LO_WATER (1 * 1024 * 1024) /* End of CVS configuration section */ /* - * Externs that are included in libc, but are used frequently enough to - * warrant defining here. + * Externs that are included in libc, but are used frequently enough + * to warrant defining here. */ #ifndef STDC_HEADERS extern void exit (); diff --git a/gnu/usr.bin/cvs/src/rcs.h b/gnu/usr.bin/cvs/src/rcs.h index 698a3b17c04..91175309833 100644 --- a/gnu/usr.bin/cvs/src/rcs.h +++ b/gnu/usr.bin/cvs/src/rcs.h @@ -13,7 +13,6 @@ #define RCS "rcs" #define RCS_CI "ci" #define RCS_CO "co" -#define RCS_RLOG "rlog" #define RCS_DIFF "rcsdiff" #define RCS_RCSMERGE "rcsmerge" #define RCS_MERGE_PAT "^>>>>>>> " /* runs "grep" with this pattern */ @@ -41,6 +40,7 @@ #define VALID 0x1 /* flags field contains valid data */ #define INATTIC 0x2 /* RCS file is located in the Attic */ #define PARTIAL 0x4 /* RCS file not completly parsed */ +#define NODELTA 0x8 /* delta_pos no longer valid */ struct rcsnode { @@ -53,6 +53,8 @@ struct rcsnode char *expand; List *symbols; List *versions; + long delta_pos; + List *other; }; typedef struct rcsnode RCSNode; @@ -65,6 +67,7 @@ struct rcsversnode char *next; int dead; List *branches; + List *other; }; typedef struct rcsversnode RCSVers; @@ -82,12 +85,13 @@ typedef struct rcsversnode RCSVers; */ RCSNode *RCS_parse PROTO((const char *file, const char *repos)); RCSNode *RCS_parsercsfile PROTO((char *rcsfile)); +void RCS_fully_parse PROTO((RCSNode *)); char *RCS_check_kflag PROTO((const char *arg)); char *RCS_getdate PROTO((RCSNode * rcs, char *date, int force_tag_match)); char *RCS_gettag PROTO((RCSNode * rcs, char *symtag, int force_tag_match, - int return_both)); + int *simple_tag)); char *RCS_getversion PROTO((RCSNode * rcs, char *tag, char *date, - int force_tag_match, int return_both)); + int force_tag_match, int *simple_tag)); char *RCS_magicrev PROTO((RCSNode *rcs, char *rev)); int RCS_isbranch PROTO((RCSNode *rcs, const char *rev)); int RCS_nodeisbranch PROTO((RCSNode *rcs, const char *tag)); @@ -102,3 +106,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_settag PROTO ((RCSNode *, const char *, const char *)); +int RCS_deltag PROTO ((RCSNode *, const char *, int)); +int RCS_setbranch PROTO((RCSNode *, const char *)); +int RCS_lock PROTO ((RCSNode *, const char *, int)); +int RCS_unlock PROTO ((RCSNode *, const char *, int)); diff --git a/gnu/usr.bin/cvs/src/remove.c b/gnu/usr.bin/cvs/src/remove.c index 2911bf41ff7..95c395d5d16 100644 --- a/gnu/usr.bin/cvs/src/remove.c +++ b/gnu/usr.bin/cvs/src/remove.c @@ -17,8 +17,10 @@ #include "cvs.h" -static int remove_fileproc PROTO((struct file_info *finfo)); -static Dtype remove_dirproc PROTO((char *dir, char *repos, char *update_dir)); +static int remove_fileproc PROTO ((void *callerdat, struct file_info *finfo)); +static Dtype remove_dirproc PROTO ((void *callerdat, char *dir, + char *repos, char *update_dir, + List *entries)); static int force; static int local; @@ -71,11 +73,34 @@ cvsremove (argc, argv) #ifdef CLIENT_SUPPORT if (client_active) { + /* Call expand_wild so that the local removal of files will + work. It's ok to do it always because we have to send the + file names expanded anyway. */ + expand_wild (argc, argv, &argc, &argv); + + if (force) + { + if (!noexec) + { + int i; + + for (i = 0; i < argc; i++) + { + if ( CVS_UNLINK (argv[i]) < 0 && ! existence_error (errno)) + { + error (0, errno, "unable to remove %s", argv[i]); + } + } + } + /* else FIXME should probably act as if the file doesn't exist + in doing the following checks. */ + } + start_server (); ign_setup (); if (local) send_arg("-l"); - send_file_names (argc, argv, SEND_EXPAND_WILD); + send_file_names (argc, argv, 0); send_files (argc, argv, local, 0); send_to_server ("remove\012", 0); return get_responses_and_close (); @@ -84,8 +109,9 @@ cvsremove (argc, argv) /* start the recursion processor */ err = start_recursion (remove_fileproc, (FILESDONEPROC) NULL, - remove_dirproc, (DIRLEAVEPROC) NULL, argc, argv, - local, W_LOCAL, 0, 1, (char *) NULL, 1, 0); + remove_dirproc, (DIRLEAVEPROC) NULL, NULL, + argc, argv, + local, W_LOCAL, 0, 1, (char *) NULL, 1); if (removed_files) error (0, 0, "use '%s commit' to remove %s permanently", program_name, @@ -106,7 +132,8 @@ cvsremove (argc, argv) */ /* ARGSUSED */ static int -remove_fileproc (finfo) +remove_fileproc (callerdat, finfo) + void *callerdat; struct file_info *finfo; { char fname[PATH_MAX]; @@ -116,7 +143,7 @@ remove_fileproc (finfo) { if (!noexec) { - if (unlink (finfo->file) < 0 && ! existence_error (errno)) + if ( CVS_UNLINK (finfo->file) < 0 && ! existence_error (errno)) { error (0, errno, "unable to remove %s", finfo->fullname); } @@ -125,8 +152,7 @@ remove_fileproc (finfo) in doing the following checks. */ } - vers = Version_TS (finfo->repository, (char *) NULL, (char *) NULL, (char *) NULL, - finfo->file, 0, 0, finfo->entries, finfo->rcs); + vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0); if (vers->ts_user != NULL) { @@ -189,10 +215,12 @@ remove_fileproc (finfo) */ /* ARGSUSED */ static Dtype -remove_dirproc (dir, repos, update_dir) +remove_dirproc (callerdat, dir, repos, update_dir, entries) + void *callerdat; char *dir; char *repos; char *update_dir; + List *entries; { if (!quiet) error (0, 0, "Removing %s", update_dir); diff --git a/gnu/usr.bin/cvs/src/sanity.sh b/gnu/usr.bin/cvs/src/sanity.sh index 4f80f906abf..8d67c1c6cc4 100644 --- a/gnu/usr.bin/cvs/src/sanity.sh +++ b/gnu/usr.bin/cvs/src/sanity.sh @@ -17,6 +17,10 @@ unset CVSREAD TESTDIR=/tmp/cvs-sanity +# This will show up in cvs history output where it prints the working +# directory. It should *not* appear in any cvs output referring to the +# repository; cvs should use the name of the repository as specified. +TMPPWD=`cd /tmp; /bin/pwd` # "debugger" #set -x @@ -26,6 +30,12 @@ echo 'This test should produce no other output than this line, and a final "OK". if test x"$1" = x"-r"; then shift remote=yes + # If we're going to do remote testing, make sure 'rsh' works first. + host="`hostname`" + if test "x`${CVS_RSH-rsh} $host 'echo hi'`" != "xhi"; then + echo "ERROR: cannot test remote CVS, because \`rsh $host' fails." >&2 + exit 1 + fi else remote=no fi @@ -79,18 +89,79 @@ if test -f check.log; then mv check.log check.plog fi +GEXPRLOCS="`echo $PATH | sed 's/:/ /g'` /usr/local/bin /usr/contrib/bin /usr/gnu/bin /local/bin /local/gnu/bin /gun/bin" + +EXPR=expr + +# Cause NextStep 3.3 users to lose in a more graceful fashion. +if $EXPR 'abc +def' : 'abc +def' >/dev/null; then + : good, it works +else + for path in $GEXPRLOCS ; do + if test -x $path/gexpr ; then + if test "X`$path/gexpr --version`" != "X--version" ; then + EXPR=$path/gexpr + break + fi + fi + if test -x $path/expr ; then + if test "X`$path/expr --version`" != "X--version" ; then + EXPR=$path/expr + break + fi + fi + done + if test -z "$EXPR" ; then + echo 'Running these tests requires an "expr" program that can handle' + echo 'multi-line patterns. Make sure that such an expr (GNU, or many but' + echo 'not all vendor-supplied versions) is in your path.' + exit 1 + fi +fi + +# Warn SunOS, SysVr3.2, etc., users that they may be partially losing +# if we can't find a GNU expr to ease their troubles... +if $EXPR 'a +b' : 'a +c' >/dev/null; then + for path in $GEXPRLOCS ; do + if test -x $path/gexpr ; then + if test "X`$path/gexpr --version`" != "X--version" ; then + EXPR=$path/gexpr + break + fi + fi + if test -x $path/expr ; then + if test "X`$path/expr --version`" != "X--version" ; then + EXPR=$path/expr + break + fi + fi + done + if test -z "$EXPR" ; then + echo 'Warning: you are using a version of expr which does not correctly' + echo 'match multi-line patterns. Some tests may spuriously pass.' + echo 'You may wish to make sure GNU expr is in your path.' + EXPR=expr + fi +else + : good, it works +fi + # That we should have to do this is total bogosity, but GNU expr -# version 1.9.4 uses the emacs definition of "$" instead of the unix +# version 1.9.4-1.12 uses the emacs definition of "$" instead of the unix # (e.g. SunOS 4.1.3 expr) one. Rumor has it this will be fixed in the # next release of GNU expr after 1.12 (but we still have to cater to the old # ones for some time because they are in many linux distributions). ENDANCHOR="$" -if expr 'abc +if $EXPR 'abc def' : 'abc$' >/dev/null; then ENDANCHOR='\'\' fi -# Work around another GNU expr (version 1.10) bug/incompatibility. +# Work around another GNU expr (version 1.10-1.12) bug/incompatibility. # "." doesn't appear to match a newline (it does with SunOS 4.1.3 expr). # Note that the workaround is not a complete equivalent of .* because # the first parenthesized expression in the regexp must match something @@ -99,7 +170,7 @@ fi # next release of GNU expr after 1.12 (but we still have to cater to the old # ones for some time because they are in many linux distributions). DOTSTAR='.*' -if expr 'abc +if $EXPR 'abc def' : "a${DOTSTAR}f" >/dev/null; then : good, it works else @@ -115,7 +186,7 @@ fi # next release of GNU expr after 1.12 (but we still have to cater to the old # ones for some time because they are in many linux distributions). PLUS='+' -if expr 'a +b' : "a ${PLUS}b" >/dev/null; then +if $EXPR 'a +b' : "a ${PLUS}b" >/dev/null; then : good, it works else PLUS='\+' @@ -123,35 +194,12 @@ fi # Likewise, for ? QUESTION='?' -if expr 'a?b' : "a${QUESTION}b" >/dev/null; then +if $EXPR 'a?b' : "a${QUESTION}b" >/dev/null; then : good, it works else QUESTION='\?' fi -# Cause NextStep 3.3 users to lose in a more graceful fashion. -if expr 'abc -def' : 'abc -def' >/dev/null; then - : good, it works -else - echo 'Running these tests requires an "expr" program that can handle' - echo 'multi-line patterns. Make sure that such an expr (GNU, or many but' - echo 'not all vendor-supplied versions) is in your path.' - exit 1 -fi - -# Warn SunOS, SysVr3.2, etc., users that they may be partially losing -if expr 'a -b' : 'a -c' >/dev/null; then - echo 'Warning: you are using a version of expr which does not correctly' - echo 'match multi-line patterns. Some tests may spuriously pass.' - echo 'You may wish to make sure GNU expr is in your path.' -else - : good, it works -fi - pass () { echo "PASS: $1" >>${LOGFILE} @@ -174,25 +222,109 @@ dotest_internal () if test -s ${TESTDIR}/dotest.tmp; then echo "** expected: " >>${LOGFILE} echo "$3" >>${LOGFILE} + echo "$3" > ${TESTDIR}/dotest.exp + rm -f ${TESTDIR}/dotest.ex2 echo "** got: " >>${LOGFILE} cat ${TESTDIR}/dotest.tmp >>${LOGFILE} fail "$1" else - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} pass "$1" fi else - if expr "`cat ${TESTDIR}/dotest.tmp`" : \ + if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : \ "$3"${ENDANCHOR} >/dev/null; then - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} pass "$1" else if test x"$4" != x; then - if expr "`cat ${TESTDIR}/dotest.tmp`" : \ + if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : \ "$4"${ENDANCHOR} >/dev/null; then + pass "$1" + else + echo "** expected: " >>${LOGFILE} + echo "$3" >>${LOGFILE} + echo "$3" > ${TESTDIR}/dotest.ex1 + echo "** or: " >>${LOGFILE} + echo "$4" >>${LOGFILE} + echo "$4" > ${TESTDIR}/dotest.ex2 + echo "** got: " >>${LOGFILE} cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" + fi + else + echo "** expected: " >>${LOGFILE} + echo "$3" >>${LOGFILE} + echo "$3" > ${TESTDIR}/dotest.exp + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" + fi + fi + fi +} + +dotest_all_in_one () +{ + if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : \ + "`cat ${TESTDIR}/dotest.exp`" >/dev/null; then + return 0 + fi + return 1 +} + +# WARNING: this won't work with REs that match newlines.... +# +dotest_line_by_line () +{ + line=1 + while [ $line -le `wc -l ${TESTDIR}/dotest.tmp` ] ; do + echo "$line matched \c" >>$LOGFILE + if $EXPR "`sed -n ${line}p ${TESTDIR}/dotest.tmp`" : \ + "`sed -n ${line}p ${TESTDIR}/dotest.exp`" >/dev/null; then + : + else + echo "**** expected line: " >>${LOGFILE} + sed -n ${line}p ${TESTDIR}/dotest.exp >>${LOGFILE} + echo "**** got line: " >>${LOGFILE} + sed -n ${line}p ${TESTDIR}/dotest.tmp >>${LOGFILE} + unset line + return 1 + fi + line=`expr $line + 1` + done + unset line + return 0 +} + +# If you are having trouble telling which line of a multi-line +# expression is not being matched, replace calls to dotest_internal() +# with calls to this function: +# +dotest_internal_debug () +{ + if test -z "$3"; then + if test -s ${TESTDIR}/dotest.tmp; then + echo "** expected: " >>${LOGFILE} + echo "$3" >>${LOGFILE} + echo "$3" > ${TESTDIR}/dotest.exp + rm -f ${TESTDIR}/dotest.ex2 + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" + else + pass "$1" + fi + else + echo "$3" > ${TESTDIR}/dotest.exp + if dotest_line_by_line "$1" "$2"; then + pass "$1" + else + if test x"$4" != x; then + mv ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.ex1 + echo "$4" > ${TESTDIR}/dotest.exp + if dotest_line_by_line "$1" "$2"; then pass "$1" else + mv ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.ex2 echo "** expected: " >>${LOGFILE} echo "$3" >>${LOGFILE} echo "** or: " >>${LOGFILE} @@ -215,7 +347,7 @@ dotest_internal () # Usage: # dotest TESTNAME COMMAND OUTPUT [OUTPUT2] # TESTNAME is the name used in the log to identify the test. -# COMMAND is the command to run; for the test to pass, it exits with +# COMMAND is the command to run; for the test to pass, it exits with # exitstatus zero. # OUTPUT is a regexp which is compared against the output (stdout and # stderr combined) from the test. It is anchored to the start and end @@ -227,6 +359,7 @@ dotest_internal () # lack \|). dotest () { + rm -f ${TESTDIR}/dotest.ex? 2>&1 if $2 >${TESTDIR}/dotest.tmp 2>&1; then : so far so good else @@ -238,9 +371,34 @@ dotest () dotest_internal "$@" } +# Like dotest except only 2 args and result must exactly match stdin +dotest_lit () +{ + rm -f ${TESTDIR}/dotest.ex? 2>&1 + if $2 >${TESTDIR}/dotest.tmp 2>&1; then + : so far so good + else + status=$? + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + echo "exit status was $status" >>${LOGFILE} + fail "$1" + fi + cat >${TESTDIR}/dotest.exp + if cmp ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.tmp >/dev/null 2>&1; then + pass "$1" + else + echo "** expected: " >>${LOGFILE} + cat ${TESTDIR}/dotest.exp >>${LOGFILE} + echo "** got: " >>${LOGFILE} + cat ${TESTDIR}/dotest.tmp >>${LOGFILE} + fail "$1" + fi +} + # Like dotest except exitstatus should be nonzero. dotest_fail () { + rm -f ${TESTDIR}/dotest.ex? 2>&1 if $2 >${TESTDIR}/dotest.tmp 2>&1; then status=$? cat ${TESTDIR}/dotest.tmp >>${LOGFILE} @@ -284,7 +442,13 @@ HOME=${TESTDIR}/home; export HOME # tests. if test x"$*" = x; then - tests="basica basic1 deep basic2 death branches import new conflicts modules mflag errmsg1 devcom ignore binfiles info" + # This doesn't yet include log2, because the bug it tests for + # is not yet fixed, and/or we might want to wait until after 1.9. + # + # We also omit rdiff for now, because we have put off + # committing the changes that make it work until after the 1.9 + # release. + tests="basica basicb basic1 deep basic2 death death2 branches multibranch import join new newb conflicts conflicts2 modules mflag errmsg1 devcom ignore binfiles binwrap info serverpatch log" else tests="$*" fi @@ -350,10 +514,8 @@ dotest_fail 4.75 "test -d tmp" '' # a simple function to compare directory contents # -# BTW, I don't care any more -- if you don't have a /bin/sh that handles -# shell functions, well get one. -# -# Returns: ISDIFF := true|false +# Returns: {nothing} +# Side Effects: ISDIFF := true|false # directory_cmp () { @@ -380,15 +542,14 @@ directory_cmp () cd $OLDPWD while read a do - if [ -f $DIR_1/"$a" ] ; then + if test -f $DIR_1/"$a" ; then cmp -s $DIR_1/"$a" $DIR_2/"$a" - if [ $? -ne 0 ] ; then + if test $? -ne 0 ; then ISDIFF=true fi fi done < /tmp/dc$$d1 -### FIXME: -### rm -f /tmp/dc$$* + rm -f /tmp/dc$$* } # so much for the setup. Let's try something harder. @@ -398,10 +559,10 @@ directory_cmp () CVSROOT_DIRNAME=${TESTDIR}/cvsroot CVSROOT=${CVSROOT_DIRNAME} ; export CVSROOT if test "x$remote" = xyes; then - CVSROOT=`hostname`:${CVSROOT_DIRNAME} ; export CVSROOT - # Use rsh so we can test it without having to muck with inetd or anything - # like that. Also needed to get CVS_SERVER to work. - CVS_CLIENT_PORT=-1; export CVS_CLIENT_PORT + # Use rsh so we can test it without having to muck with inetd + # or anything like that. Also needed to get CVS_SERVER to + # work. + CVSROOT=:ext:`hostname`:${CVSROOT_DIRNAME} ; export CVSROOT CVS_SERVER=${testcvs}; export CVS_SERVER fi @@ -434,6 +595,14 @@ for what in $tests; do dotest basica-1a2 "${testcvs} -q status" '' mkdir sdir + # Remote CVS gives the "cannot open CVS/Entries" error, which is + # clearly a bug, but not a simple one to fix. + dotest basica-1a10 "${testcvs} -n add sdir" \ +'Directory /tmp/cvs-sanity/cvsroot/first-dir/sdir added to the repository' \ +"${PROG} add: cannot open CVS/Entries for reading: No such file or directory +Directory /tmp/cvs-sanity/cvsroot/first-dir/sdir added to the repository" + dotest_fail basica-1a11 \ + "test -d ${CVSROOT_DIRNAME}/first-dir/sdir" '' dotest basica-2 "${testcvs} add sdir" \ 'Directory /tmp/cvs-sanity/cvsroot/first-dir/sdir added to the repository' cd sdir @@ -465,12 +634,12 @@ ${PROG} "'\[[a-z]* aborted\]: correct the above errors first!' done Checking in sdir/ssdir/ssfile; /tmp/cvs-sanity/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile -initial revision: 1.1 +initial revision: 1\.1 done' dotest_fail basica-5a \ "${testcvs} -q tag BASE sdir/ssdir/ssfile" \ "${PROG} [a-z]*: Attempt to add reserved tag name BASE -${PROG} \[[a-z]* aborted\]: failed to set tag BASE to revision 1.1 in /tmp/cvs-sanity/cvsroot/first-dir/sdir/ssdir/ssfile,v" +${PROG} \[[a-z]* aborted\]: failed to set tag BASE to revision 1\.1 in /tmp/cvs-sanity/cvsroot/first-dir/sdir/ssdir/ssfile,v" dotest basica-5b "${testcvs} -q tag NOT_RESERVED" \ 'T sdir/ssdir/ssfile' @@ -489,32 +658,140 @@ diff -c -r1\.1 ssfile --- 1,2 ---- ssfile '"${PLUS} ssfile line 2" + dotest_status basica-6.3 1 "${testcvs} -q diff -c -rBASE" \ +'Index: sdir/ssdir/ssfile +=================================================================== +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/sdir/ssdir/ssfile,v +retrieving revision 1\.1 +diff -c -r1\.1 ssfile +\*\*\* ssfile [0-9/]* [0-9:]* 1\.1 +--- ssfile [0-9/]* [0-9:]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +--- 1,2 ---- + ssfile +'"${PLUS} ssfile line 2" dotest basica-7 "${testcvs} -q ci -m modify-it" \ 'Checking in sdir/ssdir/ssfile; /tmp/cvs-sanity/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 1.2; previous revision: 1.1 +new revision: 1\.2; previous revision: 1\.1 done' dotest_fail basica-nonexist "${testcvs} -q ci nonexist" \ "${PROG}"' [a-z]*: nothing known about `nonexist'\'' '"${PROG}"' \[[a-z]* aborted\]: correct above errors first!' dotest basica-8 "${testcvs} -q update" '' + + # The .* here will normally be "No such file or directory", + # but if memory serves some systems (AIX?) have a different message. +: dotest_fail basica-9 \ + "${testcvs} -q -d /tmp/cvs-sanity/nonexist update" \ +"${PROG}: cannot access cvs root /tmp/cvs-sanity/nonexist: .*" dotest_fail basica-9 \ "${testcvs} -q -d /tmp/cvs-sanity/nonexist update" \ -"${PROG}: .*/tmp/cvs-sanity/cvsroot value for CVS Root found in CVS/Root -${PROG}"': does not match command line -d /tmp/cvs-sanity/nonexist setting -'"${PROG}"': you may wish to try the cvs command again without the -d option ' +"${PROG} \[[a-z]* aborted\]: /tmp/cvs-sanity/nonexist/CVSROOT: .*" dotest basica-10 "${testcvs} annotate" \ 'Annotations for sdir/ssdir/ssfile \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -1.1 .[a-z@][a-z@ ]* [0-9a-zA-Z-]*.: ssfile -1.2 .[a-z@][a-z@ ]* [0-9a-zA-Z-]*.: ssfile line 2' +1\.1 .[a-z0-9@][a-z0-9@ ]* [0-9a-zA-Z-]*.: ssfile +1\.2 .[a-z0-9@][a-z0-9@ ]* [0-9a-zA-Z-]*.: ssfile line 2' cd .. rm -rf ${CVSROOT_DIRNAME}/first-dir rm -r first-dir ;; + basicb) + # More basic tests, including non-branch tags and co -d. + mkdir ${CVSROOT_DIRNAME}/first-dir + dotest basicb-1 "${testcvs} -q co first-dir" '' + cd first-dir + mkdir sdir1 sdir2 + dotest basicb-2 "${testcvs} add sdir1 sdir2" \ +'Directory /tmp/cvs-sanity/cvsroot/first-dir/sdir1 added to the repository +Directory /tmp/cvs-sanity/cvsroot/first-dir/sdir2 added to the repository' + cd sdir1 + echo sfile1 starts >sfile1 + dotest basicb-2a10 "${testcvs} -n add sfile1" \ +"${PROG} [a-z]*: scheduling file .sfile1. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + dotest basicb-2a11 "${testcvs} status sfile1" \ +"${PROG} [a-z]*: use .cvs add' to create an entry for sfile1 +=================================================================== +File: sfile1 Status: Unknown + + Working revision: No entry for sfile1 + Repository revision: No revision control file" + dotest basicb-3 "${testcvs} add sfile1" \ +"${PROG} [a-z]*: scheduling file .sfile1. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + dotest basicb-3a1 "${testcvs} status sfile1" \ +"=================================================================== +File: sfile1 Status: Locally Added + + Working revision: New file! + Repository revision: No revision control file + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none)" + + cd ../sdir2 + echo sfile2 starts >sfile2 + dotest basicb-4 "${testcvs} add sfile2" \ +"${PROG} [a-z]*: scheduling file .sfile2. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + cd .. + dotest basicb-5 "${testcvs} -q ci -m add" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/sdir1/sfile1,v +done +Checking in sdir1/sfile1; +/tmp/cvs-sanity/cvsroot/first-dir/sdir1/sfile1,v <-- sfile1 +initial revision: 1\.1 +done +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/sdir2/sfile2,v +done +Checking in sdir2/sfile2; +/tmp/cvs-sanity/cvsroot/first-dir/sdir2/sfile2,v <-- sfile2 +initial revision: 1\.1 +done' + echo sfile1 develops >sdir1/sfile1 + dotest basicb-6 "${testcvs} -q ci -m modify" \ +'Checking in sdir1/sfile1; +/tmp/cvs-sanity/cvsroot/first-dir/sdir1/sfile1,v <-- sfile1 +new revision: 1\.2; previous revision: 1\.1 +done' + dotest basicb-7 "${testcvs} -q tag release-1" 'T sdir1/sfile1 +T sdir2/sfile2' + echo not in time for release-1 >sdir2/sfile2 + dotest basicb-8 "${testcvs} -q ci -m modify-2" \ +'Checking in sdir2/sfile2; +/tmp/cvs-sanity/cvsroot/first-dir/sdir2/sfile2,v <-- sfile2 +new revision: 1\.2; previous revision: 1\.1 +done' + cd .. + + # Test that we recurse into the correct directory when checking + # for existing files, even if co -d is in use. + touch first-dir/extra + dotest basicb-cod-1 "${testcvs} -q co -d first-dir1 first-dir" \ +'U first-dir1/sdir1/sfile1 +U first-dir1/sdir2/sfile2' + rm -rf first-dir1 + + rm -rf first-dir + dotest basicb-9 \ +"${testcvs} -q co -d newdir -r release-1 first-dir/sdir1 first-dir/sdir2" \ +'U newdir/sdir1/sfile1 +U newdir/sdir2/sfile2' + dotest basicb-10 "cat newdir/sdir1/sfile1 newdir/sdir2/sfile2" \ +"sfile1 develops +sfile2 starts" + + rm -rf newdir + + rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + basic1) # first dive - add a files, first singly, then in a group. mkdir ${CVSROOT_DIRNAME}/first-dir # check out an empty directory @@ -541,7 +818,7 @@ ${PROG}"': does not match command line -d /tmp/cvs-sanity/nonexist setting fi # update it. - if [ "${do}" = "rm" -a "$j" != "commit -m test" ] || ${CVS} update ${files} ; then + if test "${do}" = "rm" -a "$j" != "commit -m test" || ${CVS} update ${files} ; then echo "PASS: test 15-${do}-$j" >>${LOGFILE} else echo "FAIL: test 15-${do}-$j" | tee -a ${LOGFILE}; exit 1 @@ -639,8 +916,8 @@ ${PROG}"': does not match command line -d /tmp/cvs-sanity/nonexist setting '"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently' done cd ../../../../../../../../.. - dotest deep-4 "${testcvs} -q ci -m add-them first-dir" \ -'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/dir1/file1,v + dotest_lit deep-4 "${testcvs} -q ci -m add-them first-dir" <<'HERE' +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/dir1/file1,v done Checking in first-dir/dir1/file1; /tmp/cvs-sanity/cvsroot/first-dir/dir1/file1,v <-- file1 @@ -687,7 +964,23 @@ done Checking in first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1; /tmp/cvs-sanity/cvsroot/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1,v <-- file1 initial revision: 1.1 +done +HERE + + cd first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8 + rm file1 + dotest deep-4a0 "${testcvs} rm file1" \ +"${PROG} [a-z]*: scheduling .file1. for removal +${PROG} [a-z]*: use .cvs commit. to remove this file permanently" + dotest deep-4a1 "${testcvs} -q ci -m rm-it" 'Removing file1; +/tmp/cvs-sanity/cvsroot/first-dir/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file1,v <-- file1 +new revision: delete; previous revision: 1\.1 done' + cd ../../.. + dotest deep-4a2 "${testcvs} -q update -P dir6/dir7" '' + # Should be using "test -e" if that is portable enough. + dotest_fail deep-4a3 "test -d dir6/dir7/dir8" '' + cd ../../../../../.. if echo "yes" | ${testcvs} release -d first-dir >>${LOGFILE}; then pass deep-5 @@ -700,14 +993,21 @@ done' basic2) # Test rtag, import, history, various miscellaneous operations + # NOTE: this section has reached the size and + # complexity where it is getting to be a good idea to + # add new tests to a new section rather than + # continuing to piggyback them onto the tests here. + # First empty the history file rm ${CVSROOT_DIRNAME}/CVSROOT/history touch ${CVSROOT_DIRNAME}/CVSROOT/history +### XXX maybe should use 'cvs imprt -b1 -m new-module first-dir F F1' in an +### empty directory to do this instead of hacking directly into $CVSROOT mkdir ${CVSROOT_DIRNAME}/first-dir dotest basic2-1 "${testcvs} -q co first-dir" '' for i in first-dir dir1 dir2 ; do - if [ ! -d $i ] ; then + if test ! -d $i ; then mkdir $i if ${CVS} add $i >> ${LOGFILE}; then echo "PASS: test 29-$i" >>${LOGFILE} @@ -748,7 +1048,8 @@ done' echo "FAIL: test 33" | tee -a ${LOGFILE} ; exit 1 fi -# if ${CVS} diff -u first-dir >> ${LOGFILE} || [ $? = 1 ] ; then +# XXX why is this commented out??? +# if ${CVS} diff -u first-dir >> ${LOGFILE} || test $? = 1 ; then # echo "PASS: test 34" >>${LOGFILE} # else # echo "FAIL: test 34" | tee -a ${LOGFILE} # ; exit 1 @@ -800,7 +1101,7 @@ done' echo "FAIL: test 39" | tee -a ${LOGFILE} ; exit 1 fi - # fixme: doesn't work right for added files + # FIXME: doesn't work right for added files if ${CVS} log first-dir >> ${LOGFILE}; then echo "PASS: test 40" >>${LOGFILE} else @@ -813,7 +1114,8 @@ done' echo "FAIL: test 41" | tee -a ${LOGFILE} ; exit 1 fi -# if ${CVS} diff -u first-dir >> ${LOGFILE} || [ $? = 1 ] ; then +# XXX why is this commented out? +# if ${CVS} diff -u first-dir >> ${LOGFILE} || test $? = 1 ; then # echo "PASS: test 42" >>${LOGFILE} # else # echo "FAIL: test 42" | tee -a ${LOGFILE} # ; exit 1 @@ -839,7 +1141,7 @@ done' fi # end of third dive - if [ -d first-dir ] ; then + if test -d first-dir ; then echo "FAIL: test 45.5" | tee -a ${LOGFILE} ; exit 1 else echo "PASS: test 45.5" >>${LOGFILE} @@ -869,7 +1171,7 @@ done' fi # rdiff by revision - if ${CVS} rdiff -r1.1 -rrtagged-by-head first-dir >> ${LOGFILE} || [ $? = 1 ] ; then + if ${CVS} rdiff -r1.1 -rrtagged-by-head first-dir >> ${LOGFILE} || test $? = 1 ; then echo "PASS: test 49" >>${LOGFILE} else echo "FAIL: test 49" | tee -a ${LOGFILE} ; exit 1 @@ -917,13 +1219,14 @@ done' directory_cmp first-dir export-dir - if $ISDIFF ; then + if $ISDIFF ; then echo "FAIL: test 55" | tee -a ${LOGFILE} ; exit 1 else echo "PASS: test 55" >>${LOGFILE} fi - # interrupt, while we've got a clean 1.1 here, let's import it into another tree. + # interrupt, while we've got a clean 1.1 here, let's import it + # into a couple of other modules. cd export-dir dotest 56 "${testcvs} import -m first-import second-dir first-immigration immigration1 immigration1_0" \ 'N second-dir/file14 @@ -939,7 +1242,6 @@ N second-dir/dir1/dir2/file6 N second-dir/dir1/dir2/file7 No conflicts created by this import' - cd .. if ${CVS} export -r HEAD second-dir ; then @@ -957,6 +1259,7 @@ No conflicts created by this import' fi rm -rf second-dir + rm -rf export-dir first-dir mkdir first-dir (cd first-dir.cpy ; tar cf - * | (cd ../first-dir ; tar xf -)) @@ -1020,50 +1323,188 @@ No conflicts created by this import' # which don't exist in the remote output? would seem to be # a CVS bug. dotest basic2-64 "${testcvs} his -e -a" \ -'O [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* first-dir =first-dir= /tmp/cvs-sanity/\* -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file6 first-dir == /tmp/cvs-sanity -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file7 first-dir == /tmp/cvs-sanity -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file6 first-dir/dir1 == /tmp/cvs-sanity -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file7 first-dir/dir1 == /tmp/cvs-sanity -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file6 first-dir/dir1/dir2 == /tmp/cvs-sanity -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file7 first-dir/dir1/dir2 == /tmp/cvs-sanity -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file14 first-dir == /tmp/cvs-sanity -M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.2 file6 first-dir == /tmp/cvs-sanity -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file14 first-dir/dir1 == /tmp/cvs-sanity -M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.2 file6 first-dir/dir1 == /tmp/cvs-sanity -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file14 first-dir/dir1/dir2 == /tmp/cvs-sanity -M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.2 file6 first-dir/dir1/dir2 == /tmp/cvs-sanity -F [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* =first-dir= /tmp/cvs-sanity/\* -T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* first-dir \[rtagged-by-head:A\] -T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* first-dir \[rtagged-by-tag:rtagged-by-head\] -T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* first-dir \[rtagged-by-revision:1.1\] -O [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* \[1.1\] first-dir =first-dir= /tmp/cvs-sanity/\* -U [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.2 file6 first-dir == /tmp/cvs-sanity/first-dir -U [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.2 file7 first-dir == /tmp/cvs-sanity/first-dir' \ -'O [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* first-dir =first-dir= <remote>/\* -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file6 first-dir == <remote> -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file7 first-dir == <remote> -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file6 first-dir/dir1 == <remote> -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file7 first-dir/dir1 == <remote> -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file6 first-dir/dir1/dir2 == <remote> -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file7 first-dir/dir1/dir2 == <remote> -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file14 first-dir == <remote> -M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.2 file6 first-dir == <remote> -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file14 first-dir/dir1 == <remote> -M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.2 file6 first-dir/dir1 == <remote> -A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.1 file14 first-dir/dir1/dir2 == <remote> -M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* 1.2 file6 first-dir/dir1/dir2 == <remote> -F [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* =first-dir= <remote>/\* -T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* first-dir \[rtagged-by-head:A\] -T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* first-dir \[rtagged-by-tag:rtagged-by-head\] -T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* first-dir \[rtagged-by-revision:1.1\] -O [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* \[1.1\] first-dir =first-dir= <remote>/\*' +'O [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* first-dir =first-dir= '"${TMPPWD}"'/cvs-sanity/\* +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file6 first-dir == '"${TMPPWD}"'/cvs-sanity +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file7 first-dir == '"${TMPPWD}"'/cvs-sanity +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file6 first-dir/dir1 == '"${TMPPWD}"'/cvs-sanity +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file7 first-dir/dir1 == '"${TMPPWD}"'/cvs-sanity +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file6 first-dir/dir1/dir2 == '"${TMPPWD}"'/cvs-sanity +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file7 first-dir/dir1/dir2 == '"${TMPPWD}"'/cvs-sanity +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file14 first-dir == '"${TMPPWD}"'/cvs-sanity +M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.2 file6 first-dir == '"${TMPPWD}"'/cvs-sanity +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file14 first-dir/dir1 == '"${TMPPWD}"'/cvs-sanity +M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.2 file6 first-dir/dir1 == '"${TMPPWD}"'/cvs-sanity +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file14 first-dir/dir1/dir2 == '"${TMPPWD}"'/cvs-sanity +M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.2 file6 first-dir/dir1/dir2 == '"${TMPPWD}"'/cvs-sanity +F [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* =first-dir= '"${TMPPWD}"'/cvs-sanity/\* +T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* first-dir \[rtagged-by-head:A\] +T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* first-dir \[rtagged-by-tag:rtagged-by-head\] +T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* first-dir \[rtagged-by-revision:1\.1\] +O [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* \[1\.1\] first-dir =first-dir= '"${TMPPWD}"'/cvs-sanity/\* +U [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.2 file6 first-dir == '"${TMPPWD}"'/cvs-sanity/first-dir +U [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.2 file7 first-dir == '"${TMPPWD}"'/cvs-sanity/first-dir' \ +'O [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* first-dir =first-dir= <remote>/\* +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file6 first-dir == <remote> +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file7 first-dir == <remote> +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file6 first-dir/dir1 == <remote> +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file7 first-dir/dir1 == <remote> +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file6 first-dir/dir1/dir2 == <remote> +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file7 first-dir/dir1/dir2 == <remote> +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file14 first-dir == <remote> +M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.2 file6 first-dir == <remote> +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file14 first-dir/dir1 == <remote> +M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.2 file6 first-dir/dir1 == <remote> +A [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.1 file14 first-dir/dir1/dir2 == <remote> +M [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* 1\.2 file6 first-dir/dir1/dir2 == <remote> +F [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* =first-dir= <remote>/\* +T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* first-dir \[rtagged-by-head:A\] +T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* first-dir \[rtagged-by-tag:rtagged-by-head\] +T [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* first-dir \[rtagged-by-revision:1\.1\] +O [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z0-9@][a-z0-9@]* \[1\.1\] first-dir =first-dir= <remote>/\*' rm -rf ${CVSROOT_DIRNAME}/first-dir rm -rf ${CVSROOT_DIRNAME}/second-dir ;; - death) # next dive. test death support. + rdiff) + # Test rdiff + # XXX for now this is just the most essential test... + cd ${TESTDIR} + + mkdir testimport + cd testimport + echo '$''Id$' > foo + echo '$''Name$' >> foo + echo '$''Id$' > bar + echo '$''Name$' >> bar + dotest rdiff-1 \ + "${testcvs} import -I ! -m test-import-with-keyword trdiff TRDIFF T1" \ +'N trdiff/foo +N trdiff/bar + +No conflicts created by this import' + dotest rdiff-2 \ + "${testcvs} co -ko trdiff" \ +'cvs [a-z]*: Updating trdiff +U trdiff/bar +U trdiff/foo' + cd trdiff + echo something >> foo + dotest rdiff-3 \ + "${testcvs} ci -m added-something foo" \ +'Checking in foo; +/tmp/cvs-sanity/cvsroot/trdiff/foo,v <-- foo +new revision: 1\.2; previous revision: 1\.1 +done' + echo '#ident "@(#)trdiff:$''Name$:$''Id$"' > new + echo "new file" >> new + dotest rdiff-4 \ + "${testcvs} add -m new-file-description new" \ +"cvs [a-z]*: scheduling file \`new' for addition +cvs [a-z]*: use 'cvs commit' to add this file permanently" + dotest rdiff-5 \ + "${testcvs} commit -m added-new-file new" \ +'RCS file: /tmp/cvs-sanity/cvsroot/trdiff/new,v +done +Checking in new; +/tmp/cvs-sanity/cvsroot/trdiff/new,v <-- new +initial revision: 1\.1 +done' + dotest rdiff-6 \ + "${testcvs} tag local-v0" \ +'cvs [a-z]*: Tagging . +T bar +T foo +T new' + dotest rdiff-7 \ + "${testcvs} status -v foo" \ +'=================================================================== +File: foo Status: Up-to-date + + Working revision: 1\.2.* + Repository revision: 1\.2 /tmp/cvs-sanity/cvsroot/trdiff/foo,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -ko + + Existing Tags: + local-v0 (revision: 1\.2) + T1 (revision: 1\.1\.1\.1) + TRDIFF (branch: 1\.1\.1)' + + cd .. + rm -rf trdiff + + dotest rdiff-8 \ + "${testcvs} rdiff -r T1 -r local-v0 trdiff" \ +'cvs [a-z]*: Diffing trdiff +Index: trdiff/foo +diff -c trdiff/foo:1\.1\.1\.1 trdiff/foo:1\.2 +\*\*\* trdiff/foo:1\.1\.1\.1 .* +--- trdiff/foo .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1,2 \*\*\*\* +! \$''Id\$ +! \$''Name\$ +--- 1,3 ---- +! \$''Id: foo,v 1\.2 [0-9/]* [0-9:]* [a-zA-Z0-9][a-zA-Z0-9]* Exp \$ +! \$''Name: local-v0 \$ +! something +Index: trdiff/new +diff -c /dev/null trdiff/new:1\.1 +\*\*\* /dev/null .* +--- trdiff/new .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1,2 ---- +'"${PLUS}"' #ident "@(#)trdiff:\$''Name: local-v0 \$:\$''Id: new,v 1\.1 [0-9/]* [0-9:]* [a-zA-Z0-9][a-zA-Z0-9]* Exp \$" +'"${PLUS}"' new file' + + # This appears to be broken client/server + if test "x$remote" = xno; then + dotest rdiff-9 \ + "${testcvs} rdiff -Ko -kv -r T1 -r local-v0 trdiff" \ +'cvs [a-z]*: Diffing trdiff +Index: trdiff/foo +diff -c trdiff/foo:1\.1\.1\.1 trdiff/foo:1\.2 +\*\*\* trdiff/foo:1\.1\.1\.1 .* +--- trdiff/foo .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1,2 \*\*\*\* +! \$''Id\$ +! \$''Name\$ +--- 1,3 ---- +! foo,v 1\.2 .* Exp +! local-v0 +! something +Index: trdiff/new +diff -c /dev/null trdiff/new:1\.1 +\*\*\* /dev/null .* +--- trdiff/new .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1,2 ---- +'"${PLUS}"' #ident "@(#)trdiff:local-v0:new,v 1\.1 .* Exp" +'"${PLUS}"' new file' + fi # end tests we are skipping for client/server + +# FIXME: will this work here? +# if test "$keep" = yes; then +# echo Keeping /tmp/cvs-sanity and exiting due to --keep +# exit 0 +# fi + + rm -rf ${CVSROOT_DIRNAME}/trdiff + ;; + + death) + # next dive. test death support. + + # NOTE: this section has reached the size and + # complexity where it is getting to be a good idea to + # add new death support tests to a new section rather + # than continuing to piggyback them onto the tests here. + mkdir ${CVSROOT_DIRNAME}/first-dir if ${CVS} co first-dir ; then echo "PASS: test 65" >>${LOGFILE} @@ -1088,7 +1529,7 @@ O [0-9/]* [0-9:]* '"${PLUS}"'0000 [a-z@][a-z@]* \[1.1\] first-dir =fir done Checking in sfile; /tmp/cvs-sanity/cvsroot/first-dir/subdir/sfile,v <-- sfile -initial revision: 1.1 +initial revision: 1\.1 done' rm sfile dotest 65a3 "${testcvs} rm sfile" \ @@ -1097,7 +1538,7 @@ done' dotest 65a4 "${testcvs} -q ci -m remove-it" \ 'Removing sfile; /tmp/cvs-sanity/cvsroot/first-dir/subdir/sfile,v <-- sfile -new revision: delete; previous revision: 1.1 +new revision: delete; previous revision: 1\.1 done' cd .. dotest 65a5 "${testcvs} -q update -P" '' @@ -1174,7 +1615,7 @@ done' done Checking in file4; /tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 -initial revision: 1.1 +initial revision: 1\.1 done' rm file4 dotest death-file4-rm "${testcvs} remove file4" \ @@ -1183,9 +1624,13 @@ done' dotest death-file4-cirm "${testcvs} -q ci -m remove file4" \ 'Removing file4; /tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 -new revision: delete; previous revision: 1.1 +new revision: delete; previous revision: 1\.1 done' + # Tag the branchpoint. + dotest death-72a "${testcvs} -q tag bp_branch1" 'T file1 +T file2' + # branch1 if ${CVS} tag -b branch1 ; then echo "PASS: test 73" >>${LOGFILE} @@ -1217,6 +1662,31 @@ done' echo "FAIL: test 76" | tee -a ${LOGFILE} ; exit 1 fi + # Remote CVS outputs nothing for 76a0 and 76a1; until + # this bug is fixed just skip those tests for remote. + if test "x$remote" = xno; then + dotest death-76a0 \ +"${testcvs} -q rdiff -r bp_branch1 -r branch1 first-dir" \ +"Index: first-dir/file3 +diff -c /dev/null first-dir/file3:1\.1\.2\.1 +\*\*\* /dev/null .* +--- first-dir/file3 .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} line1 from branch1" + dotest death-76a1 \ +"${testcvs} -q rdiff -r branch1 -r bp_branch1 first-dir" \ +'Index: first-dir/file3 +diff -c first-dir/file3:1\.1\.2\.1 first-dir/file3:removed +\*\*\* first-dir/file3:1\.1\.2\.1 .* +--- first-dir/file3 .* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- line1 from branch1 +--- 0 ----' + fi + # remove rm file3 if ${CVS} rm file3 2>> ${LOGFILE}; then @@ -1281,22 +1751,24 @@ done' dotest_fail death-file4-4 "test -f file4" '' - if [ -f file3 ] ; then + if test -f file3 ; then echo "FAIL: test 85" | tee -a ${LOGFILE} ; exit 1 else echo "PASS: test 85" >>${LOGFILE} fi # join - if ${CVS} update -j branch1 >> ${LOGFILE} 2>&1; then - echo "PASS: test 86" >>${LOGFILE} - else - echo "FAIL: test 86" | tee -a ${LOGFILE} ; exit 1 - fi + dotest 86 "${testcvs} -q update -j branch1" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v +retrieving revision 1\.3 +retrieving revision 1\.3\.2\.1 +Merging differences between 1\.3 and 1\.3\.2\.1 into file1 +'"${PROG}"' [a-z]*: scheduling file2 for removal +U file3' dotest_fail death-file4-5 "test -f file4" '' - if [ -f file3 ] ; then + if test -f file3 ; then echo "PASS: test 87" >>${LOGFILE} else echo "FAIL: test 87" | tee -a ${LOGFILE} ; exit 1 @@ -1318,11 +1790,27 @@ done' fi # commit - if ${CVS} ci -m test >>${LOGFILE} 2>&1; then - echo "PASS: test 89" >>${LOGFILE} - else - echo "FAIL: test 89" | tee -a ${LOGFILE} ; exit 1 - fi + dotest 89 "${testcvs} -q ci -m test" \ +'Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.4; previous revision: 1\.3 +done +Removing file2; +/tmp/cvs-sanity/cvsroot/first-dir/file2,v <-- file2 +new revision: delete; previous revision: 1\.1 +done +Checking in file3; +/tmp/cvs-sanity/cvsroot/first-dir/file3,v <-- file3 +new revision: 1\.2; previous revision: 1\.1 +done' + cd .. + mkdir 2 + cd 2 + dotest 89a "${testcvs} -q co first-dir" 'U first-dir/file1 +U first-dir/file3' + cd .. + rm -rf 2 + cd first-dir # remove first file. rm file1 @@ -1339,7 +1827,7 @@ done' echo "FAIL: test 91" | tee -a ${LOGFILE} ; exit 1 fi - if [ -f file1 ] ; then + if test -f file1 ; then echo "FAIL: test 92" | tee -a ${LOGFILE} ; exit 1 else echo "PASS: test 92" >>${LOGFILE} @@ -1354,7 +1842,7 @@ done' else echo "PASS: 92.1b" >>${LOGFILE} fi - if test -f file2 ; then + if test -f file3 ; then echo "PASS: 92.1c" >>${LOGFILE} else echo "FAIL: 92.1c" | tee -a ${LOGFILE} ; exit 1 @@ -1369,23 +1857,280 @@ done' dotest_fail death-file4-6 "test -f file4" '' - if [ -f file1 ] ; then + if test -f file1 ; then echo "PASS: test 94" >>${LOGFILE} else echo "FAIL: test 94" | tee -a ${LOGFILE} ; exit 1 fi # and join - if ${CVS} update -j HEAD >> ${LOGFILE} 2>&1; then - echo "PASS: test 95" >>${LOGFILE} - else - echo "FAIL: test 95" | tee -a ${LOGFILE} ; exit 1 - fi + dotest 95 "${testcvs} -q update -j HEAD" \ +"${PROG}"' [a-z]*: file file1 has been modified, but has been removed in revision HEAD +'"${PROG}"' [a-z]*: file file3 exists, but has been added in revision HEAD' dotest_fail death-file4-7 "test -f file4" '' + # file2 should not have been recreated. It was + # deleted on the branch, and has not been modified on + # the trunk. That means that there have been no + # changes between the greatest common ancestor (the + # trunk version) and HEAD. + dotest_fail death-file2-1 "test -f file2" '' + cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir ;; + + death2) + # More tests of death support. + mkdir ${CVSROOT_DIRNAME}/first-dir + dotest death2-1 "${testcvs} -q co first-dir" '' + + cd first-dir + + # Add a file on the trunk. + echo "first revision" > file1 + dotest death2-2 "${testcvs} add file1" \ +"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently' + + dotest death2-3 "${testcvs} -q commit -m add" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v +done +Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done' + + # Make a branch and a non-branch tag. + dotest death2-4 "${testcvs} -q tag -b branch" 'T file1' + dotest death2-5 "${testcvs} -q tag tag" 'T file1' + + # Switch over to the branch. + dotest death2-6 "${testcvs} -q update -r branch" '' + + # Delete the file on the branch. + rm file1 + dotest death2-7 "${testcvs} rm file1" \ +"${PROG} [a-z]*: scheduling .file1. for removal +${PROG} [a-z]*: use .cvs commit. to remove this file permanently" + dotest death2-8 "${testcvs} -q ci -m removed" \ +'Removing file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +new revision: delete; previous revision: 1\.1\.2 +done' + + # Test diff of a dead file. + dotest_fail death2-diff-1 \ +"${testcvs} -q diff -r1.1 -rbranch -c file1" \ +"${PROG} [a-z]*: file1 was removed, no comparison available" + + dotest_fail death2-diff-2 \ +"${testcvs} -q diff -r1.1 -rbranch -N -c file1" \ +"Index: file1 +=================================================================== +RCS file: file1 +diff -N file1 +\*\*\* [a-zA-Z0-9/.]*[ ][ ]*[a-zA-Z0-9: ]* +--- /dev/null[ ][ ]*[a-zA-Z0-9: ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- first revision +--- 0 ----" + + dotest_fail death2-diff-3 "${testcvs} -q diff -rtag -c ." \ +"${PROG} [a-z]*: file1 no longer exists, no comparison available" + + dotest_fail death2-diff-4 "${testcvs} -q diff -rtag -N -c ." \ +"Index: file1 +=================================================================== +RCS file: file1 +diff -N file1 +\*\*\* [a-zA-Z0-9/.]*[ ][ ]*[a-zA-Z0-9: ]* +--- /dev/null[ ][ ]*[a-zA-Z0-9: ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- first revision +--- 0 ----" + + # Test rdiff of a dead file. + dotest death2-rdiff-1 \ +"${testcvs} -q rtag -rbranch rdiff-tag first-dir" '' + + dotest death2-rdiff-2 "${testcvs} -q rdiff -rtag -rbranch first-dir" \ +"Index: first-dir/file1 +diff -c first-dir/file1:1\.1 first-dir/file1:removed +\*\*\* first-dir/file1:1\.1[ ][ ]*[a-zA-Z0-9: ]* +--- first-dir/file1[ ][ ]*[a-zA-Z0-9: ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +- first revision +--- 0 ----" + + # Readd the file to the branch. + echo "second revision" > file1 + dotest death2-9 "${testcvs} add file1" \ +"${PROG}"' [a-z]*: file `file1'\'' will be added on branch `branch'\'' from version 1\.1\.2\.1 +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently' + dotest death2-10 "${testcvs} -q commit -m add" \ +'Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 +done' + + # Back to the trunk. + dotest death2-11 "${testcvs} -q update -A" 'U file1' 'P file1' + + # Add another file on the trunk. + echo "first revision" > file2 + dotest death2-12 "${testcvs} add file2" \ +"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently' + dotest death2-13 "${testcvs} -q commit -m add" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file2,v +done +Checking in file2; +/tmp/cvs-sanity/cvsroot/first-dir/file2,v <-- file2 +initial revision: 1\.1 +done' + + # Back to the branch. + # The ``no longer in the repository'' message doesn't really + # look right to me, but that's what CVS currently prints for + # this case. + dotest death2-14 "${testcvs} -q update -r branch" \ +"U file1 +${PROG} [a-z]*: file2 is no longer in the repository" \ +"P file1 +${PROG} [a-z]*: file2 is no longer in the repository" + + # Add a file on the branch with the same name. + echo "branch revision" > file2 + dotest death2-15 "${testcvs} add file2" \ +"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition on branch `branch'\'' +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently' + dotest death2-16 "${testcvs} -q commit -m add" \ +'Checking in file2; +/tmp/cvs-sanity/cvsroot/first-dir/file2,v <-- file2 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done' + + # Add a new file on the branch. + echo "first revision" > file3 + dotest death2-17 "${testcvs} add file3" \ +"${PROG}"' [a-z]*: scheduling file `file3'\'' for addition on branch `branch'\'' +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently' + dotest death2-18 "${testcvs} -q commit -m add" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/Attic/file3,v +done +Checking in file3; +/tmp/cvs-sanity/cvsroot/first-dir/Attic/file3,v <-- file3 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done' + + # Test diff of a nonexistent tag + dotest_fail death2-diff-5 "${testcvs} -q diff -rtag -c file3" \ +"${PROG} [a-z]*: tag tag is not in file file3" + + dotest_fail death2-diff-6 "${testcvs} -q diff -rtag -N -c file3" \ +"Index: file3 +=================================================================== +RCS file: file3 +diff -N file3 +\*\*\* /dev/null[ ][ ]*[a-zA-Z0-9: ]* +--- [a-zA-Z0-9/.]*[ ][ ]*[a-zA-Z0-9: ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} first revision" + + dotest_fail death2-diff-7 "${testcvs} -q diff -rtag -c ." \ +"Index: file1 +=================================================================== +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.2 +diff -c -r1\.1 -r1\.1\.2\.2 +\*\*\* file1[ ][ ]*[a-zA-Z0-9:./ ]* +--- file1[ ][ ]*[a-zA-Z0-9:./ ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +! first revision +--- 1 ---- +! second revision +${PROG} [a-z]*: tag tag is not in file file2 +${PROG} [a-z]*: tag tag is not in file file3" + + dotest_fail death2-diff-8 "${testcvs} -q diff -rtag -c -N ." \ +"Index: file1 +=================================================================== +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.2 +diff -c -r1\.1 -r1\.1\.2\.2 +\*\*\* file1[ ][ ]*[a-zA-Z0-9:./ ]* +--- file1[ ][ ]*[a-zA-Z0-9:./ ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 1 \*\*\*\* +! first revision +--- 1 ---- +! second revision +Index: file2 +=================================================================== +RCS file: file2 +diff -N file2 +\*\*\* /dev/null[ ][ ]*[a-zA-Z0-9: ]* +--- [a-zA-Z0-9/.]*[ ][ ]*[a-zA-Z0-9: ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} branch revision +Index: file3 +=================================================================== +RCS file: file3 +diff -N file3 +\*\*\* /dev/null[ ][ ]*[a-zA-Z0-9: ]* +--- [a-zA-Z0-9/.]*[ ][ ]*[a-zA-Z0-9: ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} first revision" + + # Switch to the nonbranch tag. + dotest death2-19 "${testcvs} -q update -r tag" \ +"U file1 +${PROG} [a-z]*: file2 is no longer in the repository +${PROG} [a-z]*: file3 is no longer in the repository" \ +"P file1 +${PROG} [a-z]*: file2 is no longer in the repository +${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-9 "${testcvs} -q diff -r rdiff-tag" \ +"${PROG} [a-z]*: file1 is a new entry, no comparison available" + + dotest_fail death2-diff-10 "${testcvs} -q diff -r rdiff-tag -c -N" \ +"Index: file1 +=================================================================== +RCS file: file1 +diff -N file1 +\*\*\* /dev/null[ ][ ]*[a-zA-Z0-9: ]* +--- [a-zA-Z0-9/.]*[ ][ ]*[a-zA-Z0-9: ]* +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +\*\*\* 0 \*\*\*\* +--- 1 ---- +${PLUS} first revision" + + cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir + ;; + branches) # More branch tests, including branches off of branches mkdir ${CVSROOT_DIRNAME}/first-dir @@ -1401,8 +2146,8 @@ done' '"${PROG}"' [a-z]*: scheduling file `file3'\'' for addition '"${PROG}"' [a-z]*: scheduling file `file4'\'' for addition '"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add these files permanently' - dotest branches-3 "${testcvs} -q ci -m add-it" \ -'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v + dotest_lit branches-3 "${testcvs} -q ci -m add-it" <<'HERE' +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v done Checking in file1; /tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 @@ -1425,12 +2170,13 @@ done Checking in file4; /tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 initial revision: 1.1 -done' +done +HERE echo 4:trunk-2 >file4 dotest branches-3.2 "${testcvs} -q ci -m trunk-before-branch" \ 'Checking in file4; /tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 -new revision: 1.2; previous revision: 1.1 +new revision: 1\.2; previous revision: 1\.1 done' dotest branches-4 "${testcvs} tag -b br1" "${PROG}"' [a-z]*: Tagging \. T file1 @@ -1445,15 +2191,15 @@ T file4' dotest branches-6 "${testcvs} -q ci -m modify" \ 'Checking in file1; /tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 -new revision: 1.1.2.1; previous revision: 1.1 +new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in file2; /tmp/cvs-sanity/cvsroot/first-dir/file2,v <-- file2 -new revision: 1.1.2.1; previous revision: 1.1 +new revision: 1\.1\.2\.1; previous revision: 1\.1 done Checking in file4; /tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 -new revision: 1.2.2.1; previous revision: 1.2 +new revision: 1\.2\.2\.1; previous revision: 1\.2 done' dotest branches-7 "${testcvs} -q tag -b brbr" 'T file1 T file2 @@ -1465,11 +2211,11 @@ T file4' dotest branches-9 "${testcvs} -q ci -m modify" \ 'Checking in file1; /tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 -new revision: 1.1.2.1.2.1; previous revision: 1.1.2.1 +new revision: 1\.1\.2\.1\.2\.1; previous revision: 1\.1\.2\.1 done Checking in file4; /tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 -new revision: 1.2.2.1.2.1; previous revision: 1.2.2.1 +new revision: 1\.2\.2\.1\.2\.1; previous revision: 1\.2\.2\.1 done' dotest branches-10 "cat file1 file2 file3 file4" '1:brbr 2:br1 @@ -1486,7 +2232,7 @@ done' dotest branches-12.2 "${testcvs} -q ci -m change-on-br1" \ 'Checking in file4; /tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 -new revision: 1.2.2.2; previous revision: 1.2.2.1 +new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1 done' dotest branches-13 "${testcvs} -q update -A" '[UP] file1 [UP] file2 @@ -1500,7 +2246,7 @@ done' "${testcvs} -q ci -m trunk-change-after-branch" \ 'Checking in file4; /tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 -new revision: 1.3; previous revision: 1.2 +new revision: 1\.3; previous revision: 1\.2 done' dotest branches-14.3 "${testcvs} log file4" \ ' @@ -1518,29 +2264,29 @@ total revisions: 6; selected revisions: 6 description: ---------------------------- revision 1\.3 -date: [0-9/: ]*; author: [a-z@][a-z@]*; state: Exp; lines: '"${PLUS}"'1 -1 +date: [0-9/: ]*; author: [a-z0-9@][a-z0-9@]*; state: Exp; lines: '"${PLUS}"'1 -1 trunk-change-after-branch ---------------------------- revision 1\.2 -date: [0-9/: ]*; author: [a-z@][a-z@]*; state: Exp; lines: '"${PLUS}"'1 -1 +date: [0-9/: ]*; author: [a-z0-9@][a-z0-9@]*; state: Exp; lines: '"${PLUS}"'1 -1 branches: 1\.2\.2; trunk-before-branch ---------------------------- revision 1\.1 -date: [0-9/: ]*; author: [a-z@][a-z@]*; state: Exp; +date: [0-9/: ]*; author: [a-z0-9@][a-z0-9@]*; state: Exp; add-it ---------------------------- revision 1\.2\.2\.2 -date: [0-9/: ]*; author: [a-z@][a-z@]*; state: Exp; lines: '"${PLUS}"'1 -1 +date: [0-9/: ]*; author: [a-z0-9@][a-z0-9@]*; state: Exp; lines: '"${PLUS}"'1 -1 change-on-br1 ---------------------------- revision 1\.2\.2\.1 -date: [0-9/: ]*; author: [a-z@][a-z@]*; state: Exp; lines: '"${PLUS}"'1 -1 +date: [0-9/: ]*; author: [a-z0-9@][a-z0-9@]*; state: Exp; lines: '"${PLUS}"'1 -1 branches: 1\.2\.2\.1\.2; modify ---------------------------- revision 1\.2\.2\.1\.2\.1 -date: [0-9/: ]*; author: [a-z@][a-z@]*; state: Exp; lines: '"${PLUS}"'1 -1 +date: [0-9/: ]*; author: [a-z0-9@][a-z0-9@]*; state: Exp; lines: '"${PLUS}"'1 -1 modify =============================================================================' dotest_status branches-14.4 1 \ @@ -1576,15 +2322,98 @@ diff -c -r1\.1 -r1\.2\.2\.1 dotest branches-15 \ "${testcvs} update -j 1.1.2.1 -j 1.1.2.1.2.1 file1" \ 'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v -retrieving revision 1.1.2.1 -retrieving revision 1.1.2.1.2.1 -Merging differences between 1.1.2.1 and 1.1.2.1.2.1 into file1 +retrieving revision 1\.1\.2\.1 +retrieving revision 1\.1\.2\.1\.2\.1 +Merging differences between 1\.1\.2\.1 and 1\.1\.2\.1\.2\.1 into file1 rcsmerge: warning: conflicts during merge' dotest branches-16 "cat file1" '<<<<<<< file1 1:ancest ======= 1:brbr ->>>>>>> 1.1.2.1.2.1' +[>]>>>>>> 1\.1\.2\.1\.2\.1' + cd .. + + if test "$keep" = yes; then + echo Keeping /tmp/cvs-sanity and exiting due to --keep + exit 0 + fi + + rm -rf ${CVSROOT_DIRNAME}/first-dir + rm -r first-dir + ;; + + multibranch) + # Test the ability to have several branchpoints coming off the + # same revision. + mkdir ${CVSROOT_DIRNAME}/first-dir + dotest multibranch-1 "${testcvs} -q co first-dir" '' + cd first-dir + echo 1:trunk-1 >file1 + dotest multibranch-2 "${testcvs} add file1" \ +"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently' + dotest_lit multibranch-3 "${testcvs} -q ci -m add-it" <<'HERE' +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v +done +Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1.1 +done +HERE + dotest multibranch-4 "${testcvs} tag -b br1" \ +"${PROG} [a-z]*: Tagging \. +T file1" + dotest multibranch-5 "${testcvs} tag -b br2" \ +"${PROG} [a-z]*: Tagging \. +T file1" + dotest multibranch-6 "${testcvs} -q update -r br1" '' + echo on-br1 >file1 + dotest multibranch-7 "${testcvs} -q ci -m modify-on-br1" \ +'Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done' + dotest multibranch-8 "${testcvs} -q update -r br2" '[UP] file1' + echo br2 adds a line >>file1 + dotest multibranch-9 "${testcvs} -q ci -m modify-on-br2" \ +'Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.1\.4\.1; previous revision: 1\.1 +done' + dotest multibranch-10 "${testcvs} -q update -r br1" '[UP] file1' + dotest multibranch-11 "cat file1" 'on-br1' + dotest multibranch-12 "${testcvs} -q update -r br2" '[UP] file1' + dotest multibranch-13 "cat file1" '1:trunk-1 +br2 adds a line' + + dotest multibranch-14 "${testcvs} log file1" \ +" +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v +Working file: file1 +head: 1\.1 +branch: +locks: strict +access list: +symbolic names: + br2: 1\.1\.0\.4 + br1: 1\.1\.0\.2 +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1\.1 +date: [0-9/]* [0-9:]*; author: [0-9a-zA-Z-]*; state: Exp; +branches: 1\.1\.2; 1\.1\.4; +add-it +---------------------------- +revision 1\.1\.4\.1 +date: [0-9/]* [0-9:]*; author: [0-9a-zA-Z-]*; state: Exp; lines: ${PLUS}1 -0 +modify-on-br2 +---------------------------- +revision 1\.1\.2\.1 +date: [0-9/]* [0-9:]*; author: [0-9a-zA-Z-]*; state: Exp; lines: ${PLUS}1 -1 +modify-on-br1 +=============================================================================" cd .. if test "$keep" = yes; then @@ -1634,7 +2463,7 @@ rcsmerge: warning: conflicts during merge' cd first-dir for i in 1 2 3 4 ; do - if [ -f imported-file"$i" ] ; then + if test -f imported-file"$i" ; then echo "PASS: test 98-$i" >>${LOGFILE} else echo "FAIL: test 98-$i" | tee -a ${LOGFILE} ; exit 1 @@ -1655,9 +2484,6 @@ rcsmerge: warning: conflicts during merge' fi # change - # this sleep is significant. Otherwise, on some machines, things happen so - # fast that the file mod times do not differ. - sleep 1 echo local-change >> imported-file2 # commit @@ -1732,14 +2558,14 @@ rcsmerge: warning: conflicts during merge' cd first-dir - if [ -f imported-file1 ] ; then + if test -f imported-file1 ; then echo "FAIL: test 108" | tee -a ${LOGFILE} ; exit 1 else echo "PASS: test 108" >>${LOGFILE} fi for i in 2 3 ; do - if [ -f imported-file"$i" ] ; then + if test -f imported-file"$i" ; then echo "PASS: test 109-$i" >>${LOGFILE} else echo "FAIL: test 109-$i" | tee -a ${LOGFILE} ; exit 1 @@ -1753,7 +2579,7 @@ rcsmerge: warning: conflicts during merge' echo "FAIL: test 110" | tee -a ${LOGFILE} ; exit 1 fi - if [ -f imported-file4 ] ; then + if test -f imported-file4 ; then echo "PASS: test 111" >>${LOGFILE} else echo "FAIL: test 111" | tee -a ${LOGFILE} ; exit 1 @@ -1768,37 +2594,385 @@ rcsmerge: warning: conflicts during merge' cd .. - if ${CVS} co -jjunk-1_0 -jjunk-2_0 first-dir >>${LOGFILE} 2>&1; then - echo "PASS: test 113" >>${LOGFILE} - else - echo "FAIL: test 113" | tee -a ${LOGFILE} ; exit 1 - fi + dotest import-113 \ +"${testcvs} -q co -jjunk-1_0 -jjunk-2_0 first-dir" \ +"${PROG}"' [a-z]*: file first-dir/imported-file1 is present in revision junk-2_0 +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/imported-file2,v +retrieving revision 1\.1\.1\.1 +retrieving revision 1\.1\.1\.2 +Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into imported-file2 +rcsmerge: warning: conflicts during merge' cd first-dir - if [ -f imported-file1 ] ; then + if test -f imported-file1 ; then echo "FAIL: test 114" | tee -a ${LOGFILE} ; exit 1 else echo "PASS: test 114" >>${LOGFILE} fi for i in 2 3 ; do - if [ -f imported-file"$i" ] ; then + if test -f imported-file"$i" ; then echo "PASS: test 115-$i" >>${LOGFILE} else echo "FAIL: test 115-$i" | tee -a ${LOGFILE} ; exit 1 fi done - if cat imported-file2 | grep '====' >> ${LOGFILE}; then - echo "PASS: test 116" >>${LOGFILE} - else - echo "FAIL: test 116" | tee -a ${LOGFILE} ; exit 1 - fi + dotest import-116 'cat imported-file2' \ +'imported file2 +[<]<<<<<< imported-file2 +import should not expand \$''Id: imported-file2,v 1\.2 [0-9/]* [0-9:]* [a-z0-9@][a-z0-9@]* Exp \$ +local-change +[=]====== +import should not expand \$''Id: imported-file2,v 1\.1\.1\.2 [0-9/]* [0-9:]* [a-z0-9@][a-z0-9@]* Exp \$ +rev 2 of file 2 +[>]>>>>>> 1\.1\.1\.2' + cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir rm -rf import-dir ;; + join) + # Test doing joins which involve adding and removing files. + + # We check merging changes from T1 to T2 into the main line. + # Here are the interesting cases I can think of: + # 1) File added between T1 and T2, not on main line. + # File should be marked for addition. + # 2) File added between T1 and T2, also added on main line. + # Conflict. + # 3) File removed between T1 and T2, unchanged on main line. + # File should be marked for removal. + # 4) File removed between T1 and T2, modified on main line. + # If mod checked in, file should be marked for removal. + # If mod still in working directory, conflict. + # 5) File removed between T1 and T2, was never on main line. + # Nothing should happen. + # 6) File removed between T1 and T2, also removed on main line. + # Nothing should happen. + # 7) File added on main line, not added between T1 and T2. + # Nothing should happen. + # 8) File removed on main line, not modified between T1 and T2. + # Nothing should happen. + + # We also check merging changes from a branch into the main + # line. Here are the interesting cases: + # 1) File added on branch, not on main line. + # File should be marked for addition. + # 2) File added on branch, also added on main line. + # Conflict. + # 3) File removed on branch, unchanged on main line. + # File should be marked for removal. + # 4) File removed on branch, modified on main line. + # Conflict. + # 5) File removed on branch, was never on main line. + # Nothing should happen. + # 6) File removed on branch, also removed on main line. + # Nothing should happen. + # 7) File added on main line, not added on branch. + # Nothing should happen. + # 8) File removed on main line, not modified on branch. + # Nothing should happen. + + # In the tests below, fileN represents case N in the above + # lists. + + mkdir ${CVSROOT_DIRNAME}/first-dir + mkdir 1 + cd 1 + dotest join-1 "${testcvs} -q co first-dir" '' + + cd first-dir + + # Add two files. + echo 'first revision of file3' > file3 + echo 'first revision of file4' > file4 + echo 'first revision of file6' > file6 + echo 'first revision of file8' > file8 + dotest join-2 "${testcvs} add file3 file4 file6 file8" \ +"${PROG}"' [a-z]*: scheduling file `file3'\'' for addition +'"${PROG}"' [a-z]*: scheduling file `file4'\'' for addition +'"${PROG}"' [a-z]*: scheduling file `file6'\'' for addition +'"${PROG}"' [a-z]*: scheduling file `file8'\'' for addition +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add these files permanently' + + dotest join-3 "${testcvs} -q commit -m add" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file3,v +done +Checking in file3; +/tmp/cvs-sanity/cvsroot/first-dir/file3,v <-- file3 +initial revision: 1\.1 +done +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file4,v +done +Checking in file4; +/tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 +initial revision: 1\.1 +done +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file6,v +done +Checking in file6; +/tmp/cvs-sanity/cvsroot/first-dir/file6,v <-- file6 +initial revision: 1\.1 +done +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file8,v +done +Checking in file8; +/tmp/cvs-sanity/cvsroot/first-dir/file8,v <-- file8 +initial revision: 1\.1 +done' + + # Make a branch. + dotest join-4 "${testcvs} -q tag -b branch ." \ +'T file3 +T file4 +T file6 +T file8' + + # Add file2 and file7, modify file4, and remove file6 and file8. + echo 'first revision of file2' > file2 + echo 'second revision of file4' > file4 + echo 'first revision of file7' > file7 + rm file6 file8 + dotest join-5 "${testcvs} add file2 file7" \ +"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition +'"${PROG}"' [a-z]*: scheduling file `file7'\'' for addition +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add these files permanently' + dotest join-6 "${testcvs} rm file6 file8" \ +"${PROG}"' [a-z]*: scheduling `file6'\'' for removal +'"${PROG}"' [a-z]*: scheduling `file8'\'' for removal +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to remove these files permanently' + dotest join-7 "${testcvs} -q ci -mx ." \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file2,v +done +Checking in file2; +/tmp/cvs-sanity/cvsroot/first-dir/file2,v <-- file2 +initial revision: 1\.1 +done +Checking in file4; +/tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 +new revision: 1\.2; previous revision: 1\.1 +done +Removing file6; +/tmp/cvs-sanity/cvsroot/first-dir/file6,v <-- file6 +new revision: delete; previous revision: 1\.1 +done +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file7,v +done +Checking in file7; +/tmp/cvs-sanity/cvsroot/first-dir/file7,v <-- file7 +initial revision: 1\.1 +done +Removing file8; +/tmp/cvs-sanity/cvsroot/first-dir/file8,v <-- file8 +new revision: delete; previous revision: 1\.1 +done' + + # Check out the branch. + cd ../.. + mkdir 2 + cd 2 + dotest join-8 "${testcvs} -q co -r branch first-dir" \ +'U first-dir/file3 +U first-dir/file4 +U first-dir/file6 +U first-dir/file8' + + cd first-dir + + # Modify the files on the branch, so that T1 is not an + # ancestor of the main line, and add file5 + echo 'first branch revision of file3' > file3 + echo 'first branch revision of file4' > file4 + echo 'first branch revision of file6' > file6 + echo 'first branch revision of file5' > file5 + dotest join-9 "${testcvs} add file5" \ +"${PROG}"' [a-z]*: scheduling file `file5'\'' for addition on branch `branch'\'' +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently' + dotest join-10 "${testcvs} -q ci -mx ." \ +'Checking in file3; +/tmp/cvs-sanity/cvsroot/first-dir/file3,v <-- file3 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done +Checking in file4; +/tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/Attic/file5,v +done +Checking in file5; +/tmp/cvs-sanity/cvsroot/first-dir/Attic/file5,v <-- file5 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done +Checking in file6; +/tmp/cvs-sanity/cvsroot/first-dir/Attic/file6,v <-- file6 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done' + + # Tag the current revisions on the branch. + dotest join-11 "${testcvs} -q tag T1 ." \ +'T file3 +T file4 +T file5 +T file6 +T file8' + + # Add file1 and file2, and remove the other files. + echo 'first branch revision of file1' > file1 + echo 'first branch revision of file2' > file2 + rm file3 file4 file5 file6 + dotest join-12 "${testcvs} add file1 file2" \ +"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition on branch `branch'\'' +'"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition on branch `branch'\'' +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add these files permanently' + dotest join-13 "${testcvs} rm file3 file4 file5 file6" \ +"${PROG}"' [a-z]*: scheduling `file3'\'' for removal +'"${PROG}"' [a-z]*: scheduling `file4'\'' for removal +'"${PROG}"' [a-z]*: scheduling `file5'\'' for removal +'"${PROG}"' [a-z]*: scheduling `file6'\'' for removal +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to remove these files permanently' + dotest join-14 "${testcvs} -q ci -mx ." \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/Attic/file1,v +done +Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/Attic/file1,v <-- file1 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done +Checking in file2; +/tmp/cvs-sanity/cvsroot/first-dir/file2,v <-- file2 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done +Removing file3; +/tmp/cvs-sanity/cvsroot/first-dir/file3,v <-- file3 +new revision: delete; previous revision: 1\.1\.2\.1 +done +Removing file4; +/tmp/cvs-sanity/cvsroot/first-dir/file4,v <-- file4 +new revision: delete; previous revision: 1\.1\.2\.1 +done +Removing file5; +/tmp/cvs-sanity/cvsroot/first-dir/Attic/file5,v <-- file5 +new revision: delete; previous revision: 1\.1\.2\.1 +done +Removing file6; +/tmp/cvs-sanity/cvsroot/first-dir/Attic/file6,v <-- file6 +new revision: delete; previous revision: 1\.1\.2\.1 +done' + + # Tag the current revisions on the branch. + dotest join-15 "${testcvs} -q tag T2 ." \ +'T file1 +T file2 +T file8' + + # Do a checkout with a merge. + cd ../.. + mkdir 3 + cd 3 + dotest join-16 "${testcvs} -q co -jT1 -jT2 first-dir" \ +'U first-dir/file1 +U first-dir/file2 +'"${PROG}"' [a-z]*: file first-dir/file2 exists, but has been added in revision T2 +U first-dir/file3 +'"${PROG}"' [a-z]*: scheduling first-dir/file3 for removal +U first-dir/file4 +'"${PROG}"' [a-z]*: scheduling first-dir/file4 for removal +U first-dir/file7' + + # Verify that the right changes have been scheduled. + cd first-dir + dotest join-17 "${testcvs} -q update" \ +'A file1 +R file3 +R file4' + + # Modify file4 locally, and do an update with a merge. + cd ../../1/first-dir + echo 'third revision of file4' > file4 + dotest join-18 "${testcvs} -q update -jT1 -jT2 ." \ +'U file1 +'"${PROG}"' [a-z]*: file file2 exists, but has been added in revision T2 +'"${PROG}"' [a-z]*: scheduling file3 for removal +M file4 +'"${PROG}"' [a-z]*: file file4 is locally modified, but has been removed in revision T2' + + # Verify that the right changes have been scheduled. + dotest join-19 "${testcvs} -q update" \ +'A file1 +R file3 +M file4' + + # Do a checkout with a merge from a single revision. + + # FIXME: CVS currently gets this wrong. file2 has been + # added on both the branch and the main line, and so should + # be regarded as a conflict. However, given the way that + # CVS sets up the RCS file, there is no way to distinguish + # this case from the case of file2 having existed before the + # branch was made. This could be fixed by reserving + # a revision somewhere, perhaps 1.1, as an always dead + # revision which can be used as the source for files added + # on branches. + cd ../../3 + rm -rf first-dir + dotest join-20 "${testcvs} -q co -jbranch first-dir" \ +'U first-dir/file1 +U first-dir/file2 +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file2,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into file2 +U first-dir/file3 +'"${PROG}"' [a-z]*: scheduling first-dir/file3 for removal +U first-dir/file4 +'"${PROG}"' [a-z]*: file first-dir/file4 has been modified, but has been removed in revision branch +U first-dir/file7' + + # Verify that the right changes have been scheduled. + # The M file2 line is a bug; see above join-20. + cd first-dir + dotest join-21 "${testcvs} -q update" \ +'A file1 +M file2 +R file3' + + # Checkout the main line again. + cd ../../1 + rm -rf first-dir + dotest join-22 "${testcvs} -q co first-dir" \ +'U first-dir/file2 +U first-dir/file3 +U first-dir/file4 +U first-dir/file7' + + # Modify file4 locally, and do an update with a merge from a + # single revision. + # The file2 handling is a bug; see above join-20. + cd first-dir + echo 'third revision of file4' > file4 + dotest join-23 "${testcvs} -q update -jbranch ." \ +'U file1 +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file2,v +retrieving revision 1\.1 +retrieving revision 1\.1\.2\.1 +Merging differences between 1\.1 and 1\.1\.2\.1 into file2 +'"${PROG}"' [a-z]*: scheduling file3 for removal +M file4 +'"${PROG}"' [a-z]*: file file4 is locally modified, but has been removed in revision branch' + + # Verify that the right changes have been scheduled. + # The M file2 line is a bug; see above join-20 + dotest join-24 "${testcvs} -q update" \ +'A file1 +M file2 +R file3 +M file4' + + cd ../.. + rm -rf 1 2 3 ${CVSROOT_DIRNAME}/first-dir + ;; + new) # look for stray "no longer pertinent" messages. mkdir ${CVSROOT_DIRNAME}/first-dir @@ -1852,38 +3026,129 @@ rcsmerge: warning: conflicts during merge' cd .. ; rm -rf first-dir ; rm -rf ${CVSROOT_DIRNAME}/first-dir ;; + newb) + # Test removing a file on a branch and then checking it out. + + # We call this "newb" only because it, like the "new" tests, + # has something to do with "no longer pertinent" messages. + # Not necessarily the most brilliant nomenclature. + + # Create file 'a'. + mkdir ${CVSROOT_DIRNAME}/first-dir + dotest newb-123a "${testcvs} -q co first-dir" '' + cd first-dir + touch a + dotest newb-123b "${testcvs} add a" \ +"${PROG} [a-z]*: scheduling file .a. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + dotest newb-123c "${testcvs} -q ci -m added" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/a,v +done +Checking in a; +/tmp/cvs-sanity/cvsroot/first-dir/a,v <-- a +initial revision: 1\.1 +done' + + # Make a branch. + dotest newb-123d "${testcvs} -q tag -b branch" "T a" + + # Check out the branch. + cd .. + rm -rf first-dir + mkdir 1 + cd 1 + dotest newb-123e "${testcvs} -q co -r branch first-dir" \ +"U first-dir/a" + + # Remove 'a' on another copy of the branch. + cd .. + mkdir 2 + cd 2 + dotest newb-123f "${testcvs} -q co -r branch first-dir" \ +"U first-dir/a" + cd first-dir + rm a + dotest newb-123g "${testcvs} rm a" \ +"${PROG} [a-z]*: scheduling .a. for removal +${PROG} [a-z]*: use .cvs commit. to remove this file permanently" + dotest newb-123h "${testcvs} -q ci -m removed" \ +'Removing a; +/tmp/cvs-sanity/cvsroot/first-dir/a,v <-- a +new revision: delete; previous revision: 1\.1\.2 +done' + + # Check out the file on the branch. This should report + # that the file is not pertinent, but it should not + # say anything else. + cd .. + rm -rf first-dir + dotest newb-123i "${testcvs} -q co -r branch first-dir/a" \ +"${PROG} [a-z]*: warning: first-dir/a is not (any longer) pertinent" + + # Update the other copy, and make sure that a is removed. + cd ../1/first-dir + # "Needs Patch" is a rather strange output here. Something like + # "Removed in Repository" would make more sense. + dotest newb-123j0 "${testcvs} status a" \ +"=================================================================== +File: a Status: Needs Patch + + Working revision: 1\.1.* + Repository revision: 1\.1\.2\.1 /tmp/cvs-sanity/cvsroot/first-dir/a,v + Sticky Tag: branch (branch: 1\.1\.2) + Sticky Date: (none) + Sticky Options: (none)" + dotest newb-123j "${testcvs} -q update" \ +"${PROG} [a-z]*: warning: a is not (any longer) pertinent" + + if test -f a; then + fail newb-123k + else + pass newb-123k + fi + + cd ../.. + rm -rf 1 2 ; rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + conflicts) - rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir mkdir ${CVSROOT_DIRNAME}/first-dir mkdir 1 cd 1 - if ${CVS} co first-dir ; then - echo 'PASS: test 124' >>${LOGFILE} - else - echo 'FAIL: test 124' | tee -a ${LOGFILE} - fi + dotest conflicts-124 "${testcvs} -q co first-dir" '' cd first-dir touch a - if ${CVS} add a 2>>${LOGFILE} ; then - echo 'PASS: test 125' >>${LOGFILE} - else - echo 'FAIL: test 125' | tee -a ${LOGFILE} - fi - - if ${CVS} ci -m added >>${LOGFILE} 2>&1; then - echo 'PASS: test 126' >>${LOGFILE} - else - echo 'FAIL: test 126' | tee -a ${LOGFILE} - fi + dotest conflicts-125 "${testcvs} add a" \ +"${PROG} [a-z]*: scheduling file .a. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + dotest conflicts-126 "${testcvs} -q ci -m added" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/a,v +done +Checking in a; +/tmp/cvs-sanity/cvsroot/first-dir/a,v <-- a +initial revision: 1\.1 +done' cd ../.. mkdir 2 cd 2 + # TODO-maybe: we could also check this (also in an empty + # directory) after the file has nonempty contents. + # + # The need for TMPPWD here is a (minor) CVS bug; the + # output should use the name of the repository as specified. + dotest conflicts-126.5 "${testcvs} co -p first-dir" \ +"${PROG} [a-z]*"': Updating first-dir +=================================================================== +Checking out first-dir/a +RCS: '"${TMPPWD}"'/cvs-sanity/cvsroot/first-dir/a,v +VERS: 1\.1 +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*' if ${CVS} co first-dir ; then echo 'PASS: test 127' >>${LOGFILE} else @@ -1904,7 +3169,7 @@ rcsmerge: warning: conflicts during merge' dotest conflicts-128 "${testcvs} -q ci -m changed" \ 'Checking in a; /tmp/cvs-sanity/cvsroot/first-dir/a,v <-- a -new revision: 1.2; previous revision: 1.1 +new revision: 1\.2; previous revision: 1\.1 done' cd ../../2/first-dir echo add a conflicting line >>a @@ -1915,9 +3180,9 @@ done' mkdir sdir dotest conflicts-130 "${testcvs} -q update" \ 'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/a,v -retrieving revision 1.1 -retrieving revision 1.2 -Merging differences between 1.1 and 1.2 into a +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into a rcsmerge: warning: conflicts during merge '"${PROG}"' [a-z]*: conflicts found in a C a @@ -1926,12 +3191,13 @@ C a ''"${QUESTION}"' dir1 '"${QUESTION}"' sdir RCS file: /tmp/cvs-sanity/cvsroot/first-dir/a,v -retrieving revision 1.1 -retrieving revision 1.2 -Merging differences between 1.1 and 1.2 into a +retrieving revision 1\.1 +retrieving revision 1\.2 +Merging differences between 1\.1 and 1\.2 into a rcsmerge: warning: conflicts during merge '"${PROG}"' [a-z]*: conflicts found in a C a' + rmdir dir1 sdir # Try to check in the file with the conflict markers in it. if ${CVS} ci -m try 2>>${LOGFILE}; then @@ -1972,6 +3238,7 @@ C a' echo 'FAIL: test 135' | tee -a ${LOGFILE} fi cd ../../2 + mkdir first-dir/dir1 first-dir/sdir dotest conflicts-136 "${testcvs} -q update" \ '[UP] first-dir/abc '"${QUESTION}"' first-dir/dir1 @@ -2024,10 +3291,130 @@ C a' else echo 'FAIL: test 142' | tee -a ${LOGFILE} fi - - cd ../.. + cd ../.. rm -rf 1 2 3 ; rm -rf ${CVSROOT_DIRNAME}/first-dir ;; + + conflicts2) + # More conflicts tests; separate from conflicts to keep each + # test a manageable size. + mkdir ${CVSROOT_DIRNAME}/first-dir + + mkdir 1 + cd 1 + + dotest conflicts2-142a1 "${testcvs} -q co first-dir" '' + + cd first-dir + touch a abc + + dotest conflicts2-142a2 "${testcvs} add a abc" \ +"${PROG} [a-z]*: scheduling file .a. for addition +${PROG} [a-z]*: scheduling file .abc. for addition +${PROG} [a-z]*: use .cvs commit. to add these files permanently" + dotest conflicts2-142a3 "${testcvs} -q ci -m added" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/a,v +done +Checking in a; +/tmp/cvs-sanity/cvsroot/first-dir/a,v <-- a +initial revision: 1\.1 +done +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/abc,v +done +Checking in abc; +/tmp/cvs-sanity/cvsroot/first-dir/abc,v <-- abc +initial revision: 1\.1 +done' + + cd ../.. + mkdir 2 + cd 2 + + dotest conflicts2-142a4 "${testcvs} -q co first-dir" 'U first-dir/a +U first-dir/abc' + cd .. + + # Now test that if one person modifies and commits a + # file and a second person removes it, it is a + # conflict + cd 1/first-dir + echo modify a >>a + dotest conflicts2-142b2 "${testcvs} -q ci -m modify-a" \ +'Checking in a; +/tmp/cvs-sanity/cvsroot/first-dir/a,v <-- a +new revision: 1\.2; previous revision: 1\.1 +done' + cd ../../2/first-dir + rm a + dotest conflicts2-142b3 "${testcvs} rm a" \ +"${PROG} [a-z]*: scheduling .a. for removal +${PROG} [a-z]*: use .cvs commit. to remove this file permanently" + dotest_fail conflicts2-142b4 "${testcvs} -q update" \ +"${PROG} [a-z]*: conflict: removed a was modified by second party +C a" + # Resolve the conflict by deciding not to remove the file + # after all. + dotest conflicts2-142b5 "${testcvs} add a" "U a +${PROG} [a-z]*: a, version 1\.1, resurrected" + dotest conflicts2-142b6 "${testcvs} -q update" '' + cd ../.. + + # Now test that if one person removes a file and + # commits it, and a second person removes it, is it + # not a conflict. + cd 1/first-dir + rm abc + dotest conflicts2-142c0 "${testcvs} rm abc" \ +"${PROG} [a-z]*: scheduling .abc. for removal +${PROG} [a-z]*: use .cvs commit. to remove this file permanently" + dotest conflicts2-142c1 "${testcvs} -q ci -m remove-abc" \ +'Removing abc; +/tmp/cvs-sanity/cvsroot/first-dir/abc,v <-- abc +new revision: delete; previous revision: 1\.1 +done' + cd ../../2/first-dir + rm abc + dotest conflicts2-142c2 "${testcvs} rm abc" \ +"${PROG} [a-z]*: scheduling .abc. for removal +${PROG} [a-z]*: use .cvs commit. to remove this file permanently" + dotest conflicts2-142c3 "${testcvs} update" \ +"${PROG} [a-z]*: Updating \." + cd ../.. + + # conflicts2-142d*: test that if one party adds a file, and another + # party has a file of the same name, cvs notices + cd 1/first-dir + touch aa.c + dotest conflicts2-142d0 "${testcvs} add aa.c" \ +"${PROG} [a-z]*: scheduling file .aa\.c. for addition +${PROG} [a-z]*: use .cvs commit. to add this file permanently" + dotest conflicts2-142d1 "${testcvs} -q ci -m added" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/aa.c,v +done +Checking in aa.c; +/tmp/cvs-sanity/cvsroot/first-dir/aa.c,v <-- aa.c +initial revision: 1\.1 +done' + cd ../../2/first-dir + echo "don't you dare obliterate this text" >aa.c + # Doing this test separately for remote and local is a fair + # bit of a kludge, but the exit status differs. I'm not sure + # which exit status is the more appropriate one. + if test "$remote" = yes; then + dotest conflicts2-142d2 "${testcvs} -q update" \ +"${QUESTION} aa\.c +U aa\.c +${PROG} update: move away \./aa\.c; it is in the way" + else + dotest_fail conflicts2-142d2 "${testcvs} -q update" \ +"${PROG} [a-z]*: move away aa\.c; it is in the way +C aa\.c" + fi + cd ../.. + + rm -rf 1 2 ; rm -rf ${CVSROOT_DIRNAME}/first-dir + ;; + modules) rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir mkdir ${CVSROOT_DIRNAME}/first-dir @@ -2090,6 +3477,8 @@ C a' echo namedmodule -d nameddir first-dir/subdir >>CVSROOT/modules echo aliasmodule -a first-dir/subdir/a >>CVSROOT/modules echo aliasnested -a first-dir/subdir/ssdir >>CVSROOT/modules + echo topfiles -a first-dir/file1 first-dir/file2 >>CVSROOT/modules + echo world -a . >>CVSROOT/modules # Options must come before arguments. It is possible this should # be relaxed at some point (though the result would be bizarre for @@ -2109,7 +3498,9 @@ aliasnested -a first-dir/subdir/ssdir bogusalias first-dir/subdir/a -a dirmodule first-dir/subdir namedmodule -d nameddir first-dir/subdir -realmodule first-dir/subdir a' +realmodule first-dir/subdir a +topfiles -a first-dir/file1 first-dir/file2 +world -a .' # I don't know why aliasmodule isn't printed (I would have thought # that it gets printed without the -a; although I'm not sure that # printing expansions without options is useful). @@ -2258,10 +3649,59 @@ U nameddir/b' dotest modules-155a2 "test -d first-dir/subdir" '' dotest modules-155a3 "test -d first-dir/subdir/ssdir" '' # Test that nothing extraneous got created. - dotest modules-155a4 "ls -1" "first-dir" + dotest modules-155a4 "ls" "first-dir" cd .. rm -rf 2 + # Test checking out everything. + mkdir 1 + cd 1 + dotest modules-155b "${testcvs} -q co world" \ +"U CVSROOT/modules +U first-dir/subdir/a +U first-dir/subdir/b" + cd .. + rm -rf 1 + + # Test checking out a module which lists at least two + # specific files twice. At one time, this failed over + # remote CVS. + mkdir 1 + cd 1 + dotest modules-155c1 "${testcvs} -q co first-dir" \ +"U first-dir/subdir/a +U first-dir/subdir/b" + + cd first-dir + echo 'first revision' > file1 + echo 'first revision' > file2 + dotest modules-155c2 "${testcvs} add file1 file2" \ +"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition +'"${PROG}"' [a-z]*: scheduling file `file2'\'' for addition +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add these files permanently' + dotest modules-155c3 "${testcvs} -q ci -m add-it" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v +done +Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file2,v +done +Checking in file2; +/tmp/cvs-sanity/cvsroot/first-dir/file2,v <-- file2 +initial revision: 1\.1 +done' + + cd .. + rm -rf first-dir + dotest modules-155c4 "${testcvs} -q co topfiles" \ +"U first-dir/file1 +U first-dir/file2" + dotest modules-155c5 "${testcvs} -q co topfiles" "" + cd .. + rm -rf 1 + rm -rf ${CVSROOT_DIRNAME}/first-dir ;; mflag) @@ -2355,7 +3795,7 @@ U nameddir/b' fi chmod a-w 1dir cd ../1/1dir - rm foo; + rm foo; if ${testcvs} rm foo >>${LOGFILE} 2>&1; then echo 'PASS: test 166' >>${LOGFILE} else @@ -2564,8 +4004,26 @@ abc [a-z0-9]* edit unedit commit' dotest devcom-a4 "${testcvs} watchers abb" \ 'abb [a-z0-9]* edit commit' + # Check tagging and checking out while we have a CVS + # directory in the repository. + dotest devcom-t0 "${testcvs} -q tag tag" \ +'T abb +T abc' cd ../.. - rm -rf 1 2 ${CVSROOT_DIRNAME}/first-dir + mkdir 3 + cd 3 + dotest devcom-t1 "${testcvs} -q co -rtag first-dir/abb" \ +'U first-dir/abb' + + # Now remove all the file attributes + cd ../2/first-dir + dotest devcom-b0 "${testcvs} watch off" '' + dotest devcom-b1 "${testcvs} watch remove" '' + # Test that CVS 1.6 and earlier can handle the repository. + dotest_fail devcom-b2 "test -d ${CVSROOT_DIRNAME}/first-dir/CVS" + + cd ../.. + rm -rf 1 2 3 ${CVSROOT_DIRNAME}/first-dir ;; ignore) @@ -2582,7 +4040,7 @@ abc [a-z0-9]* edit unedit commit' done Checking in cvsignore; /tmp/cvs-sanity/cvsroot/CVSROOT/cvsignore,v <-- cvsignore -initial revision: 1.1 +initial revision: 1\.1 done '"${PROG}"' [a-z]*: Rebuilding administrative file database' @@ -2638,7 +4096,6 @@ U second-dir/envig.c U second-dir/foobar.c U second-dir/optig.c U second-dir/rootig.c' - rm -rf second-dir dotest 189b "${testcvs} -q co first-dir" 'U first-dir/bar.c U first-dir/foobar.c' cd first-dir @@ -2651,9 +4108,57 @@ ${QUESTION} defig.o ${QUESTION} envig.c ${QUESTION} optig.c ${QUESTION} notig.c" - cd .. - rm -rf first-dir + # Now test that commands other than update also print "? notig.c" + # where appropriate. Only test this for remote, because local + # CVS only prints it on update. + rm optig.c + if test "x$remote" = xyes; then + dotest 189e "${testcvs} -q diff" "${QUESTION} notig.c" + + # Force the server to be contacted. Ugh. Having CVS + # contact the server for the sole purpose of checking + # the CVSROOT/cvsignore file does not seem like such a + # good idea, so I imagine this will continue to be + # necessary. Oh well, at least we test CVS's ablity to + # handle a file with a modified timestamp but unmodified + # contents. + touch bar.c + + dotest 189f "${testcvs} -q ci -m commit-it" "${QUESTION} notig.c" + fi + + # now test .cvsignore files + cd .. + echo notig.c >first-dir/.cvsignore + echo foobar.c >second-dir/.cvsignore + touch first-dir/notig.c second-dir/notig.c second-dir/foobar.c + dotest 190 "${testcvs} -qn update" \ +"${QUESTION} first-dir/.cvsignore +${QUESTION} second-dir/.cvsignore +${QUESTION} second-dir/notig.c" \ +"${QUESTION} first-dir/.cvsignore +${QUESTION} second-dir/notig.c +${QUESTION} second-dir/.cvsignore" + dotest 191 "${testcvs} -qn update -I!" \ +"${QUESTION} first-dir/CVS +${QUESTION} first-dir/rootig.c +${QUESTION} first-dir/defig.o +${QUESTION} first-dir/envig.c +${QUESTION} first-dir/.cvsignore +${QUESTION} second-dir/CVS +${QUESTION} second-dir/.cvsignore +${QUESTION} second-dir/notig.c" \ +"${QUESTION} first-dir/CVS +${QUESTION} first-dir/rootig.c +${QUESTION} first-dir/defig.o +${QUESTION} first-dir/envig.c +${QUESTION} first-dir/.cvsignore +${QUESTION} second-dir/CVS +${QUESTION} second-dir/notig.c +${QUESTION} second-dir/.cvsignore" + + rm -rf first-dir second-dir rm -rf ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/second-dir ;; @@ -2675,7 +4180,7 @@ ${QUESTION} notig.c" done Checking in binfile; /tmp/cvs-sanity/cvsroot/first-dir/binfile,v <-- binfile -initial revision: 1.1 +initial revision: 1\.1 done' cd ../.. mkdir 2; cd 2 @@ -2694,16 +4199,65 @@ File: binfile Status: Up-to-date Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb' + + # Test whether the default options from the RCS file are + # also used when operating on files instead of whole + # directories + cd ../.. + mkdir 3; cd 3 + dotest binfiles-5.5b0 "${testcvs} -q co first-dir/binfile" \ +'U first-dir/binfile' + cd first-dir + dotest binfiles-5.5b1 "${testcvs} status binfile" \ +'=================================================================== +File: binfile Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 /tmp/cvs-sanity/cvsroot/first-dir/binfile,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb' + cd ../.. + rm -rf 3 + cd 2/first-dir + cp ../../1/binfile2.dat binfile dotest binfiles-6 "${testcvs} -q ci -m modify-it" \ 'Checking in binfile; /tmp/cvs-sanity/cvsroot/first-dir/binfile,v <-- binfile -new revision: 1.2; previous revision: 1.1 +new revision: 1\.2; previous revision: 1\.1 done' cd ../../1/first-dir dotest binfiles-7 "${testcvs} -q update" '[UP] binfile' dotest binfiles-8 "cmp ../binfile2.dat binfile" '' + # Now test handling of conflicts with binary files. + cp ../binfile.dat binfile + dotest binfiles-con0 "${testcvs} -q ci -m modify-it" \ +'Checking in binfile; +/tmp/cvs-sanity/cvsroot/first-dir/binfile,v <-- binfile +new revision: 1\.3; previous revision: 1\.2 +done' + cd ../../2/first-dir + echo 'edits in dir 2' >binfile + dotest binfiles-con1 "${testcvs} -q update" \ +'U binfile +cvs [a-z]*: binary file needs merge +cvs [a-z]*: revision 1\.3 from repository is now in binfile +cvs [a-z]*: file from working directory is now in \.#binfile\.1\.2 +C binfile' + dotest binfiles-con2 "cmp binfile ../../1/binfile.dat" '' + dotest binfiles-con3 "cat .#binfile.1.2" 'edits in dir 2' + + cp ../../1/binfile2.dat binfile + dotest binfiles-con4 "${testcvs} -q ci -m resolve-it" \ +'Checking in binfile; +/tmp/cvs-sanity/cvsroot/first-dir/binfile,v <-- binfile +new revision: 1\.4; previous revision: 1\.3 +done' + cd ../../1/first-dir + dotest binfiles-con5 "${testcvs} -q update" '[UP] binfile' + # The bugs which these test for are apparently not fixed for remote. if test "$remote" = no; then dotest binfiles-9 "${testcvs} -q update -A" '' @@ -2713,12 +4267,32 @@ done' dotest binfiles-13 "${testcvs} -q update -A" '' fi - cd ../../2/first-dir + cd ../.. + rm -rf 1 + + mkdir 3 + cd 3 + dotest binfiles-13a0 "${testcvs} -q co -r HEAD first-dir" \ +'U first-dir/binfile' + cd first-dir + dotest binfiles-13a1 "${testcvs} status binfile" \ +'=================================================================== +File: binfile Status: Up-to-date + + Working revision: 1\.4.* + Repository revision: 1\.4 /tmp/cvs-sanity/cvsroot/first-dir/binfile,v + Sticky Tag: HEAD (revision: 1\.4) + Sticky Date: (none) + Sticky Options: -kb' + cd ../.. + rm -rf 3 + + cd 2/first-dir echo 'this file is $''RCSfile$' >binfile dotest binfiles-14a "${testcvs} -q ci -m modify-it" \ 'Checking in binfile; /tmp/cvs-sanity/cvsroot/first-dir/binfile,v <-- binfile -new revision: 1.3; previous revision: 1.2 +new revision: 1\.5; previous revision: 1\.4 done' dotest binfiles-14b "cat binfile" 'this file is $''RCSfile$' # See binfiles-5.5 for discussion of -kb. @@ -2726,8 +4300,8 @@ done' '=================================================================== File: binfile Status: Up-to-date - Working revision: 1\.3.* - Repository revision: 1\.3 /tmp/cvs-sanity/cvsroot/first-dir/binfile,v + Working revision: 1\.5.* + Repository revision: 1\.5 /tmp/cvs-sanity/cvsroot/first-dir/binfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb' @@ -2743,8 +4317,8 @@ done' '=================================================================== File: binfile Status: Up-to-date - Working revision: 1\.3.* - Repository revision: 1\.3 /tmp/cvs-sanity/cvsroot/first-dir/binfile,v + Working revision: 1\.5.* + Repository revision: 1\.5 /tmp/cvs-sanity/cvsroot/first-dir/binfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kb' @@ -2754,16 +4328,80 @@ File: binfile Status: Up-to-date '=================================================================== File: binfile Status: Up-to-date - Working revision: 1\.3.* - Repository revision: 1\.3 /tmp/cvs-sanity/cvsroot/first-dir/binfile,v + Working revision: 1\.5.* + Repository revision: 1\.5 /tmp/cvs-sanity/cvsroot/first-dir/binfile,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: -kv' + # Do sticky options work when used with 'cvs update'? + echo "Not a binary file." > nibfile + dotest binfiles-sticky1 "${testcvs} -q add nibfile" \ + 'cvs [a-z]*: use '\''cvs commit'\'' to add this file permanently' + dotest binfiles-sticky2 "${testcvs} -q ci -m add-it nibfile" \ + 'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/nibfile,v +done +Checking in nibfile; +/tmp/cvs-sanity/cvsroot/first-dir/nibfile,v <-- nibfile +initial revision: 1\.1 +done' + dotest binfiles-sticky3 "${testcvs} -q update -kb nibfile" \ + '[UP] nibfile' + dotest binfiles-sticky4 "${testcvs} -q status nibfile" \ +'=================================================================== +File: nibfile Status: Up-to-date + + Working revision: 1\.1.* + Repository revision: 1\.1 /tmp/cvs-sanity/cvsroot/first-dir/nibfile,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb' + # Eventually we should test that -A removes the -kb here... + cd ../.. rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r 1 2 + rm -r 2 + ;; + + binwrap) + # Test the ability to specify binary-ness based on file name. + # We could also be testing the ability to use the other + # ways to specify a wrapper (CVSROOT/cvswrappers, etc.). + + mkdir dir-to-import + cd dir-to-import + touch foo.c foo.exe + if ${testcvs} import -m message -I ! -W "*.exe -k 'b'" \ + first-dir tag1 tag2 >>${LOGFILE}; then + pass binwrap-1 + else + fail binwrap-1 + fi + cd .. + rm -rf dir-to-import + dotest binwrap-2 "${testcvs} -q co first-dir" 'U first-dir/foo.c +U first-dir/foo.exe' + dotest binwrap-3 "${testcvs} -q status first-dir" \ +'=================================================================== +File: foo\.c Status: Up-to-date + + Working revision: 1\.1\.1\.1.* + Repository revision: 1\.1\.1\.1 /tmp/cvs-sanity/cvsroot/first-dir/foo\.c,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: (none) + +=================================================================== +File: foo\.exe Status: Up-to-date + + Working revision: 1\.1\.1\.1.* + Repository revision: 1\.1\.1\.1 /tmp/cvs-sanity/cvsroot/first-dir/foo\.exe,v + Sticky Tag: (none) + Sticky Date: (none) + Sticky Options: -kb' + rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir ;; + info) # Test CVS's ability to handle *info files. dotest info-1 "${testcvs} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" @@ -2777,7 +4415,7 @@ File: binfile Status: Up-to-date done Checking in loginfo; /tmp/cvs-sanity/cvsroot/CVSROOT/loginfo,v <-- loginfo -initial revision: 1.1 +initial revision: 1\.1 done '"${PROG}"' [a-z]*: Rebuilding administrative file database' cd .. @@ -2800,14 +4438,14 @@ done done Checking in file1; /tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 -initial revision: 1.1 +initial revision: 1\.1 done '"${PROG}"' [a-z]*: loginfo:1: no such user variable ${=ZEE}' echo line1 >>file1 dotest info-7 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \ 'Checking in file1; /tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 -new revision: 1.2; previous revision: 1.1 +new revision: 1\.2; previous revision: 1\.1 done' cd .. if echo "yes" | ${testcvs} release -d first-dir >>${LOGFILE} ; then @@ -2815,7 +4453,7 @@ done' else fail info-8 fi - dotest info-9 "cat $TESTDIR/testlog" 'xenv-valueyz=[a-z@][a-z@]*=/tmp/cvs-sanity/cvsroot=' + dotest info-9 "cat $TESTDIR/testlog" 'xenv-valueyz=[a-z0-9@][a-z0-9@]*=/tmp/cvs-sanity/cvsroot=' # I think this might be doable with cvs remove, or at least # checking in a version with only comments, but I'm too lazy @@ -2824,6 +4462,290 @@ done' rm -rf ${CVSROOT_DIRNAME}/first-dir ;; + + serverpatch) + # Test remote CVS handling of unpatchable files. This isn't + # much of a test for local CVS. + mkdir ${CVSROOT_DIRNAME}/first-dir + mkdir 1 + cd 1 + dotest serverpatch-1 "${testcvs} -q co first-dir" '' + + cd first-dir + + # Add a file with an RCS keyword. + echo '$''Name$' > file1 + echo '1' >> file1 + dotest serverpatch-2 "${testcvs} add file1" \ +"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently' + + dotest serverpatch-3 "${testcvs} -q commit -m add" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v +done +Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done' + + # Tag the file. + dotest serverpatch-4 "${testcvs} -q tag tag file1" 'T file1' + + # Check out a tagged copy of the file. + cd ../.. + mkdir 2 + cd 2 + dotest serverpatch-5 "${testcvs} -q co -r tag first-dir" \ +'U first-dir/file1' + + # Remove the tag. This will leave the tag string in the + # expansion of the Name keyword. + dotest serverpatch-6 "${testcvs} -q update -A" '' + + # Modify and check in the first copy. + cd ../1/first-dir + echo '2' >> file1 + dotest serverpatch-7 "${testcvs} -q ci -mx file1" \ +'Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +done' + + # Now update the second copy. When using remote CVS, the + # patch will fail, forcing the file to be refetched. + cd ../../2/first-dir + dotest serverpatch-8 "${testcvs} -q update" \ +'U file1' \ +'P file1 +'"${PROG}"' [a-z]*: checksum failure after patch to ./file1; will refetch +'"${PROG}"' [a-z]*: refetching unpatchable files +U file1' + + cd ../.. + rm -rf 1 2 ${CVSROOT_DIRNAME}/first-dir + ;; + + log) + # Test selecting revisions with cvs log. + + # Check in a file with a few revisions and branches. + mkdir ${CVSROOT_DIRNAME}/first-dir + dotest log-1 "${testcvs} -q co first-dir" '' + cd first-dir + echo 'first revision' > file1 + dotest log-2 "${testcvs} add file1" \ +"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition +'"${PROG}"' [a-z]*: use '\''cvs commit'\'' to add this file permanently' + + dotest log-3 "${testcvs} -q commit -m 1" \ +'RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v +done +Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +initial revision: 1\.1 +done' + + echo 'second revision' > file1 + dotest log-4 "${testcvs} -q ci -m2 file1" \ +'Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.2; previous revision: 1\.1 +done' + + dotest log-5 "${testcvs} -q tag -b branch file1" 'T file1' + + echo 'third revision' > file1 + dotest log-6 "${testcvs} -q ci -m3 file1" \ +'Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.3; previous revision: 1\.2 +done' + + dotest log-7 "${testcvs} -q update -r branch" '[UP] file1' + + echo 'first branch revision' > file1 + dotest log-8 "${testcvs} -q ci -m1b file1" \ +'Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.2\.2\.1; previous revision: 1\.2 +done' + + dotest log-9 "${testcvs} -q tag tag file1" 'T file1' + + echo 'second branch revision' > file1 + dotest log-10 "${testcvs} -q ci -m2b file1" \ +'Checking in file1; +/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 +new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1 +done' + + # Set up a bunch of shell variables to make the later tests + # easier to describe.= + log_header=' +RCS file: /tmp/cvs-sanity/cvsroot/first-dir/file1,v +Working file: file1 +head: 1\.3 +branch: +locks: strict +access list:' + log_tags='symbolic names: + tag: 1\.2\.2\.1 + branch: 1\.2\.0\.2' + log_header2='keyword substitution: kv' + log_dash='---------------------------- +revision' + log_date='date: [0-9/]* [0-9:]*; author: [a-zA-Z0-9@]*; state: Exp;' + log_lines=" lines: ${PLUS}1 -1" + log_rev1="${log_dash} 1\.1 +${log_date} +1" + log_rev2="${log_dash} 1\.2 +${log_date}${log_lines} +branches: 1\.2\.2; +2" + log_rev3="${log_dash} 1\.3 +${log_date}${log_lines} +3" + log_rev1b="${log_dash} 1\.2\.2\.1 +${log_date}${log_lines} +1b" + log_rev2b="${log_dash} 1\.2\.2\.2 +${log_date}${log_lines} +2b" + log_trailer='=============================================================================' + + # Now, finally, test the log output. + + dotest log-11 "${testcvs} log file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 5 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-12 "${testcvs} log -N file1" \ +"${log_header} +${log_header2} +total revisions: 5; selected revisions: 5 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-13 "${testcvs} log -b file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 3 +description: +${log_rev3} +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-14 "${testcvs} log -r file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev3} +${log_trailer}" + + dotest log-15 "${testcvs} log -r1.2 file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev2} +${log_trailer}" + + dotest log-16 "${testcvs} log -r1.2.2 file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + + # This test would fail with the old invocation of rlog, but it + # works with the builtin log support. + dotest log-17 "${testcvs} log -rbranch file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev2b} +${log_rev1b} +${log_trailer}" + + dotest log-18 "${testcvs} log -r1.2.2. file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev2b} +${log_trailer}" + + # This test would fail with the old invocation of rlog, but it + # works with the builtin log support. + dotest log-19 "${testcvs} log -rbranch. file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 1 +description: +${log_rev2b} +${log_trailer}" + + dotest log-20 "${testcvs} log -r1.2: file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev3} +${log_rev2} +${log_trailer}" + + dotest log-21 "${testcvs} log -r:1.2 file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev2} +${log_rev1} +${log_trailer}" + + dotest log-22 "${testcvs} log -r1.1:1.2 file1" \ +"${log_header} +${log_tags} +${log_header2} +total revisions: 5; selected revisions: 2 +description: +${log_rev2} +${log_rev1} +${log_trailer}" + + cd .. + rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir + ;; + *) echo $what is not the name of a test -- ignored ;; @@ -2833,6 +4755,7 @@ done echo "OK, all tests completed." # TODO: +# * use "test" not "[" and see if all test's support `-z' # * Test `cvs admin'. # * Test `cvs update -d foo' (where foo does not exist). # * Test `cvs update foo bar' (where foo and bar are both from the same @@ -2844,7 +4767,7 @@ echo "OK, all tests completed." # Test that ciprog gets run both on checkin in that directory, or a # higher-level checkin which recurses into it. # * Test that $ followed by "Header" followed by $ gets expanded on checkin. -# * Test operations on a directory that contains other directories but has +# * Test operations on a directory that contains other directories but has # no files of its own. # * -t global option # * cvs rm followed by cvs add or vice versa (with no checkin in between). @@ -2852,7 +4775,7 @@ echo "OK, all tests completed." # * -P option to checkout--(a) refrains from checking out new empty dirs, # (b) prunes empty dirs already there. # * Test that cvs -d `hostname`:/tmp/cvs-sanity/non/existent co foo -# gives an appropriate error (e.g. +# gives an appropriate error (e.g. # Cannot access /tmp/cvs-sanity/non-existent/CVSROOT # No such file or directory). # * Test ability to send notifications in response to watches. (currently @@ -2860,6 +4783,7 @@ echo "OK, all tests completed." # same). # * Test that remote edit and/or unedit works when disconnected from # server (e.g. set CVS_SERVER to "foobar"). +# * Test things to do with the CVS/* files, esp. CVS/Root.... # End of TODO list. # Remove the test directory, but first change out of it. diff --git a/gnu/usr.bin/cvs/src/status.c b/gnu/usr.bin/cvs/src/status.c index 277da0c2944..203e0aae84d 100644 --- a/gnu/usr.bin/cvs/src/status.c +++ b/gnu/usr.bin/cvs/src/status.c @@ -10,8 +10,10 @@ #include "cvs.h" -static Dtype status_dirproc PROTO((char *dir, char *repos, char *update_dir)); -static int status_fileproc PROTO((struct file_info *finfo)); +static Dtype status_dirproc PROTO ((void *callerdat, char *dir, + char *repos, char *update_dir, + List *entries)); +static int status_fileproc PROTO ((void *callerdat, struct file_info *finfo)); static int tag_list_proc PROTO((Node * p, void *closure)); static int local = 0; @@ -87,9 +89,10 @@ status (argc, argv) #endif /* start the recursion processor */ - err = start_recursion (status_fileproc, (FILESDONEPROC) NULL, status_dirproc, - (DIRLEAVEPROC) NULL, argc, argv, local, - W_LOCAL, 0, 1, (char *) NULL, 1, 0); + err = start_recursion (status_fileproc, (FILESDONEPROC) NULL, + status_dirproc, (DIRLEAVEPROC) NULL, NULL, + argc, argv, local, + W_LOCAL, 0, 1, (char *) NULL, 1); return (err); } @@ -99,16 +102,17 @@ status (argc, argv) */ /* ARGSUSED */ static int -status_fileproc (finfo) +status_fileproc (callerdat, finfo) + void *callerdat; struct file_info *finfo; { Ctype status; char *sstat; Vers_TS *vers; - status = Classify_File (finfo->file, (char *) NULL, (char *) NULL, (char *) NULL, - 1, 0, finfo->repository, finfo->entries, finfo->rcs, &vers, - finfo->update_dir, 0); + status = Classify_File (finfo, (char *) NULL, (char *) NULL, (char *) NULL, + 1, 0, &vers, 0); + sstat = "Classify Error"; switch (status) { case T_UNKNOWN: @@ -146,34 +150,66 @@ status_fileproc (finfo) case T_NEEDS_MERGE: sstat = "Needs Merge"; break; - default: - sstat = "Classify Error"; + case T_TITLE: + /* I don't think this case can occur here. Just print + "Classify Error". */ break; } - (void) printf ("===================================================================\n"); + cvs_output ("\ +===================================================================\n", 0); if (vers->ts_user == NULL) - (void) printf ("File: no file %s\t\tStatus: %s\n\n", finfo->file, sstat); + { + cvs_output ("File: no file ", 0); + cvs_output (finfo->file, 0); + cvs_output ("\t\tStatus: ", 0); + cvs_output (sstat, 0); + cvs_output ("\n\n", 0); + } else - (void) printf ("File: %-17s\tStatus: %s\n\n", finfo->file, sstat); + { + char *buf; + buf = xmalloc (strlen (finfo->file) + strlen (sstat) + 80); + sprintf (buf, "File: %-17s\tStatus: %s\n\n", finfo->file, sstat); + cvs_output (buf, 0); + free (buf); + } if (vers->vn_user == NULL) - (void) printf (" Working revision:\tNo entry for %s\n", finfo->file); + { + cvs_output (" Working revision:\tNo entry for ", 0); + cvs_output (finfo->file, 0); + cvs_output ("\n", 0); + } else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0') - (void) printf (" Working revision:\tNew file!\n"); + cvs_output (" Working revision:\tNew file!\n", 0); #ifdef SERVER_SUPPORT else if (server_active) - (void) printf (" Working revision:\t%s\n", vers->vn_user); + { + cvs_output (" Working revision:\t", 0); + cvs_output (vers->vn_user, 0); + cvs_output ("\n", 0); + } #endif else - (void) printf (" Working revision:\t%s\t%s\n", vers->vn_user, - vers->ts_rcs); + { + cvs_output (" Working revision:\t", 0); + cvs_output (vers->vn_user, 0); + cvs_output ("\t", 0); + cvs_output (vers->ts_rcs, 0); + cvs_output ("\n", 0); + } if (vers->vn_rcs == NULL) - (void) printf (" Repository revision:\tNo revision control file\n"); + cvs_output (" Repository revision:\tNo revision control file\n", 0); else - (void) printf (" Repository revision:\t%s\t%s\n", vers->vn_rcs, - vers->srcfile->path); + { + cvs_output (" Repository revision:\t", 0); + cvs_output (vers->vn_rcs, 0); + cvs_output ("\t", 0); + cvs_output (vers->srcfile->path, 0); + cvs_output ("\n", 0); + } if (vers->entdata) { @@ -183,24 +219,33 @@ status_fileproc (finfo) if (edata->tag) { if (vers->vn_rcs == NULL) - (void) printf ( - " Sticky Tag:\t\t%s - MISSING from RCS file!\n", - edata->tag); + { + cvs_output (" Sticky Tag:\t\t", 0); + cvs_output (edata->tag, 0); + cvs_output (" - MISSING from RCS file!\n", 0); + } else { if (isdigit (edata->tag[0])) - (void) printf (" Sticky Tag:\t\t%s\n", edata->tag); + { + cvs_output (" Sticky Tag:\t\t", 0); + cvs_output (edata->tag, 0); + cvs_output ("\n", 0); + } else { char *branch = NULL; - + if (RCS_isbranch (finfo->rcs, edata->tag)) branch = RCS_whatbranch(finfo->rcs, edata->tag); - (void) printf (" Sticky Tag:\t\t%s (%s: %s)\n", - edata->tag, - branch ? "branch" : "revision", - branch ? branch : vers->vn_rcs); + cvs_output (" Sticky Tag:\t\t", 0); + cvs_output (edata->tag, 0); + cvs_output (" (", 0); + cvs_output (branch ? "branch" : "revision", 0); + cvs_output (": ", 0); + cvs_output (branch ? branch : vers->vn_rcs, 0); + cvs_output (")\n", 0); if (branch) free (branch); @@ -208,34 +253,42 @@ status_fileproc (finfo) } } else if (!really_quiet) - (void) printf (" Sticky Tag:\t\t(none)\n"); + cvs_output (" Sticky Tag:\t\t(none)\n", 0); if (edata->date) - (void) printf (" Sticky Date:\t\t%s\n", edata->date); + { + cvs_output (" Sticky Date:\t\t", 0); + cvs_output (edata->date, 0); + cvs_output ("\n", 0); + } else if (!really_quiet) - (void) printf (" Sticky Date:\t\t(none)\n"); + cvs_output (" Sticky Date:\t\t(none)\n", 0); if (edata->options && edata->options[0]) - (void) printf (" Sticky Options:\t%s\n", edata->options); + { + cvs_output (" Sticky Options:\t", 0); + cvs_output (edata->options, 0); + cvs_output ("\n", 0); + } else if (!really_quiet) - (void) printf (" Sticky Options:\t(none)\n"); + cvs_output (" Sticky Options:\t(none)\n", 0); if (long_format && vers->srcfile) { List *symbols = RCS_symbols(vers->srcfile); - (void) printf ("\n Existing Tags:\n"); + cvs_output ("\n Existing Tags:\n", 0); if (symbols) { xrcsnode = finfo->rcs; (void) walklist (symbols, tag_list_proc, NULL); } else - (void) printf ("\tNo Tags Exist\n"); + cvs_output ("\tNo Tags Exist\n", 0); } } - (void) printf ("\n"); + cvs_output ("\n", 0); freevers_ts (&vers); return (0); } @@ -245,10 +298,12 @@ status_fileproc (finfo) */ /* ARGSUSED */ static Dtype -status_dirproc (dir, repos, update_dir) +status_dirproc (callerdat, dir, repos, update_dir, entries) + void *callerdat; char *dir; char *repos; char *update_dir; + List *entries; { if (!quiet) error (0, 0, "Examining %s", update_dir); @@ -264,13 +319,18 @@ tag_list_proc (p, closure) void *closure; { char *branch = NULL; + char *buf; if (RCS_isbranch (xrcsnode, p->key)) branch = RCS_whatbranch(xrcsnode, p->key) ; - (void) printf ("\t%-25.25s\t(%s: %s)\n", p->key, - branch ? "branch" : "revision", - branch ? branch : p->data); + buf = xmalloc (80 + strlen (p->key) + + (branch ? strlen (branch) : strlen (p->data))); + sprintf (buf, "\t%-25.25s\t(%s: %s)\n", p->key, + branch ? "branch" : "revision", + branch ? branch : p->data); + cvs_output (buf, 0); + free (buf); if (branch) free (branch); diff --git a/gnu/usr.bin/cvs/src/tag.c b/gnu/usr.bin/cvs/src/tag.c index 2e3000945de..312c8820b6c 100644 --- a/gnu/usr.bin/cvs/src/tag.c +++ b/gnu/usr.bin/cvs/src/tag.c @@ -14,15 +14,22 @@ #include "cvs.h" #include "savecwd.h" -static int check_fileproc PROTO((struct file_info *finfo)); -static int check_filesdoneproc PROTO((int err, char *repos, char *update_dir)); +static int check_fileproc PROTO ((void *callerdat, struct file_info *finfo)); +static int check_filesdoneproc PROTO ((void *callerdat, int err, + char *repos, char *update_dir, + List *entries)); static int pretag_proc PROTO((char *repository, char *filter)); static void masterlist_delproc PROTO((Node *p)); static void tag_delproc PROTO((Node *p)); static int pretag_list_proc PROTO((Node *p, void *closure)); -static Dtype tag_dirproc PROTO((char *dir, char *repos, char *update_dir)); -static int tag_fileproc PROTO((struct file_info *finfo)); +static Dtype tag_dirproc PROTO ((void *callerdat, char *dir, + char *repos, char *update_dir, + List *entries)); +static int tag_fileproc PROTO ((void *callerdat, struct file_info *finfo)); +static int tag_filesdoneproc PROTO ((void *callerdat, int err, + char *repos, char *update_dir, + List *entries)); static char *numtag; static char *date = NULL; @@ -32,6 +39,7 @@ static int branch_mode; /* make an automagic "branch" tag */ static int local; /* recursive by default */ static int force_tag_match = 1; /* force tag to match by default */ static int force_tag_move; /* don't force tag to move by default */ +static int check_uptodate; /* no uptodate-check by default */ struct tag_info { @@ -51,14 +59,15 @@ static List *tlist; static const char *const tag_usage[] = { - "Usage: %s %s [-lRF] [-b] [-d] [-r tag|-D date] tag [files...]\n", + "Usage: %s %s [-lRF] [-b] [-d] [-c] [-r tag|-D date] tag [files...]\n", "\t-l\tLocal directory only, not recursive.\n", "\t-R\tProcess directories recursively.\n", - "\t-d\tDelete the given Tag.\n", + "\t-d\tDelete the given tag.\n", "\t-[rD]\tExisting tag or date.\n", - "\t-f\tForce a head revision if tag etc not found.\n", + "\t-f\tForce a head revision if specified tag not found.\n", "\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n", - "\t-F\tMove tag if it already exists\n", + "\t-F\tMove tag if it already exists.\n", + "\t-c\tCheck that working files are unmodified.\n", NULL }; @@ -74,7 +83,7 @@ tag (argc, argv) usage (tag_usage); optind = 1; - while ((c = getopt (argc, argv, "FQqlRdr:D:bf")) != -1) + while ((c = getopt (argc, argv, "FQqlRcdr:D:bf")) != -1) { switch (c) { @@ -98,6 +107,9 @@ tag (argc, argv) case 'd': delete_flag = 1; break; + case 'c': + check_uptodate = 1; + break; case 'r': numtag = optarg; break; @@ -148,6 +160,8 @@ tag (argc, argv) send_arg("-l"); if (delete_flag) send_arg("-d"); + if (check_uptodate) + send_arg("-c"); if (branch_mode) send_arg("-b"); if (force_tag_move) @@ -178,9 +192,9 @@ tag (argc, argv) mtlist = getlist(); err = start_recursion (check_fileproc, check_filesdoneproc, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, + (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, argc, argv, local, W_LOCAL, 0, 1, - (char *) NULL, 1, 0); + (char *) NULL, 1); if (err) { @@ -188,9 +202,9 @@ tag (argc, argv) } /* start the recursion processor */ - err = start_recursion (tag_fileproc, (FILESDONEPROC) NULL, tag_dirproc, - (DIRLEAVEPROC) NULL, argc, argv, local, - W_LOCAL, 0, 1, (char *) NULL, 1, 0); + err = start_recursion (tag_fileproc, tag_filesdoneproc, tag_dirproc, + (DIRLEAVEPROC) NULL, NULL, argc, argv, local, + W_LOCAL, 0, 0, (char *) NULL, 1); dellist(&mtlist); return (err); } @@ -199,13 +213,25 @@ tag (argc, argv) /* All we do here is add it to our list */ static int -check_fileproc (finfo) +check_fileproc (callerdat, finfo) + void *callerdat; struct file_info *finfo; { char *xdir; Node *p; Vers_TS *vers; + if (check_uptodate) + { + Ctype status = Classify_File (finfo, (char *) NULL, (char *) NULL, + (char *) NULL, 1, 0, &vers, 0); + if ((status != T_UPTODATE) && (status != T_CHECKOUT)) + { + error (0, 0, "%s is locally modified", finfo->fullname); + return (1); + } + } + if (finfo->update_dir[0] == '\0') xdir = "."; else @@ -234,22 +260,22 @@ check_fileproc (finfo) p->key = xstrdup (finfo->file); p->type = UPDATE; p->delproc = tag_delproc; - vers = Version_TS (finfo->repository, (char *) NULL, (char *) NULL, - (char *) NULL, finfo->file, 0, 0, - finfo->entries, finfo->rcs); + vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0); if (vers->srcfile == NULL) { if (!really_quiet) error (0, 0, "nothing known about %s", finfo->file); return (1); } - p->data = RCS_getversion(vers->srcfile, numtag, date, force_tag_match, 0); + p->data = RCS_getversion(vers->srcfile, numtag, date, force_tag_match, + (int *) NULL); if (p->data != NULL) { int addit = 1; char *oversion; - oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, 0); + oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, + (int *) NULL); if (oversion == NULL) { if (delete_flag) @@ -281,10 +307,12 @@ check_fileproc (finfo) } static int -check_filesdoneproc(err, repos, update_dir) +check_filesdoneproc (callerdat, err, repos, update_dir, entries) + void *callerdat; int err; char *repos; char *update_dir; + List *entries; { int n; Node *p; @@ -389,7 +417,8 @@ pretag_list_proc(p, closure) */ /* ARGSUSED */ static int -tag_fileproc (finfo) +tag_fileproc (callerdat, finfo) + void *callerdat; struct file_info *finfo; { char *version, *oversion; @@ -398,15 +427,20 @@ tag_fileproc (finfo) Vers_TS *vers; int retcode = 0; - vers = Version_TS (finfo->repository, (char *) NULL, (char *) NULL, (char *) NULL, - finfo->file, 0, 0, finfo->entries, finfo->rcs); + /* Lock the directory if it is not already locked. We can't rely + on tag_dirproc because it won't handle the case where the user + specifies a list of files on the command line. */ + tag_lockdir (finfo->repository); + + vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0); if ((numtag != NULL) || (date != NULL)) { nversion = RCS_getversion(vers->srcfile, numtag, date, - force_tag_match, 0); + force_tag_match, + (int *) NULL); if (nversion == NULL) { freevers_ts (&vers); @@ -425,7 +459,8 @@ tag_fileproc (finfo) * "rcs" to remove the tag... trust me. */ - version = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, 0); + version = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, + (int *) NULL); if (version == NULL || vers->srcfile == NULL) { freevers_ts (&vers); @@ -433,7 +468,7 @@ tag_fileproc (finfo) } free (version); - if ((retcode = RCS_deltag(vers->srcfile->path, symtag, 1)) != 0) + if ((retcode = RCS_deltag(vers->srcfile, symtag, 1)) != 0) { if (!quiet) error (0, retcode == -1 ? errno : 0, @@ -501,7 +536,8 @@ tag_fileproc (finfo) * module -- which I have found to be a typical tagging operation. */ rev = branch_mode ? RCS_magicrev (vers->srcfile, version) : version; - oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, 0); + oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, + (int *) NULL); if (oversion != NULL) { int isbranch = RCS_isbranch (finfo->rcs, symtag); @@ -533,7 +569,7 @@ tag_fileproc (finfo) free (oversion); } - if ((retcode = RCS_settag(vers->srcfile->path, symtag, rev)) != 0) + if ((retcode = RCS_settag(vers->srcfile, symtag, rev)) != 0) { error (1, retcode == -1 ? errno : 0, "failed to set tag %s to revision %s in %s", @@ -556,21 +592,98 @@ tag_fileproc (finfo) return (0); } +/* Clear any lock we may hold on the current directory. */ + +static int +tag_filesdoneproc (callerdat, err, repos, update_dir, entries) + void *callerdat; + int err; + char *repos; + char *update_dir; + List *entries; +{ + tag_unlockdir (); + + return (err); +} + /* * Print a warm fuzzy message */ /* ARGSUSED */ static Dtype -tag_dirproc (dir, repos, update_dir) +tag_dirproc (callerdat, dir, repos, update_dir, entries) + void *callerdat; char *dir; char *repos; char *update_dir; + List *entries; { if (!quiet) error (0, 0, "%s %s", delete_flag ? "Untagging" : "Tagging", update_dir); return (R_PROCESS); } +/* We do not need to acquire a full write lock for the tag operation: + the revisions are obtained from the working directory, so we do not + require consistency across the entire repository. However, we do + need to prevent simultaneous tag operations from interfering with + each other. Therefore, we write lock each directory as we enter + it, and unlock it as we leave it. + + In the rtag case, it would be nice to provide consistency with + respect to commits; however CVS lacks the infrastructure to do that + (see Concurrency in cvs.texinfo and comment in do_recursion). We + can and will prevent simultaneous tag operations from interfering + with each other, by write locking each directory as we enter it, + and unlocking it as we leave it. */ +static char *locked_dir; +static List *locked_list; + +/* + * Lock the directory for a tag operation. This is also called by the + * rtag code. + */ +void +tag_lockdir (repository) + char *repository; +{ + if (repository != NULL + && (locked_dir == NULL + || strcmp (locked_dir, repository) != 0)) + { + Node *node; + + if (locked_dir != NULL) + tag_unlockdir (); + + locked_dir = xstrdup (repository); + locked_list = getlist (); + node = getnode (); + node->type = LOCK; + node->key = xstrdup (repository); + (void) addnode (locked_list, node); + Writer_Lock (locked_list); + } +} + +/* + * Unlock the directory for a tag operation. This is also called by + * the rtag code. + */ +void +tag_unlockdir () +{ + if (locked_dir != NULL) + { + Lock_Cleanup (); + dellist (&locked_list); + free (locked_dir); + locked_dir = NULL; + locked_list = NULL; + } +} + /* Code relating to the val-tags file. Note that this file has no way of knowing when a tag has been deleted. The problem is that there is no way of knowing whether a tag still exists somewhere, when we @@ -584,18 +697,15 @@ struct val_args { int found; }; -/* Pass as a static until we get around to fixing start_recursion to pass along - a void * where we can stash it. */ -static struct val_args *val_args_static; - -static int val_fileproc PROTO ((struct file_info *finfo)); +static int val_fileproc PROTO ((void *callerdat, struct file_info *finfo)); static int -val_fileproc (finfo) +val_fileproc (callerdat, finfo) + void *callerdat; struct file_info *finfo; { RCSNode *rcsdata; - struct val_args *args = val_args_static; + struct val_args *args = (struct val_args *)callerdat; char *tag; if ((rcsdata = finfo->rcs) == NULL) @@ -603,7 +713,7 @@ val_fileproc (finfo) W_REPOS | W_ATTIC. */ return 0; - tag = RCS_gettag (rcsdata, args->name, 1, 0); + tag = RCS_gettag (rcsdata, args->name, 1, (int *) NULL); if (tag != NULL) { /* FIXME: should find out a way to stop the search at this point. */ @@ -613,13 +723,15 @@ val_fileproc (finfo) return 0; } -static Dtype val_direntproc PROTO ((char *, char *, char *)); +static Dtype val_direntproc PROTO ((void *, char *, char *, char *, List *)); static Dtype -val_direntproc (dir, repository, update_dir) +val_direntproc (callerdat, dir, repository, update_dir, entries) + void *callerdat; char *dir; char *repository; char *update_dir; + List *entries; { /* This is not quite right--it doesn't get right the case of "cvs update -d -r foobar" where foobar is a tag which exists only in @@ -672,12 +784,18 @@ Numeric tag %s contains characters other than digits and '.'", name); return; } + /* Special tags are always valid. */ + if (strcmp (name, TAG_BASE) == 0 + || strcmp (name, TAG_HEAD) == 0) + return; + mytag.dptr = name; mytag.dsize = strlen (name); - valtags_filename = xmalloc (strlen (CVSroot) + sizeof CVSROOTADM - + sizeof CVSROOTADM_HISTORY + 20); - strcpy (valtags_filename, CVSroot); + valtags_filename = xmalloc (strlen (CVSroot_directory) + + sizeof CVSROOTADM + + sizeof CVSROOTADM_VALTAGS + 20); + strcpy (valtags_filename, CVSroot_directory); strcat (valtags_filename, "/"); strcat (valtags_filename, CVSROOTADM); strcat (valtags_filename, "/"); @@ -709,11 +827,15 @@ Numeric tag %s contains characters other than digits and '.'", name); /* We didn't find the tag in val-tags, so look through all the RCS files to see whether it exists there. Yes, this is expensive, but there is no other way to cope with a tag which might have been created - by an old version of CVS, from before val-tags was invented. */ + by an old version of CVS, from before val-tags was invented. + + Since we need this code anyway, we also use it to create + entries in val-tags in general (that is, the val-tags entry + will get created the first time the tag is used, not when the + tag is created). */ the_val_args.name = name; the_val_args.found = 0; - val_args_static = &the_val_args; which = W_REPOS | W_ATTIC; @@ -725,15 +847,16 @@ Numeric tag %s contains characters other than digits and '.'", name); { if (save_cwd (&cwd)) exit (EXIT_FAILURE); - if (chdir (repository) < 0) + if ( CVS_CHDIR (repository) < 0) error (1, errno, "cannot change to %s directory", repository); } } err = start_recursion (val_fileproc, (FILESDONEPROC) NULL, val_direntproc, (DIRLEAVEPROC) NULL, + (void *)&the_val_args, argc, argv, local, which, aflag, - 1, NULL, 1, 0); + 1, NULL, 1); if (repository != NULL && repository[0] != '\0') { if (restore_cwd (&cwd, NULL)) @@ -779,3 +902,36 @@ Numeric tag %s contains characters other than digits and '.'", name); } free (valtags_filename); } + +/* + * Check whether a join tag is valid. This is just like + * tag_check_valid, but we must stop before the colon if there is one. + */ + +void +tag_check_valid_join (join_tag, argc, argv, local, aflag, repository) + char *join_tag; + int argc; + char **argv; + int local; + int aflag; + char *repository; +{ + char *c, *s; + + c = xstrdup (join_tag); + s = strchr (c, ':'); + if (s != NULL) + { + if (isdigit (join_tag[0])) + error (1, 0, + "Numeric join tag %s may not contain a date specifier", + join_tag); + + *s = '\0'; + } + + tag_check_valid (c, argc, argv, local, aflag, repository); + + free (c); +} diff --git a/gnu/usr.bin/cvs/src/vers_ts.c b/gnu/usr.bin/cvs/src/vers_ts.c index 34983a125d8..415b68785b6 100644 --- a/gnu/usr.bin/cvs/src/vers_ts.c +++ b/gnu/usr.bin/cvs/src/vers_ts.c @@ -18,17 +18,13 @@ static void time_stamp_server PROTO((char *, Vers_TS *)); * the current source control file - preparsed for our pleasure. */ Vers_TS * -Version_TS (repository, options, tag, date, user, force_tag_match, - set_time, entries, rcs) - char *repository; +Version_TS (finfo, options, tag, date, force_tag_match, set_time) + struct file_info *finfo; char *options; char *tag; char *date; - char *user; int force_tag_match; int set_time; - List *entries; - RCSNode *rcs; { Node *p; RCSNode *rcsdata; @@ -44,15 +40,15 @@ Version_TS (repository, options, tag, date, user, force_tag_match, * if entries is NULL, there is no entries file so don't bother trying to * look it up (used by checkout -P) */ - if (entries == NULL) + if (finfo->entries == NULL) { sdtp = NULL; p = NULL; } else { - p = findnode_fn (entries, user); - sdtp = (struct stickydirtag *) entries->list->data; /* list-private */ + p = findnode_fn (finfo->entries, finfo->file); + sdtp = (struct stickydirtag *) finfo->entries->list->data; /* list-private */ } if (p != NULL) @@ -88,15 +84,13 @@ Version_TS (repository, options, tag, date, user, force_tag_match, vers_ts->options = xstrdup (options); else if (!vers_ts->options) { - if (sdtp && sdtp->aflag == 0) - vers_ts->options = xstrdup (sdtp->options); - else if (rcs != NULL) + if (finfo->rcs != NULL) { /* If no keyword expansion was specified on command line, use whatever was in the rcs file (if there is one). This is how we, if we are the server, tell the client whether a file is binary. */ - char *rcsexpand = RCS_getexpand (rcs); + char *rcsexpand = RCS_getexpand (finfo->rcs); if (rcsexpand != NULL) { vers_ts->options = xmalloc (strlen (rcsexpand) + 3); @@ -126,13 +120,13 @@ Version_TS (repository, options, tag, date, user, force_tag_match, } /* Now look up the info on the source controlled file */ - if (rcs != NULL) + if (finfo->rcs != NULL) { - rcsdata = rcs; + rcsdata = finfo->rcs; rcsdata->refcount++; } - else if (repository != NULL) - rcsdata = RCS_parse (user, repository); + else if (finfo->repository != NULL) + rcsdata = RCS_parse (finfo->file, finfo->repository); else rcsdata = NULL; @@ -148,21 +142,17 @@ Version_TS (repository, options, tag, date, user, force_tag_match, } else { + int simple; + vers_ts->vn_rcs = RCS_getversion (rcsdata, vers_ts->tag, - vers_ts->date, force_tag_match, 1); + vers_ts->date, force_tag_match, + &simple); if (vers_ts->vn_rcs == NULL) vers_ts->vn_tag = NULL; + else if (simple) + vers_ts->vn_tag = xstrdup (vers_ts->tag); else - { - char *colon = strchr (vers_ts->vn_rcs, ':'); - if (colon) - { - vers_ts->vn_tag = xstrdup (colon+1); - *colon = '\0'; - } - else - vers_ts->vn_tag = xstrdup (vers_ts->vn_rcs); - } + vers_ts->vn_tag = xstrdup (vers_ts->vn_rcs); } /* @@ -178,19 +168,19 @@ Version_TS (repository, options, tag, date, user, force_tag_match, if (vers_ts->vn_rcs && (t.actime = t.modtime = RCS_getrevtime (rcsdata, vers_ts->vn_rcs, (char *) 0, 0)) != -1) - (void) utime (user, &t); + (void) utime (finfo->file, &t); } } /* get user file time-stamp in ts_user */ - if (entries != (List *) NULL) + if (finfo->entries != (List *) NULL) { #ifdef SERVER_SUPPORT if (server_active) - time_stamp_server (user, vers_ts); + time_stamp_server (finfo->file, vers_ts); else #endif - vers_ts->ts_user = time_stamp (user); + vers_ts->ts_user = time_stamp (finfo->file); } return (vers_ts); @@ -212,7 +202,7 @@ time_stamp_server (file, vers_ts) struct stat sb; char *cp; - if (stat (file, &sb) < 0) + if ( CVS_STAT (file, &sb) < 0) { if (! existence_error (errno)) error (1, errno, "cannot stat temp file"); @@ -290,7 +280,7 @@ time_stamp (file) char *cp; char *ts; - if (stat (file, &sb) < 0) + if ( CVS_STAT (file, &sb) < 0) { ts = NULL; } diff --git a/gnu/usr.bin/cvs/src/version.c b/gnu/usr.bin/cvs/src/version.c index 4848e82b1f1..d74012af9fd 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.8.1"; +char *version_string = "\nConcurrent Versions System (CVS) 1.9"; #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 08734895d28..80626e3d508 100644 --- a/gnu/usr.bin/cvs/src/watch.c +++ b/gnu/usr.bin/cvs/src/watch.c @@ -215,23 +215,28 @@ watch_modify_watchers (file, what) free (mynewattr); } -static int addremove_fileproc PROTO ((struct file_info *finfo)); +static int addremove_fileproc PROTO ((void *callerdat, + struct file_info *finfo)); static int -addremove_fileproc (finfo) +addremove_fileproc (callerdat, finfo) + void *callerdat; struct file_info *finfo; { watch_modify_watchers (finfo->file, &the_args); return 0; } -static int addremove_filesdoneproc PROTO ((int, char *, char *)); +static int addremove_filesdoneproc PROTO ((void *, int, char *, char *, + List *)); static int -addremove_filesdoneproc (err, repository, update_dir) +addremove_filesdoneproc (callerdat, err, repository, update_dir, entries) + void *callerdat; int err; char *repository; char *update_dir; + List *entries; { if (the_args.setting_default) watch_modify_watchers (NULL, &the_args); @@ -348,9 +353,9 @@ watch_addremove (argc, argv) lock_tree_for_write (argc, argv, local, 0); err = start_recursion (addremove_fileproc, addremove_filesdoneproc, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, + (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, argc, argv, local, W_LOCAL, 0, 0, (char *)NULL, - 1, 0); + 1); lock_tree_cleanup (); return err; @@ -416,10 +421,12 @@ static const char *const watchers_usage[] = NULL }; -static int watchers_fileproc PROTO ((struct file_info *finfo)); +static int watchers_fileproc PROTO ((void *callerdat, + struct file_info *finfo)); static int -watchers_fileproc (finfo) +watchers_fileproc (callerdat, finfo) + void *callerdat; struct file_info *finfo; { char *them; @@ -515,7 +522,7 @@ watchers (argc, argv) #endif /* CLIENT_SUPPORT */ return start_recursion (watchers_fileproc, (FILESDONEPROC) NULL, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, + (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, argc, argv, local, W_LOCAL, 0, 1, (char *)NULL, - 1, 0); + 1); } diff --git a/gnu/usr.bin/cvs/src/zlib.c b/gnu/usr.bin/cvs/src/zlib.c new file mode 100644 index 00000000000..776e1bfb5e4 --- /dev/null +++ b/gnu/usr.bin/cvs/src/zlib.c @@ -0,0 +1,433 @@ +/* zlib.c --- interface to the zlib compression library + Ian Lance Taylor <ian@cygnus.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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* The routines in this file are the interface between the CVS + client/server support and the zlib compression library. */ + +#include <assert.h> +#include "cvs.h" +#include "buffer.h" + +#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) + +#include "zlib.h" + +/* OS/2 doesn't have EIO. FIXME: this whole notion of turning + a different error into EIO strikes me as pretty dubious. */ +#if !defined (EIO) +#define EIO EBADPOS +#endif + +/* The compression interface is built upon the buffer data structure. + We provide a buffer type which compresses or decompresses the data + which passes through it. An input buffer decompresses the data + read from an underlying buffer, and an output buffer compresses the + data before writing it to an underlying buffer. */ + +/* This structure is the closure field of the buffer. */ + +struct compress_buffer +{ + /* The underlying buffer. */ + struct buffer *buf; + /* The compression information. */ + z_stream zstr; +}; + +static void compress_error PROTO((int, int, z_stream *, const char *)); +static int compress_buffer_input PROTO((void *, char *, int, int, int *)); +static int compress_buffer_output PROTO((void *, const char *, int, int *)); +static int compress_buffer_flush PROTO((void *)); +static int compress_buffer_block PROTO((void *, int)); +static int compress_buffer_shutdown_input PROTO((void *)); +static int compress_buffer_shutdown_output PROTO((void *)); + +/* Report an error from one of the zlib functions. */ + +static void +compress_error (status, zstatus, zstr, msg) + int status; + int zstatus; + z_stream *zstr; + const char *msg; +{ + int hold_errno; + const char *zmsg; + char buf[100]; + + hold_errno = errno; + + zmsg = zstr->msg; + if (zmsg == NULL) + { + sprintf (buf, "error %d", zstatus); + zmsg = buf; + } + + error (status, + zstatus == Z_ERRNO ? hold_errno : 0, + "%s: %s", msg, zmsg); +} + +/* Create a compression buffer. */ + +struct buffer * +compress_buffer_initialize (buf, input, level, memory) + struct buffer *buf; + int input; + int level; + void (*memory) PROTO((struct buffer *)); +{ + struct compress_buffer *n; + int zstatus; + + n = (struct compress_buffer *) xmalloc (sizeof *n); + memset (n, 0, sizeof *n); + + n->buf = buf; + + if (input) + zstatus = inflateInit (&n->zstr); + else + zstatus = deflateInit (&n->zstr, level); + if (zstatus != Z_OK) + compress_error (1, zstatus, &n->zstr, "compression initialization"); + + /* There may already be data buffered on BUF. For an output + buffer, this is OK, because these routines will just use the + buffer routines to append data to the (uncompressed) data + already on BUF. An input buffer expects to handle a single + buffer_data of buffered input to be uncompressed, so that is OK + provided there is only one buffer. At present that is all + there ever will be; if this changes, compress_buffer_input must + be modified to handle multiple input buffers. */ + assert (! input || buf->data == NULL || buf->data->next == NULL); + + return buf_initialize (input ? compress_buffer_input : NULL, + input ? NULL : compress_buffer_output, + input ? NULL : compress_buffer_flush, + compress_buffer_block, + (input + ? compress_buffer_shutdown_input + : compress_buffer_shutdown_output), + memory, + n); +} + +/* Input data from a compression buffer. */ + +static int +compress_buffer_input (closure, data, need, size, got) + void *closure; + char *data; + int need; + int size; + int *got; +{ + struct compress_buffer *cb = (struct compress_buffer *) closure; + struct buffer_data *bd; + + if (cb->buf->input == NULL) + abort (); + + /* We use a single buffer_data structure to buffer up data which + the z_stream structure won't use yet. We can safely store this + on cb->buf->data, because we never call the buffer routines on + cb->buf; we only call the buffer input routine, since that + gives us the semantics we want. As noted in + compress_buffer_initialize, the buffer_data structure may + already exist, and hold data which was already read and + buffered before the decompression began. */ + bd = cb->buf->data; + if (bd == NULL) + { + bd = ((struct buffer_data *) malloc (sizeof (struct buffer_data))); + if (bd == NULL) + return -2; + bd->text = (char *) malloc (BUFFER_DATA_SIZE); + if (bd->text == NULL) + { + free (bd); + return -2; + } + bd->bufp = bd->text; + bd->size = 0; + cb->buf->data = bd; + } + + cb->zstr.avail_out = size; + cb->zstr.next_out = (Bytef *) data; + + while (1) + { + int zstatus, sofar, status, nread; + + /* First try to inflate any data we already have buffered up. + This is useful even if we don't have any buffered data, + because there may be data buffered inside the z_stream + structure. */ + + cb->zstr.avail_in = bd->size; + cb->zstr.next_in = (Bytef *) bd->bufp; + + do + { + zstatus = inflate (&cb->zstr, Z_NO_FLUSH); + if (zstatus == Z_STREAM_END) + break; + if (zstatus != Z_OK && zstatus != Z_BUF_ERROR) + { + compress_error (0, zstatus, &cb->zstr, "inflate"); + return EIO; + } + } while (cb->zstr.avail_in > 0 + && cb->zstr.avail_out > 0); + + bd->size = cb->zstr.avail_in; + bd->bufp = (char *) cb->zstr.next_in; + + if (zstatus == Z_STREAM_END) + return -1; + + /* If we have obtained NEED bytes, then return, unless NEED is + zero and we haven't obtained anything at all. If NEED is + zero, we will keep reading from the underlying buffer until + we either can't read anything, or we have managed to + inflate at least one byte. */ + sofar = size - cb->zstr.avail_out; + if (sofar > 0 && sofar >= need) + break; + + /* All our buffered data should have been processed at this + point. */ + assert (bd->size == 0); + + /* This will work well in the server, because this call will + do an unblocked read and fetch all the available data. In + the client, this will read a single byte from the stdio + stream, which will cause us to call inflate once per byte. + It would be more efficient if we could make a call which + would fetch all the available bytes, and at least one byte. */ + + status = (*cb->buf->input) (cb->buf->closure, bd->text, + need > 0 ? 1 : 0, + BUFFER_DATA_SIZE, &nread); + if (status != 0) + return status; + + /* If we didn't read anything, then presumably the buffer is + in nonblocking mode, and we should just get out now with + whatever we've inflated. */ + if (nread == 0) + { + assert (need == 0); + break; + } + + bd->bufp = bd->text; + bd->size = nread; + } + + *got = size - cb->zstr.avail_out; + + return 0; +} + +/* Output data to a compression buffer. */ + +static int +compress_buffer_output (closure, data, have, wrote) + void *closure; + const char *data; + int have; + int *wrote; +{ + struct compress_buffer *cb = (struct compress_buffer *) closure; + + cb->zstr.avail_in = have; + cb->zstr.next_in = (unsigned char *) data; + + while (cb->zstr.avail_in > 0) + { + char buffer[BUFFER_DATA_SIZE]; + int zstatus; + + cb->zstr.avail_out = BUFFER_DATA_SIZE; + cb->zstr.next_out = (unsigned char *) buffer; + + zstatus = deflate (&cb->zstr, Z_NO_FLUSH); + if (zstatus != Z_OK) + { + compress_error (0, zstatus, &cb->zstr, "deflate"); + return EIO; + } + + if (cb->zstr.avail_out != BUFFER_DATA_SIZE) + buf_output (cb->buf, buffer, + BUFFER_DATA_SIZE - cb->zstr.avail_out); + } + + *wrote = have; + + /* We will only be here because buf_send_output was called on the + compression buffer. That means that we should now call + buf_send_output on the underlying buffer. */ + return buf_send_output (cb->buf); +} + +/* Flush a compression buffer. */ + +static int +compress_buffer_flush (closure) + void *closure; +{ + struct compress_buffer *cb = (struct compress_buffer *) closure; + + cb->zstr.avail_in = 0; + cb->zstr.next_in = NULL; + + while (1) + { + char buffer[BUFFER_DATA_SIZE]; + int zstatus; + + cb->zstr.avail_out = BUFFER_DATA_SIZE; + cb->zstr.next_out = (unsigned char *) buffer; + + zstatus = deflate (&cb->zstr, Z_SYNC_FLUSH); + + /* The deflate function will return Z_BUF_ERROR if it can't do + anything, which in this case means that all data has been + flushed. */ + if (zstatus == Z_BUF_ERROR) + break; + + if (zstatus != Z_OK) + { + compress_error (0, zstatus, &cb->zstr, "deflate flush"); + return EIO; + } + + if (cb->zstr.avail_out != BUFFER_DATA_SIZE) + buf_output (cb->buf, buffer, + BUFFER_DATA_SIZE - cb->zstr.avail_out); + + /* If the deflate function did not fill the output buffer, + then all data has been flushed. */ + if (cb->zstr.avail_out > 0) + break; + } + + /* Now flush the underlying buffer. Note that if the original + call to buf_flush passed 1 for the BLOCK argument, then the + buffer will already have been set into blocking mode, so we + should always pass 0 here. */ + return buf_flush (cb->buf, 0); +} + +/* The block routine for a compression buffer. */ + +static int +compress_buffer_block (closure, block) + void *closure; + int block; +{ + struct compress_buffer *cb = (struct compress_buffer *) closure; + + if (block) + return set_block (cb->buf); + else + return set_nonblock (cb->buf); +} + +/* Shut down an input buffer. */ + +static int +compress_buffer_shutdown_input (closure) + void *closure; +{ + struct compress_buffer *cb = (struct compress_buffer *) closure; + int zstatus; + + /* Pick up any trailing data, such as the checksum. */ + while (1) + { + int status, nread; + char buf[100]; + + status = compress_buffer_input (cb, buf, 0, sizeof buf, &nread); + if (status == -1) + break; + if (status != 0) + return status; + } + + zstatus = inflateEnd (&cb->zstr); + if (zstatus != Z_OK) + { + compress_error (0, zstatus, &cb->zstr, "inflateEnd"); + return EIO; + } + + return buf_shutdown (cb->buf); +} + +/* Shut down an output buffer. */ + +static int +compress_buffer_shutdown_output (closure) + void *closure; +{ + struct compress_buffer *cb = (struct compress_buffer *) closure; + int zstatus, status; + + do + { + char buffer[BUFFER_DATA_SIZE]; + + cb->zstr.avail_out = BUFFER_DATA_SIZE; + cb->zstr.next_out = (unsigned char *) buffer; + + zstatus = deflate (&cb->zstr, Z_FINISH); + if (zstatus != Z_OK && zstatus != Z_STREAM_END) + { + compress_error (0, zstatus, &cb->zstr, "deflate finish"); + return EIO; + } + + if (cb->zstr.avail_out != BUFFER_DATA_SIZE) + buf_output (cb->buf, buffer, + BUFFER_DATA_SIZE - cb->zstr.avail_out); + } while (zstatus != Z_STREAM_END); + + zstatus = deflateEnd (&cb->zstr); + if (zstatus != Z_OK) + { + compress_error (0, zstatus, &cb->zstr, "deflateEnd"); + return EIO; + } + + status = buf_flush (cb->buf, 1); + if (status != 0) + return status; + + return buf_shutdown (cb->buf); +} + +#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */ diff --git a/gnu/usr.bin/cvs/tools/ChangeLog b/gnu/usr.bin/cvs/tools/ChangeLog index c6b6e1c7d11..ce046436b13 100644 --- a/gnu/usr.bin/cvs/tools/ChangeLog +++ b/gnu/usr.bin/cvs/tools/ChangeLog @@ -1,3 +1,7 @@ +Fri Aug 16 16:05:56 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * Makefile.in (installdirs): new (empty) target + Sun Apr 14 11:07:43 1996 Karl Fogel <kfogel@floss.red-bean.com> * .cvsignore: new file. diff --git a/gnu/usr.bin/cvs/tools/Makefile.in b/gnu/usr.bin/cvs/tools/Makefile.in index c83d1a807c3..d47d44c4e32 100644 --- a/gnu/usr.bin/cvs/tools/Makefile.in +++ b/gnu/usr.bin/cvs/tools/Makefile.in @@ -42,6 +42,9 @@ install: all @echo "pcl-cvs not installed" .PHONY: install +installdirs: +.PHONY: installdirs + tags: .PHONY: tags diff --git a/gnu/usr.bin/cvs/vms/ChangeLog b/gnu/usr.bin/cvs/vms/ChangeLog new file mode 100644 index 00000000000..1b172206585 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/ChangeLog @@ -0,0 +1,86 @@ +Wed Sep 25 15:09:53 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * options.h: Define TMPDIR_DFLT to sys$scratch not sys$login. + +Tue Sep 24 14:11:30 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * options.h: Add TMPDIR_DFLT. + + * Makefile.in (DISTFILES): Add getpass.c. + +Thu Sep 12 1996 Jim Kingdon <kingdon@cyclic.com> + + * config.h: Define ARGV0_NOT_PROGRAM_NAME. + +Thu Sep 12 14:56:42 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * config.h, filesubr.c: Add FOLD_FN_CHAR, VMS_filename_classes, + fncmp, and fnfold. This is copied from the NT port except various + comments were changed and '/' is not considered the same as '\'. + +Wed Sep 11 15:53:18 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * config.h: Define NO_SLASH_AFTER_HOME. + + * options.h: Define AUTH_CLIENT_SUPPORT. + * build_vms.com: Add getpass.c. + * getpass.c: New file. + + * config.h: Define getopt, optind, optopt, optarg, and opterr to + avoid name conflicts with system libraries. + + * filesubr.c (expand_wild): Added. + +Wed Sep 11 11:12:01 1996 Jim Blandy <jimb@totoro.cyclic.com> + + * Makefile.in (DISTFILES): Omit filesubr.c.rej. + +Tue Sep 10 19:15:47 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * Makefile.in: New file. + + * config.h (START_SERVER_RETURNS_SOCKET, SEND_NEVER_PARTIAL): + Define. This just preserves the behavior the VMS port has had all + along. + +Mon Aug 26 12:51:52 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (mkdir_if_needed): Added. + +Tue May 14 13:38:51 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (cvs_temp_name): New function. + +Tue Mar 19 17:49:16 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * startserver.c (vms_start_server): Added support for + CVS_RCMD_PORT (and thus made consistent with WindowsNT and Mac) + +Fri Mar 1 00:10:06 1996 Benjamin J. Lee <benjamin@cyclic.com> + + * startserver.c, rcmd.c: Made privileged/non-privileged + rsh communication more adaptive. Removed USE_PRIVILEGED_RCMD. + +Wed Feb 28 11:08:06 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * options.h: Remove comment about automatic generation from + options.h.in. + + * options.h: Remove AUTH_SERVER_SUPPORT; no longer should be + defined in options.h. + + * options.h: Remove RM and SORT; no longer used. + + * config.h: Remove C_ALLOCA, CRAY_STACKSEG_END, HAVE_ALLOCA, + HAVE_ALLOCA_H, and STACK_DIRECTION to reflect alloca removal. + + * vms.h: Remove DEATH_SUPPORT; it was removed from CVS Feb 9. + + * alloca.c: Removed. + * build_vms.com: Remove alloca. + * startserver.c (vms_start_server): Use xmalloc/free, not alloca. + +Wed Feb 28 03:38:42 1996 Benjamin J. Lee <benjamin@cyclic.com> + + * VMS support files added. + diff --git a/gnu/usr.bin/cvs/vms/Makefile.in b/gnu/usr.bin/cvs/vms/Makefile.in new file mode 100644 index 00000000000..f37bf736dd7 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/Makefile.in @@ -0,0 +1,85 @@ +#### Under VMS, we use *.COM to build, not +#### this makefile. However, we need this file in order for 'make +#### dist' to work properly on Unix machines. + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +cvs_srcdir = @top_srcdir@/src +VPATH = @srcdir@ + +SHELL = /bin/sh + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +DISTFILES = \ + ChangeLog \ + Makefile.in \ + build_vms.com \ + config.h \ + dir.h \ + filesubr.c \ + filutils.c \ + filutils.h \ + getpass.c \ + getwd.c \ + misc.c \ + misc.h \ + ndir.c \ + ndir.h \ + options.h \ + pathnames.h \ + pc.c \ + pipe.c \ + pipe.h \ + piped_child.c \ + pwd.c \ + pwd.h \ + rcmd.c \ + readlink.c \ + rmdir.c \ + startserver.c \ + stat.c \ + unlink.c \ + utime.c \ + vms-types.h \ + vms.h \ + vmsmunch.c \ + vmsmunch.h \ + vmsmunch_private.h \ + waitpid.c + +all: + +.PHONY: all install uninstall +all install uninstall: + +installdirs: +.PHONY: installdirs + +.PHONY: tags TAGS +tags TAGS: + +.PHONY: ls +ls: + @echo ${DISTFILES} + +.PHONY: clean distclean realclean mostlyclean +clean distclean realclean mostlyclean: + +.PHONY: lint +lint: + +.PHONY: dist-dir +dist-dir: + mkdir ${DISTDIR} + for i in ${DISTFILES}; do \ + ln $(srcdir)/$${i} ${DISTDIR}; \ + done + +clean: + @echo make clean does nothing in vms subdir + +subdir = vms +Makefile: ../config.status Makefile.in + cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status diff --git a/gnu/usr.bin/cvs/vms/build_vms.com b/gnu/usr.bin/cvs/vms/build_vms.com new file mode 100644 index 00000000000..f2d97413158 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/build_vms.com @@ -0,0 +1,24 @@ +$ CC :== CC/DEBUG/NOOPTIMIZE/STANDARD=VAXC/DEFINE=HAVE_CONFIG_H- +/INCLUDE_DIRECTORY=([-],[-.LIB],[-.SRC],[-.VMS])/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES +$ CC filesubr.c +$ CC filutils.c +$ CC getpass.c +$ CC getwd.c +$ CC misc.c +$ CC ndir.c +$ CC pipe.c +$ CC piped_child.c +$ CC pwd.c +$ CC rcmd.c +$ CC readlink.c +$ CC rmdir.c +$ CC stat.c +$ CC startserver.c +$ CC unlink.c +$ CC utime.c +$ CC /NOSTANDARD vmsmunch.c +$ CC waitpid.c +$ library/create openvmslib.olb filesubr.obj,- +filutils.obj,getpass.obj,getwd.obj,misc.obj,ndir.obj,pipe.obj,- +pwd.obj,rcmd.obj,readlink.obj,rmdir.obj,stat.obj,startserver.obj,- +unlink.obj,utime.obj,vmsmunch.obj,waitpid.obj diff --git a/gnu/usr.bin/cvs/vms/config.h b/gnu/usr.bin/cvs/vms/config.h new file mode 100644 index 00000000000..d115228e309 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/config.h @@ -0,0 +1,219 @@ +/* config.h - OpenVMS/AXP specific configuration + June 1995 - <benjamin@cyclic.com> */ + +/* We only want to build the client */ +#define CLIENT_SUPPORT 1 +#undef SERVER_SUPPORT + +/* VMS is case insensitive */ +/* #define FOLD_FN_CHAR(c) tolower(c) */ + +/* Temporary files named "#booger.3.6~" aren't legal under VMS, + Define this if you want to use names which are legal for VMS */ +#define USE_VMS_FILENAMES 1 + +/* More issues with how VMS names files, kind of a kludge. See login.c. */ +#define NO_SLASH_AFTER_HOME 1 + +/* Only good for NT or DOS with hacked open */ +/* #undef LINES_CRLF_TERMINATED */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you have <dirent.h>. */ +/* #undef DIRENT */ + +/* Define if you have <sys/param.h> */ +/* #undef HAVE_SYS_PARAM_H */ + +/* Define to `int' if <sys/types.h> doesn't define. */ +/* #undef gid_t */ + +/* Define if you support file names longer than 14 characters. */ +/* #undef HAVE_LONG_FILE_NAMES */ + +/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */ +/* #define HAVE_SYS_WAIT_H 1 OpenVMS POSIX has it, but VMS does not. */ +#undef POSIX + +/* Define if utime(file, NULL) sets file's timestamp to the present. */ +/* #undef HAVE_UTIME_NULL */ + +/* Define if on MINIX. */ +/* #undef _MINIX */ + +/* Define to `int' if <sys/types.h> doesn't define. */ +/* #undef mode_t */ + +/* Define if you don't have <dirent.h>, but have <ndir.h>. */ +/* #undef NDIR */ + +/* Define to `int' if <sys/types.h> doesn't define. */ +/* #undef pid_t */ + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if <sys/types.h> doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you don't have <dirent.h>, but have <sys/dir.h>. */ +/* #undef SYSDIR */ + +/* Define if you don't have <dirent.h>, but have <sys/ndir.h>. */ +/* #undef SYSNDIR */ + +/* Define if your <sys/time.h> declares struct tm. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define to `int' if <sys/types.h> doesn't define. */ +/* #undef uid_t */ + +/* Define if the closedir function returns void instead of int. */ +/* #undef VOID_CLOSEDIR */ + +/* Define if you want direct TCP access to server */ +#define USE_DIRECT_TCP 1 + +/* Define if you have MIT Kerberos version 4 available. */ +/* #undef HAVE_KERBEROS */ + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* Define if you have the fchmod function. */ +/* #undef HAVE_FCHMOD */ + +/* Define if you have the fsync function. */ +/* #undef HAVE_FSYNC */ + +/* Define if you have the ftime function. */ +/* #undef HAVE_FTIME */ + +/* Define if you have the ftruncate function. */ +/* #undef HAVE_FTRUNCATE */ + +/* Define if you have the getpagesize function. */ +/* #undef HAVE_GETPAGESIZE */ + +/* Define if you have the krb_get_err_text function. */ +/* #undef HAVE_KRB_GET_ERR_TEXT */ + +/* Define if you have the mkdir function */ +#define HAVE_MKDIR 1 + +/* Define if you have the rmdir function */ +#define HAVE_RMDIR 1 + +/* Define if you have the rename function */ +#define HAVE_RENAME 1 + +/* Define if you have the strdup function */ +#define HAVE_STRDUP 1 + +/* Define if you have the mkfifo function. */ +/* #undef HAVE_MKFIFO */ + +/* Define if you have the putenv function. */ +/* #undef HAVE_PUTENV */ + +/* Define if you have the setvbuf function. */ +/* #undef HAVE_SETVBUF */ + +/* Define if you have the timezone function. */ +/* #undef HAVE_TIMEZONE */ + +/* Define if you have the vfork function. */ +#define HAVE_VFORK + +/* Define if you have the vprintf function. */ +/* #undef HAVE_VPRINTF */ + +/* Define if you have the <errno.h> header file. */ +/* #undef HAVE_ERRNO_H */ + +/* Define if you have the <fcntl.h> header file. */ +/* #undef HAVE_FCNTL_H */ + +/* Define if you have the <memory.h> header file. */ +/* #undef HAVE_MEMORY_H */ + +/* Define if you have the <ndbm.h> header file. */ +/* #undef HAVE_NDBM_H */ + +/* Define if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the <sys/select.h> header file. */ +/* #undef HAVE_SYS_SELECT_H */ + +/* Define this if your <sys/socket.h> defines select() */ +#define SYS_SOCKET_H_DEFINES_SELECT 1 + +/* Define if you have the <sys/timeb.h> header file. */ +#define HAVE_SYS_TIMEB_H 1 +#define HAVE_TIMEB_H 1 + +/* Define if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the <utime.h> header file. */ +/* #undef HAVE_UTIME_H */ + +/* Define if you have the nsl library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define if you have the socket library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Under Windows NT, filenames are case-insensitive, and both / and \ + are path component separators. */ +#define FOLD_FN_CHAR(c) (VMS_filename_classes[(unsigned char) (c)]) +extern unsigned char VMS_filename_classes[]; +#define FILENAMES_CASE_INSENSITIVE 1 + +/* Like strcmp, but with the appropriate tweaks for file names. + Under Windows NT, filenames are case-insensitive but case-preserving, + and both \ and / are path element separators. */ +extern int fncmp (const char *n1, const char *n2); + +/* Fold characters in FILENAME to their canonical forms. + If FOLD_FN_CHAR is not #defined, the system provides a default + definition for this. */ +extern void fnfold (char *FILENAME); + +#define RSH_NOT_TRANSPARENT 1 +#define START_SERVER vms_start_server +#define NO_SOCKET_TO_FD 1 +#define START_SERVER_RETURNS_SOCKET 1 +#define SEND_NEVER_PARTIAL 1 + +/* Avoid name conflicts with VMS libraries. */ +#define getopt cvs_getopt +#define optind cvs_optind +#define optopt cvs_optopt +#define optarg cvs_optarg +#define opterr cvs_opterr + +/* argv[0] in VMS is the full pathname which would look really ugly in error + messages. Even if we stripped out the directory and ".EXE;5", it would + still be misleading, as if one has used "OLDCVS :== ...CVS-JULY.EXE", + then argv[0] does not contain the name of the command which the user + invokes CVS with. If there is a way for VMS to find the latter, that + might be worth messing with, but it also seems fine to just always call + it "cvs". */ +#define ARGV0_NOT_PROGRAM_NAME diff --git a/gnu/usr.bin/cvs/vms/dir.h b/gnu/usr.bin/cvs/vms/dir.h new file mode 100644 index 00000000000..7ea632db625 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/dir.h @@ -0,0 +1,97 @@ +/* GNU Emacs VMS directory definition file. + Copyright (C) 1986 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs 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 1, or (at your option) +any later version. + +GNU Emacs 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. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + * Files-11 Ver. 2 directory structure (VMS V4.x - long names) + */ +#ifndef DIR$K_LENGTH + +#define DIR$C_FID 0 +#define DIR$C_LINKNAME 1 +#define DIR$K_LENGTH 6 +#define DIR$C_LENGTH 6 +#define DIR$S_DIRDEF 6 +#define DIR$W_SIZE 0 +#define DIR$W_VERLIMIT 2 +#define DIR$B_FLAGS 4 +#define DIR$S_TYPE 3 +#define DIR$V_TYPE 0 +#define DIR$V_NEXTREC 6 +#define DIR$V_PREVREC 7 +#define DIR$B_NAMECOUNT 5 +#define DIR$S_NAME 80 +#define DIR$T_NAME 6 + +#define DIR$K_VERSION 8 +#define DIR$C_VERSION 8 +#define DIR$S_DIRDEF1 8 +#define DIR$W_VERSION 0 +#define DIR$S_FID 6 +#define DIR$W_FID 2 +#define DIR$W_FID_NUM 2 +#define DIR$W_FID_SEQ 4 +#define DIR$W_FID_RVN 6 +#define DIR$B_FID_RVN 6 +#define DIR$B_FID_NMX 7 + +#define DIR$S_DIRDEF2 1 +#define DIR$T_LINKNAME 0 + +typedef struct dir$_name { +/* short dir$w_size; /* if you read with RMS, it eats this... */ + short dir$w_verlimit; /* maximum number of versions */ + union { + unsigned char dir_b_flags; +#define dir$b_flags dir__b_flags.dir_b_flags + struct { + unsigned char dir_v_type: DIR$S_TYPE; +#define dir$v_type dir__b_flags.dir___b_flags.dir_v_type + unsigned char: 3; + unsigned char dir_v_nextrec: 1; +#define dir$v_nextrec dir__b_flags.dir___b_flags.dir_v_nextrec + unsigned char dir_v_prevrec: 1; +#define dir$v_prevrec dir__b_flags.dir___b_flags.dir_v_prevrec + } dir___b_flags; + } dir__b_flags; + unsigned char dir$b_namecount; + char dir$t_name[]; +} dir$_dirdef; /* only the fixed first part */ + +typedef struct dir$_version { + short dir$w_version; + short dir$w_fid_num; + short dir$w_fid_seq; + union { + short dir_w_fid_rvn; +#define dir$w_fid_rvn dir__w_fid_rvn.dir_w_fid_rvn + struct { + char dir_b_fid_rvn; +#define dir$b_fid_rvn dir__w_fid_rvn.dir___w_fid_rvn.dir_b_fid_rvn + char dir_b_fid_nmx; +#define dir$b_fid_nmx dir__w_fid_rvn.dir___w_fid_rvn.dir_b_fid_nmx + } dir___w_fid_rvn; + } dir__w_fid_rvn; +} dir$_dirdef1; /* one for each version of the file */ + +typedef +struct dir$_linkname { + char dir$t_linkname[]; +} dir$_dirdef2; + +#endif diff --git a/gnu/usr.bin/cvs/vms/filesubr.c b/gnu/usr.bin/cvs/vms/filesubr.c new file mode 100644 index 00000000000..99c0af163c3 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/filesubr.c @@ -0,0 +1,839 @@ +/* filesubr.c --- subroutines for dealing with files + Gratuitously adapted toward VMS quirks. + + Jim Blandy <jimb@cyclic.com> + Benjamin J. Lee <benjamin@cyclic.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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "cvs.h" + +static int deep_remove_dir PROTO((const char *path)); + +/* + * Copies "from" to "to". + */ +void +copy_file (from_file, to_file) + const char *from_file; + const char *to_file; +{ + char from[PATH_MAX], to[PATH_MAX]; + struct stat sb; + struct utimbuf t; + int fdin, fdout; + + /* Prefer local relative paths to files at expense of logical name + access to files. */ + + if (isabsolute(from_file)) + strcpy(from, from_file); + else + sprintf(from, "./%s", from_file); + + if (isabsolute(to_file)) + strcpy(to, to_file); + else + sprintf(to, "./%s", to_file); + + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> copy(%s,%s)\n", + (server_active) ? 'S' : ' ', from, to); +#else + (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to); +#endif + if (noexec) + return; + + if ((fdin = open (from, O_RDONLY)) < 0) + error (1, errno, "cannot open %s for copying", from); + if (fstat (fdin, &sb) < 0) + error (1, errno, "cannot fstat %s", from); + if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0) + error (1, errno, "cannot create %s for copying", to); + if (sb.st_size > 0) + { + char buf[BUFSIZ]; + int n; + + for (;;) + { + n = read (fdin, buf, sizeof(buf)); + if (n == -1) + { +#ifdef EINTR + if (errno == EINTR) + continue; +#endif + error (1, errno, "cannot read file %s for copying", from); + } + else if (n == 0) + break; + + if (write(fdout, buf, n) != n) { + error (1, errno, "cannot write file %s for copying", to); + } + } + +#ifdef HAVE_FSYNC + if (fsync (fdout)) + error (1, errno, "cannot fsync file %s after copying", to); +#endif + } + + if (close (fdin) < 0) + error (0, errno, "cannot close %s", from); + if (close (fdout) < 0) + error (1, errno, "cannot close %s", to); + + /* now, set the times for the copied file to match those of the original */ + memset ((char *) &t, 0, sizeof (t)); + t.actime = sb.st_atime; + t.modtime = sb.st_mtime; + (void) utime (to, &t); +} + +/* FIXME-krp: these functions would benefit from caching the char * & + stat buf. */ + +/* + * Returns non-zero if the argument file is a directory, or is a symbolic + * link which points to a directory. + */ +int +isdir (file) + const char *file; +{ + struct stat sb; + + if (stat (file, &sb) < 0) + return (0); + return (S_ISDIR (sb.st_mode)); +} + +/* + * Returns non-zero if the argument file is a symbolic link. + */ +int +islink (file) + const char *file; +{ +#ifdef S_ISLNK + struct stat sb; + + if (lstat (file, &sb) < 0) + return (0); + return (S_ISLNK (sb.st_mode)); +#else + return (0); +#endif +} + +/* + * Returns non-zero if the argument file exists. + */ +int +isfile (file) + const char *file; +{ + return isaccessible(file, F_OK); +} + +/* + * Returns non-zero if the argument file is readable. + */ +int +isreadable (file) + const char *file; +{ + return isaccessible(file, R_OK); +} + +/* + * Returns non-zero if the argument file is writable. + */ +int +iswritable (file) + const char *file; +{ + return isaccessible(file, W_OK); +} + +/* + * Returns non-zero if the argument file is accessable according to + * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid + * bits set. + */ +int +isaccessible (file, mode) + const char *file; + const int mode; +{ +#ifdef SETXID_SUPPORT + struct stat sb; + int umask = 0; + int gmask = 0; + int omask = 0; + int uid; + + if (stat(file, &sb) == -1) + return 0; + if (mode == F_OK) + return 1; + + uid = geteuid(); + if (uid == 0) /* superuser */ + { + if (mode & X_OK) + return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH); + else + return 1; + } + + if (mode & R_OK) + { + umask |= S_IRUSR; + gmask |= S_IRGRP; + omask |= S_IROTH; + } + if (mode & W_OK) + { + umask |= S_IWUSR; + gmask |= S_IWGRP; + omask |= S_IWOTH; + } + if (mode & X_OK) + { + umask |= S_IXUSR; + gmask |= S_IXGRP; + omask |= S_IXOTH; + } + + if (sb.st_uid == uid) + return (sb.st_mode & umask) == umask; + else if (sb.st_gid == getegid()) + return (sb.st_mode & gmask) == gmask; + else + return (sb.st_mode & omask) == omask; +#else + return access(file, mode) == 0; +#endif +} + +/* + * Open a file and die if it fails + */ +FILE * +open_file (name, mode) + const char *name; + const char *mode; +{ + FILE *fp; + + if ((fp = fopen (name, mode)) == NULL) + error (1, errno, "cannot open %s", name); + return (fp); +} + +/* + * Make a directory and die if it fails + */ +void +make_directory (name) + const char *name; +{ + struct stat sb; + + if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode))) + error (0, 0, "%s already exists but is not a directory", name); + if (!noexec && mkdir (name, 0777) < 0) + error (1, errno, "cannot make directory %s", name); +} + +/* + * Make a path to the argument directory, printing a message if something + * goes wrong. + */ +void +make_directories (name) + const char *name; +{ + char *cp; + + if (noexec) + return; + + if (mkdir (name, 0777) == 0 || errno == EEXIST) + return; + if (! existence_error (errno)) + { + error (0, errno, "cannot make path to %s", name); + return; + } + if ((cp = strrchr (name, '/')) == NULL) + return; + *cp = '\0'; + make_directories (name); + *cp++ = '/'; + if (*cp == '\0') + return; + (void) mkdir (name, 0777); +} + +/* Create directory NAME if it does not already exist; fatal error for + other errors. Returns 0 if directory was created; 1 if it already + existed. */ +int +mkdir_if_needed (name) + char *name; +{ + if (mkdir (name, 0777) < 0) + { + if (errno != EEXIST +#ifdef EACCESS + /* This was copied over from the OS/2 code; I would guess it + isn't needed here but that has not been verified. */ + && errno != EACCESS +#endif + ) + error (1, errno, "cannot make directory %s", name); + return 1; + } + return 0; +} + +/* + * Change the mode of a file, either adding write permissions, or removing + * all write permissions. Either change honors the current umask setting. + */ +void +xchmod (fname_file, writable) + char *fname_file; + int writable; +{ + char fname[PATH_MAX]; + struct stat sb; + mode_t mode, oumask; + + /* Prefer local relative paths to files at expense of logical name + access to files. */ + + if (isabsolute(fname_file)) + strcpy(fname, fname_file); + else + sprintf(fname, "./%s", fname_file); + + if (stat (fname, &sb) < 0) + { + if (!noexec) + error (0, errno, "cannot stat %s", fname); + return; + } + oumask = umask (0); + (void) umask (oumask); + if (writable) + { + mode = sb.st_mode | (~oumask + & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0) + | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0) + | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0))); + } + else + { + mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask; + } + + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> chmod(%s,%o)\n", + (server_active) ? 'S' : ' ', fname, mode); +#else + (void) fprintf (stderr, "-> chmod(%s,%o)\n", fname, mode); +#endif + if (noexec) + return; + + if (chmod (fname, mode) < 0) + error (0, errno, "cannot change mode of file %s", fname); +} + +/* + * Rename a file and die if it fails + */ +void +rename_file (from_file, to_file) + const char *from_file; + const char *to_file; +{ + char from[PATH_MAX], to[PATH_MAX]; + + /* Prefer local relative paths to files at expense of logical name + access to files. */ + + if (isabsolute(from_file)) + strcpy(from, from_file); + else + sprintf(from, "./%s", from_file); + + if (isabsolute(to_file)) + strcpy(to, to_file); + else + sprintf(to, "./%s", to_file); + + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> rename(%s,%s)\n", + (server_active) ? 'S' : ' ', from, to); +#else + (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to); +#endif + if (noexec) + return; + + if (rename (from, to) < 0) + error (1, errno, "cannot rename file %s to %s", from, to); +} + +/* + * link a file, if possible. + */ +int +link_file (from_file, to_file) + const char *from_file; + const char *to_file; +{ + char from[PATH_MAX], to[PATH_MAX]; + + /* Prefer local relative paths to files at expense of logical name + access to files. */ + + if (isabsolute(from_file)) + strcpy(from, from_file); + else + sprintf(from, "./%s", from_file); + + if (isabsolute(to_file)) + strcpy(to, to_file); + else + sprintf(to, "./%s", to_file); + + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> link(%s,%s)\n", + (server_active) ? 'S' : ' ', from, to); +#else + (void) fprintf (stderr, "-> link(%s,%s)\n", from, to); +#endif + if (noexec) + return (0); + + return (link (from, to)); +} + +/* + * unlink a file, if possible. + */ +int +unlink_file (f_file) + const char *f_file; +{ + char f[PATH_MAX]; + + /* Prefer local relative paths to files at expense of logical name + access to files. */ + + if (isabsolute(f_file)) + strcpy(f, f_file); + else + sprintf(f, "./%s", f_file); + + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> unlink(%s)\n", + (server_active) ? 'S' : ' ', f); +#else + (void) fprintf (stderr, "-> unlink(%s)\n", f); +#endif + if (noexec) + return (0); + + return (unlink (f)); +} + +/* + * Unlink a file or dir, if possible. If it is a directory do a deep + * removal of all of the files in the directory. Return -1 on error + * (in which case errno is set). + */ +int +unlink_file_dir (f_file) + const char *f_file; +{ + char f[PATH_MAX]; + + /* Prefer local relative paths to files at expense of logical name + access to files. */ + + if (isabsolute(f_file)) + strcpy(f, f_file); + else + sprintf(f, "./%s", f_file); + + if (trace) +#ifdef SERVER_SUPPORT + (void) fprintf (stderr, "%c-> unlink_file_dir(%s)\n", + (server_active) ? 'S' : ' ', f); +#else + (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); +#endif + if (noexec) + return (0); + + if (unlink (f) != 0) + { + /* under NEXTSTEP errno is set to return EPERM if + * the file is a directory,or if the user is not + * allowed to read or write to the file. + * [This is probably a bug in the O/S] + * other systems will return EISDIR to indicate + * that the path is a directory. + */ + if (errno == EISDIR || errno == EPERM) + return deep_remove_dir (f); + else + /* The file wasn't a directory and some other + * error occured + */ + return -1; + } + /* We were able to remove the file from the disk */ + return 0; +} + +/* Remove a directory and everything it contains. Returns 0 for + * success, -1 for failure (in which case errno is set). + */ + +static int +deep_remove_dir (path) + const char *path; +{ + DIR *dirp; + struct dirent *dp; + char buf[PATH_MAX]; + + if (rmdir (path) != 0 && (errno == ENOTEMPTY || errno == EEXIST)) + { + if ((dirp = opendir (path)) == NULL) + /* If unable to open the directory return + * an error + */ + return -1; + + while ((dp = readdir (dirp)) != NULL) + { + if (strcmp (dp->d_name, ".") == 0 || + strcmp (dp->d_name, "..") == 0) + continue; + + sprintf (buf, "%s/%s", path, dp->d_name); + + if (unlink (buf) != 0 ) + { + if (errno == EISDIR || errno == EPERM) + { + if (deep_remove_dir (buf)) + { + closedir (dirp); + return -1; + } + } + else + { + /* buf isn't a directory, or there are + * some sort of permision problems + */ + closedir (dirp); + return -1; + } + } + } + closedir (dirp); + return rmdir (path); + } + + /* Was able to remove the directory return 0 */ + return 0; +} + +/* Read NCHARS bytes from descriptor FD into BUF. + Return the number of characters successfully read. + The number returned is always NCHARS unless end-of-file or error. */ +static size_t +block_read (fd, buf, nchars) + int fd; + char *buf; + size_t nchars; +{ + char *bp = buf; + size_t nread; + + do + { + nread = read (fd, bp, nchars); + if (nread == (size_t)-1) + { +#ifdef EINTR + if (errno == EINTR) + continue; +#endif + return (size_t)-1; + } + + if (nread == 0) + break; + + bp += nread; + nchars -= nread; + } while (nchars != 0); + + return bp - buf; +} + + +/* + * Compare "file1" to "file2". Return non-zero if they don't compare exactly. + */ +int +xcmp (file1_file, file2_file) + const char *file1_file; + const char *file2_file; +{ + char file1[PATH_MAX], file2[PATH_MAX]; + char *buf1, *buf2; + struct stat sb1, sb2; + int fd1, fd2; + int ret; + + /* Prefer local relative paths to files at expense of logical name + access to files. */ + + if (isabsolute(file1_file)) + strcpy(file1, file1_file); + else + sprintf(file1, "./%s", file1_file); + + if (isabsolute(file2_file)) + strcpy(file2, file2_file); + else + sprintf(file2, "./%s", file2_file); + + if ((fd1 = open (file1, O_RDONLY)) < 0) + error (1, errno, "cannot open file %s for comparing", file1); + if ((fd2 = open (file2, O_RDONLY)) < 0) + error (1, errno, "cannot open file %s for comparing", file2); + if (fstat (fd1, &sb1) < 0) + error (1, errno, "cannot fstat %s", file1); + if (fstat (fd2, &sb2) < 0) + error (1, errno, "cannot fstat %s", file2); + + /* A generic file compare routine might compare st_dev & st_ino here + to see if the two files being compared are actually the same file. + But that won't happen in CVS, so we won't bother. */ + + if (sb1.st_size != sb2.st_size) + ret = 1; + else if (sb1.st_size == 0) + ret = 0; + else + { + /* FIXME: compute the optimal buffer size by computing the least + common multiple of the files st_blocks field */ + size_t buf_size = 8 * 1024; + size_t read1; + size_t read2; + + buf1 = xmalloc (buf_size); + buf2 = xmalloc (buf_size); + + do + { + read1 = block_read (fd1, buf1, buf_size); + if (read1 == (size_t)-1) + error (1, errno, "cannot read file %s for comparing", file1); + + read2 = block_read (fd2, buf2, buf_size); + if (read2 == (size_t)-1) + error (1, errno, "cannot read file %s for comparing", file2); + + /* assert (read1 == read2); */ + + ret = memcmp(buf1, buf2, read1); + } while (ret == 0 && read1 == buf_size); + + free (buf1); + free (buf2); + } + + (void) close (fd1); + (void) close (fd2); + return (ret); +} + +unsigned char +VMS_filename_classes[] = +{ + 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, + 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27, + 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37, + 0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f, + 0x40,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, + 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, + 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, + 0x78,0x79,0x7a,0x5b, 0x5c,0x5d,0x5e,0x5f, + 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, + 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, + 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, + 0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f, + 0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f, + 0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97, + 0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f, + 0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7, + 0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf, + 0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7, + 0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf, + 0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7, + 0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf, + 0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7, + 0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf, + 0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7, + 0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef, + 0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7, + 0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff, +}; + +/* Like strcmp, but with the appropriate tweaks for file names. + Under VMS, filenames are case-insensitive but case-preserving. + FIXME: this should compare y.tab.c equal with y_tab.c, at least + if fnfold is modified (see below). */ +int +fncmp (const char *n1, const char *n2) +{ + while (*n1 && *n2 + && (VMS_filename_classes[(unsigned char) *n1] + == VMS_filename_classes[(unsigned char) *n2])) + n1++, n2++; + return (VMS_filename_classes[(unsigned char) *n1] + - VMS_filename_classes[(unsigned char) *n2]); +} + +/* Fold characters in FILENAME to their canonical forms. FIXME: this + probably should be mapping y.tab.c to y_tab.c but first we have to + figure out whether fnfold is the right hook for that functionality + (probable answer: yes, but it should not fold case on OS/2, VMS, or + NT. You see, fnfold isn't called anywhere, so we can define it to + mean whatever makes sense. Of course to solve the VMS y.tab.c + problem we'd need to call it where appropriate. It would need to + be redocumented as "fold to a form we can create in the filesystem" + rather than "canonical form"). The idea is that files we create + would get thusly munged, but CVS can cope with their names being + different the same way that the NT port copes with it if the user + renames a file from "foo" to "FOO". */ +void +fnfold (char *filename) +{ + while (*filename) + { + *filename = FOLD_FN_CHAR (*filename); + filename++; + } +} + +/* Generate a unique temporary filename. Returns a pointer to a newly + malloc'd string containing the name. Returns successfully or not at + all. */ +char * +cvs_temp_name () +{ + char value[L_tmpnam + 1]; + char *retval; + + /* FIXME: what is the VMS equivalent to TMPDIR? */ + retval = tmpnam (value); + if (retval == NULL) + error (1, errno, "cannot generate temporary filename"); + return xstrdup (retval); +} + +/* Return non-zero iff FILENAME is absolute. + Trivial under Unix, but more complicated under other systems. */ +int +isabsolute (filename) + const char *filename; +{ + if(filename[0] == '/' + || filename[0] == '[' + || filename[0] == '<' + || strchr(filename, ':')) + return 1; + else + return 0; +} + + +/* Return a pointer into PATH's last component. */ +char * +last_component (path) + char *path; +{ + char *last = strrchr (path, '/'); + + if (last) + return last + 1; + else + return path; +} + +/* Return the home directory. Returns a pointer to storage + managed by this function or its callees (currently getenv). */ +char * +get_homedir () +{ + return getenv ("HOME"); +} + +/* See cvs.h for description. On VMS this currently does nothing, although + I think we should be expanding wildcards here. */ +void +expand_wild (argc, argv, pargc, pargv) + int argc; + char **argv; + int *pargc; + char ***pargv; +{ + int i; + *pargc = argc; + *pargv = (char **) xmalloc (argc * sizeof (char *)); + for (i = 0; i < argc; ++i) + (*pargv)[i] = xstrdup (argv[i]); +} diff --git a/gnu/usr.bin/cvs/vms/filutils.c b/gnu/usr.bin/cvs/vms/filutils.c new file mode 100644 index 00000000000..748a677ad84 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/filutils.c @@ -0,0 +1,325 @@ +/* + * Copyright © 1994 the Free Software Foundation, Inc. + * + * Author: Richard Levitte (levitte@e.kth.se) + * + * This file is a part of GNU VMSLIB, the GNU library for porting GNU + * software to VMS. + * + * GNU VMSLIB 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 of the License, or + * (at your option) any later version. + * + * GNU VMSLIB 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. + * + * You should have received a copy of the GNU General Public License + * along with GNU VMSLIB; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <string.h> +#include <file.h> +#include <rmsdef.h> +#include <fab.h> +#include <nam.h> +#include <stdlib.h> +#include <lib$routines.h> +#include <descrip.h> +#include "filutils.h" + +/* file_name_as_directory was snarfed from src/fileio.c in GNU Emacs. */ + +char * +file_name_as_directory (out, in) + char *out, *in; +{ + int size = strlen (in) - 1; + int ext_point = 0; + + strcpy (out, in); + + /* Is it already a directory string? */ + if (in[size] == ':' || in[size] == ']' || in[size] == '>') + return out; + /* Is it a VMS directory file name? If so, hack VMS syntax. */ + else + if (! strchr (in, '/')) + { + ext_point = 1; + if (size > 3 && (! strcmp (&in[size - 3], ".DIR") + || ! strcmp (&in[size - 3], ".dir"))) + ext_point = -3; + else + if (size > 5 && (! strncmp (&in[size - 5], ".DIR", 4) + || ! strncmp (&in[size - 5], ".dir", 4)) + && (in[size - 1] == '.' || in[size - 1] == ';') + && in[size] == '1') + ext_point = -5; + } + if (ext_point != 0) + { + register char *p, *dot; + char brack; + + /* dir:[000000]x.dir --> dir:x.dir --> dir:[x] + dir:[000000.x]y.dir --> dir:[x]y.dir --> dir:[x.y] + but dir:[000000.000000]x.dir --> dir:[000000.000000.x] + dir:[000000.000000.x]y.dir --> dir:[000000.000000.x.y] */ + static char tem[256]; + + p = dot = strchr(in,':'); + if (p != 0 && (p[1] == '[' || p[1] == '<')) + { + p += 2; + if (strncmp(p,"000000",6) == 0) + { + p += 6; + if (strncmp(p,".000000",7) != 0 + && (*p == ']' || *p == '>' || *p == '.')) + { + size = dot - in + 1; + strncpy(tem, in, size); + if (*p == '.') + tem[size++] = '['; + strcpy(tem + size, p + 1); + in = tem; + size = strlen(in) - 1; + } + } + } + /* x.dir -> [.x] + dir:x.dir --> dir:[x] + dir:[x]y.dir --> dir:[x.y] */ + p = in + size; + while (p != in && *p != ':' && *p != '>' && *p != ']') p--; + { + char *emergency_dir = 0; + int emergency_point = 0; /* relative to the end of `out' */ + + if (p != in) + { + strncpy (out, in, p - in); + out[p - in] = '\0'; + if (*p == ':') + { + brack = ']'; + strcat (out, ":["); + emergency_dir = "000000"; + emergency_point = 0; + } + else + { + brack = *p; + strcat (out, "."); + emergency_dir = ""; + emergency_point = -1; + } + p++; + } + else + { + brack = ']'; + strcpy (out, "[."); + emergency_dir = ""; + emergency_point = -2; + } + if (strncmp (p, "000000.", 7) == 0 + && (strncmp (p+7, "000000", 6) != 0 + || (p[13] != ']' && p[13] != '>' && p[13] != '.'))) + p += 7; + if (p < (in + size + ext_point)) + { + register copy_len = ((in + size + ext_point) - p); + size = strlen (out) + copy_len; + strncat (out, p, copy_len); + } + else + { + size = strlen (out) + emergency_point; + strcpy (out + size, emergency_dir); + size += strlen (emergency_dir); + } + } + out[size++] = brack; + out[size] = '\0'; + } + return out; +} + +/* + * Convert from directory name to filename. + * On VMS: + * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1 + * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1 + * On UNIX, it's simple: just make sure there is a terminating / + + * Value is nonzero if the string output is different from the input. + */ + +/* directory_file_name was snarfed from src/fileio.c in GNU Emacs. */ + +#include <stdio.h> +directory_file_name (src, dst) + char *src, *dst; +{ + long slen; + long rlen; + char * ptr, * rptr; + char bracket; + struct FAB fab = cc$rms_fab; + struct NAM nam = cc$rms_nam; + char esa[NAM$C_MAXRSS]; + + slen = strlen (src); + + if (! strchr (src, '/') + && (src[slen - 1] == ']' + || src[slen - 1] == ':' + || src[slen - 1] == '>')) + { + /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */ + fab.fab$l_fna = src; + fab.fab$b_fns = slen; + fab.fab$l_nam = &nam; + fab.fab$l_fop = FAB$M_NAM; + + nam.nam$l_esa = esa; + nam.nam$b_ess = sizeof esa; + nam.nam$b_nop |= NAM$M_SYNCHK; + + /* We call SYS$PARSE to handle such things as [--] for us. */ + if (SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL) + { + slen = nam.nam$b_esl; + if (esa[slen - 1] == ';' && esa[slen - 2] == '.') + slen -= 2; + esa[slen] = '\0'; + src = esa; + } + if (src[slen - 1] != ']' && src[slen - 1] != '>') + { + /* what about when we have logical_name:???? */ + if (src[slen - 1] == ':') + { /* Xlate logical name and see what we get */ + ptr = strcpy (dst, src); /* upper case for getenv */ + while (*ptr) + { + if ('a' <= *ptr && *ptr <= 'z') + *ptr -= 040; + ptr++; + } + dst[slen - 1] = 0; /* remove colon */ + if (!(src = getenv (dst))) + return 0; + /* should we jump to the beginning of this procedure? + Good points: allows us to use logical names that xlate + to Unix names, + Bad points: can be a problem if we just translated to a device + name... + For now, I'll punt and always expect VMS names, and hope for + the best! */ + slen = strlen (src); + if (src[slen - 1] != ']' && src[slen - 1] != '>') + { /* no recursion here! */ + strcpy (dst, src); + return 0; + } + } + else + { /* not a directory spec */ + strcpy (dst, src); + return 0; + } + } + bracket = src[slen - 1]; + + /* If bracket is ']' or '>', bracket - 2 is the corresponding + opening bracket. */ + ptr = strchr (src, bracket - 2); + if (ptr == 0) + { /* no opening bracket */ + strcpy (dst, src); + return 0; + } + if (!(rptr = strrchr (src, '.'))) + rptr = ptr; + slen = rptr - src; + strncpy (dst, src, slen); + dst[slen] = '\0'; +#if 0 + fprintf (stderr, "dst = \"%s\"\nsrc = \"%s\"\nslen = %d\n", + dst, src, slen); +#endif + if (*rptr == '.') + { + dst[slen++] = bracket; + dst[slen] = '\0'; + } + else + { + /* If we have the top-level of a rooted directory (i.e. xx:[000000]), + then translate the device and recurse. */ + if (dst[slen - 1] == ':' + && dst[slen - 2] != ':' /* skip decnet nodes */ + && ((src[slen] == '[' + && strcmp(src + slen + 1, "000000]") == 0) + || src[slen] == '<' + && strcmp(src + slen + 1, "000000>") == 0)) + { + static char equiv_buf[256]; + static struct dsc$descriptor_s equiv + = {sizeof (equiv_buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, equiv_buf}; + static struct dsc$descriptor_s d_name + = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0}; + short eqlen; + + dst[slen - 1] = '\0'; + d_name.dsc$w_length = strlen (dst); + d_name.dsc$a_pointer = dst; + if (LIB$SYS_TRNLOG (&d_name, &eqlen, &equiv) == 1 + && (equiv_buf[eqlen] = '\0', ptr = equiv_buf) != 0 + && (rlen = strlen (ptr) - 1) > 0 + && (ptr[rlen] == ']' || ptr[rlen] == '>') + && ptr[rlen - 1] == '.') + { + char * buf = (char *) malloc (strlen (ptr) + 1); + int tmp = ptr[rlen]; + if (buf == 0) + return 0; /* bad luck */ + strcpy (buf, ptr); + buf[rlen - 1] = tmp; + buf[rlen] = '\0'; + tmp = directory_file_name (buf, dst); + free (buf); + return tmp; + } + else + dst[slen - 1] = ':'; + } + strcat (dst, "[000000]"); + slen += 8; + } + rptr++; + rlen = strlen (rptr) - 1; + strncat (dst, rptr, rlen); + dst[slen + rlen] = '\0'; + strcat (dst, ".DIR.1"); + return 1; + } + + /* Process as Unix format: just remove any final slash. + But leave "/" unchanged; do not change it to "". */ + strcpy (dst, src); + if (slen > 1 && dst[slen - 1] == '/') + { + dst[slen - 1] = 0; + return 1; + } + return 0; +} + +/* end of snarf. */ diff --git a/gnu/usr.bin/cvs/vms/filutils.h b/gnu/usr.bin/cvs/vms/filutils.h new file mode 100644 index 00000000000..6605353049f --- /dev/null +++ b/gnu/usr.bin/cvs/vms/filutils.h @@ -0,0 +1,25 @@ +/* + * Copyright © 1994 the Free Software Foundation, Inc. + * + * Author: Richard Levitte (levitte@e.kth.se) + * + * This file is a part of GNU VMSLIB, the GNU library for porting GNU + * software to VMS. + * + * GNU VMSLIB 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 of the License, or + * (at your option) any later version. + * + * GNU VMSLIB 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. + * + * You should have received a copy of the GNU General Public License + * along with GNU VMSLIB; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +char *file_name_as_directory (); +int directory_file_name (); diff --git a/gnu/usr.bin/cvs/vms/getpass.c b/gnu/usr.bin/cvs/vms/getpass.c new file mode 100644 index 00000000000..3b495c4d1a9 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/getpass.c @@ -0,0 +1,30 @@ +#include <stdio.h> +#include <curses.h> + +char * +getpass (char *prompt) +{ + /* FIXME: arbitrary limit; I think we need to ditch getstr to fix it. */ + static char buf[2048]; + + /* This clears the screen, which is *not* what we want. But until I + get some real VMS documentation.... */ + initscr (); + + printw ("%s", prompt); + refresh (); + noecho (); + getstr (buf); + endwin (); + printf ("\n"); + return buf; +} + +#if 0 +int +main () +{ + printf ("thank you for saying \"%s\"\n", getpass ("What'll it be? ")); + return 0; +} +#endif diff --git a/gnu/usr.bin/cvs/vms/getwd.c b/gnu/usr.bin/cvs/vms/getwd.c new file mode 100644 index 00000000000..db1e9c56913 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/getwd.c @@ -0,0 +1,6 @@ +#include <unixlib.h> + +char *getwd(char *pathname) +{ + return getcwd(pathname, 256, 0); +} diff --git a/gnu/usr.bin/cvs/vms/misc.c b/gnu/usr.bin/cvs/vms/misc.c new file mode 100644 index 00000000000..78bb27378f3 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/misc.c @@ -0,0 +1,201 @@ +/* + * Copyright © 1994 the Free Software Foundation, Inc. + * + * Author: Roland B. Roberts (roberts@nsrl.rochester.edu) + * + * This file is a part of GNU VMSLIB, the GNU library for porting GNU + * software to VMS. + * + * GNU VMSLIB 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 of the License, or + * (at your option) any later version. + * + * GNU VMSLIB 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. + * + * You should have received a copy of the GNU General Public License + * along with GNU VMSLIB; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Miscellaneous utilities used by hackargv(). + * Some of these are useful in their own right. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <lib$routines.h> + +/* Print message and force core dump (unix) or traceback (vms) + * These are taken from other GNU software more-or-less as-is + */ +void fatal (char *s) +{ + int *x; + printf ("%s\n", s); + lib$signal(44); +} + +/* GNU's lib implementation (alloca.c) is more portable, so I disabled these + for this distribution (benjamin@cyclic.com) */ +#ifdef USE_VMSLIB_MEMORY_ALLOCATION +void *xmalloc (int size) +{ + register void *val; + /* Avoid failure if malloc (0) returns 0. */ + if (size == 0) + size = 1; + val = (void *) malloc (size); + if (!val) fatal ("xmalloc: can't satisfy request"); + return val; +} + +void *xrealloc (void *block, int size) +{ + register void *val; + /* Avoid failure if malloc (0) returns 0. */ + if (size == 0) + size = 1; + val = (void *) realloc (block, size); + if (!val) fatal ("xrealloc: can't satisfy request"); + return val; +} +#endif + +/* See in misc.h why it is done like this. */ +void x_free (void *block) +{ + free (block); +} + +/* + * Some string utilities. + */ +char *downcase (char *s) +{ + register char *t; + for (t = s ; *t; t++) + *t = tolower(*t); + return (s); +} + +char *strdup (char *src) { + char *dst = (char*) xmalloc (strlen(src) + 1); + strcpy (dst, src); + return (dst); +} + +char *strndup (char *src, int len) { + char *dst = (char *) xmalloc (len + 1); + strncpy (dst, src, len); + dst[len] = 0; + return (dst); +} + +#include <string.h> + +/* + * int fixpath (char *path) + * + * Synopsis: + * `Fix' VMS pathnames, converting them to canonical form. + * + * Description: + * The following conversions are performed + * x:[y.][000000.z] --> x:[y.z] + * x:[y.][z] --> x:[y.z] + * x:[000000.y] --> x:[y] + * + * Author: + * Roland B Roberts (roberts@nsrl.rochester.edu) + * March 1994 + */ +int fixpath (char *path) +{ + char *s, *d, *t; + int skip = 0; + d = s = path; + if (t = strstr(path ,".][000000")) + skip = 9; + else if (t = strstr(path,"][")) + skip = 2; + else if (t = strstr(path,"[000000.")) + t++, skip = 7; + if (t) { + while (s < t) + *d++ = *s++; + s += skip; + while (*d++ = *s++); + } + return 0; +} + + +#include <ctype.h> +#include <string.h> + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +/* + * char *argvconcat (int argc, char **argv) + * + * Synopsis: + * Concatenate all elements of argv into a single string suitable for + * use as a command line. + * + * Description: + * This is intended for use with hackargv() in order to build a command + * line for background() or popen(). Each element of argv (except the + * first) is surrounded by double quotes to insure the command line is + * unaltered when DCL rereads it. + * + * Side Effect: + * Space for the new string is allocated with xmalloc(). + * + * Author: + * Roland B Roberts (roberts@nsrl.rochester.edu) + * March 1994 + */ + +char *argvconcat (int argc, char **argv) +{ + int i, j, n, addquotes, flags, pid, status; + char *cmdline; + /* + * Allocate space + */ + for (j = n = 0; j < argc; j++) + n += 3 + strlen(argv[j]); /* Need 3 extra spaces, not 1; see below */ + cmdline = (char *) xmalloc ((n + 1) * sizeof (char)); + sprintf (cmdline, "%s ", argv[0]); + for (j = 1, addquotes = FALSE; j < argc; j++) { + /* + * Add double quotes to arg if it contains uppercase of spaces. + * Hence, the need to allocate three extra spaces for each argument. + */ + for (i = 0; i < strlen(argv[j]); i++) + if (isupper(argv[j][i]) || isspace(argv[j][i])) { + addquotes = TRUE; + break; + } + if (addquotes) { + strcat (cmdline, argv[j]); + strcat (cmdline, " "); + } + else { + strcat (cmdline, "\""); /* use quotes to preserve case */ + strcat (cmdline, argv[j]); + strcat (cmdline, "\" "); + } + } + cmdline[strlen(cmdline)-1] = 0; + return (cmdline); +} diff --git a/gnu/usr.bin/cvs/vms/misc.h b/gnu/usr.bin/cvs/vms/misc.h new file mode 100644 index 00000000000..0494b16698e --- /dev/null +++ b/gnu/usr.bin/cvs/vms/misc.h @@ -0,0 +1,40 @@ +/* + * Copyright © 1994 the Free Software Foundation, Inc. + * + * Author: Richard Levitte (levitte@e.kth.se) + * + * This file is a part of GNU VMSLIB, the GNU library for porting GNU + * software to VMS. + * + * GNU VMSLIB 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 of the License, or + * (at your option) any later version. + * + * GNU VMSLIB 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. + * + * You should have received a copy of the GNU General Public License + * along with GNU VMSLIB; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +void fatal (); +void *xmalloc (); +void *xrealloc (); +void x_free(); +/* This is a trick, because the linker wants uppercase symbols, and in + that case, xfree is confused with Xfree, which is bad. */ +#define xfree x_free + +/* + * Some string utilities. + */ +char *downcase (); +char *strdup (); +char *strndup (); + +int fixpath (); +char *argvconcat (); diff --git a/gnu/usr.bin/cvs/vms/ndir.c b/gnu/usr.bin/cvs/vms/ndir.c new file mode 100644 index 00000000000..87fb0cb070a --- /dev/null +++ b/gnu/usr.bin/cvs/vms/ndir.c @@ -0,0 +1,308 @@ +/* + * Copyright © 1994 the Free Software Foundation, Inc. + * + * Author: Richard Levitte (levitte@e.kth.se) + * + * This file is a part of GNU VMSLIB, the GNU library for porting GNU + * software to VMS. + * + * GNU VMSLIB 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 of the License, or + * (at your option) any later version. + * + * GNU VMSLIB 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. + * + * You should have received a copy of the GNU General Public License + * along with GNU VMSLIB; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <varargs.h> +#include <rms.h> +#include <descrip.h> +#include <string.h> +#include <errno.h> + +#ifdef __GNUC__ +#include <sys/stat.h> +#else +#include <stat.h> +#endif +#include <lib$routines.h> + +#include "ndir.h" +#include "filutils.h" + +/* The following was snarfed from lib-src/alloca.c in GNU Emacs, + the hacked. */ + +#if __STDC__ +typedef void procedure; +typedef void *pointer; +#else +typedef int procedure; +typedef char *pointer; +#endif + +/* Different portions of Emacs need to call different versions of + malloc. The Emacs executable needs alloca to call xmalloc, because + ordinary malloc isn't protected from input signals. On the other + hand, the utilities in lib-src need alloca to call malloc; some of + them are very simple, and don't have an xmalloc routine. + + Non-Emacs programs expect this to call use xmalloc. + + Callers below should use malloc. + + There is some need for BLOCK_INPUT and UNBLOCK_INPUT, but it is really + only used in Emacs, so that's the only time it's used. Otherwise, + they are just empty statements. */ + +#ifndef emacs +#include "misc.h" +#define malloc xmalloc +#define free xfree +#endif + +#if 0 +extern pointer malloc (); +extern procedure free (); +#endif + +/* end of snarf. */ + +#ifndef BLOCK_INPUT +#define BLOCK_INPUT +#endif +#ifndef UNBLOCK_INPUT +#define UNBLOCK_INPUT +#endif + +static struct direct *vms_low_readdir (); + +typedef struct +{ + DIR s_dir; + unsigned long context; + unsigned long uflags; + struct dsc$descriptor_s dir_spec; + struct dsc$descriptor_s file_spec; + int version_flag; + unsigned long status; +} VMS_DIR; + +DIR * +opendir (infilename, filepattern) + char *infilename; /* name of directory */ + char *filepattern; +{ + register VMS_DIR *dirp; /* -> malloc'ed storage */ + register unsigned int length = 1024; + register int fd; /* file descriptor for read */ + char *filename; + struct stat sbuf; /* result of fstat */ + + filename = (char *) malloc(length+1); + strcpy(filename, infilename); + + strip_path(filename); + if(strcmp(filename, ".") == 0) + { + getcwd(filename, length+1, 1); /* Get a VMS filespec */ + length = strlen(filename); + } + + BLOCK_INPUT; + if ((filename[length-1] != ']' + && filename[length-1] != '>' + && filename[length-1] != ':' + && (stat (filename, &sbuf) < 0 + || (sbuf.st_mode & S_IFMT) != S_IFDIR))) + { + errno = ENOTDIR; + UNBLOCK_INPUT; + free(filename); + return 0; /* bad luck today */ + } + + if ((dirp = (VMS_DIR *) xmalloc (sizeof (VMS_DIR))) == 0) + { + errno = ENOMEM; + UNBLOCK_INPUT; + free(filename); + return 0; /* bad luck today */ + } + + { + int count; + va_count(count); + if (count == 2) + { + dirp->file_spec.dsc$a_pointer = + (char *) xmalloc (strlen (filepattern) + 1); + strcpy (dirp->file_spec.dsc$a_pointer, filepattern); + } + else + { + dirp->file_spec.dsc$a_pointer = + (char *) xmalloc (4); + strcpy (dirp->file_spec.dsc$a_pointer, "*.*"); + } + dirp->file_spec.dsc$w_length = strlen (dirp->file_spec.dsc$a_pointer); + dirp->file_spec.dsc$b_dtype = DSC$K_DTYPE_T; + dirp->file_spec.dsc$b_class = DSC$K_CLASS_S; + dirp->version_flag = strchr (dirp->file_spec.dsc$a_pointer, ';') != 0; + } + dirp->dir_spec.dsc$a_pointer = (char *) xmalloc (strlen (filename) + 10); + UNBLOCK_INPUT; + file_name_as_directory (dirp->dir_spec.dsc$a_pointer, filename); + dirp->dir_spec.dsc$w_length = strlen (dirp->dir_spec.dsc$a_pointer); + dirp->dir_spec.dsc$b_dtype = DSC$K_DTYPE_T; + dirp->dir_spec.dsc$b_class = DSC$K_CLASS_S; + dirp->context = 0; + dirp->uflags = 2; + dirp->s_dir.dd_fd = 0; + dirp->s_dir.dd_loc = dirp->s_dir.dd_size = 0; /* refill needed */ + + free(filename); + + /* In the cases where the filename ended with `]', `>' or `:', + we never checked if it really was a directory, so let's do that + now, by trying to read the first entry. */ + if (vms_low_readdir ((DIR *) dirp) == (struct direct *) -1) + { + closedir (dirp); /* was: xfree (dirp); */ + errno = ENOENT; + return 0; + } + dirp->s_dir.dd_loc = 0; /* Make sure the entry just read is + reused at the next call to readdir. */ + + return (DIR *) dirp; /* I had to cast, for VMS sake. */ +} + +void +closedir (dirp) + register DIR *dirp; /* stream from opendir */ +{ + { + VMS_DIR *vms_dirp = (VMS_DIR *) dirp; + + if (vms_dirp->context != 0) + lib$find_file_end (&(vms_dirp->context)); + xfree (vms_dirp->dir_spec.dsc$a_pointer); + xfree (vms_dirp->file_spec.dsc$a_pointer); + } + + xfree ((char *) dirp); +} + +struct direct dir_static; /* simulated directory contents */ + +static struct direct * +vms_low_readdir (dirp) + register DIR *dirp; +{ + static char rbuf[257]; + static struct dsc$descriptor_s rdsc = + { sizeof (rbuf), DSC$K_DTYPE_T, DSC$K_CLASS_S, rbuf }; + VMS_DIR * vms_dirp = (VMS_DIR *) dirp; + + if (dirp->dd_size == 0) + { + char *cp, *cp2; + unsigned long status; + + status = lib$find_file (&vms_dirp->file_spec, &rdsc, &vms_dirp->context, + &vms_dirp->dir_spec, 0, 0, &vms_dirp->uflags); + vms_dirp->status = status; + if (status == RMS$_NMF || status == RMS$_FNF) + return 0; + if (status != RMS$_NORMAL) + return (struct direct *) -1; + + rbuf [256] = '\0'; + if (cp = strchr (rbuf, ' ')) + *cp = '\0'; + if ((cp = strchr (rbuf, ';')) != 0 + && !vms_dirp->version_flag) + *cp = '\0'; + + for (cp2 = rbuf - 1; cp2 != 0;) + { + char *cp2tmp = 0; + cp = cp2 + 1; + cp2 = strchr (cp, ']'); + if (cp2 != 0) + cp2tmp = strchr (cp2 + 1, '>'); + if (cp2tmp != 0) + cp2 = cp2tmp; + } + + /* Propagate names as lower case only, + directories have ".dir" truncated, + do not propagate null extensions "makefile." */ + { + char *p, *q; + + if(strcmp(cp, "CVS.DIR") == 0) + strcpy(dirp->dd_buf, "CVS"); + else + { + for(p = cp, q = dirp->dd_buf; *p;) + { + if(strcmp(p, ".DIR") == 0) + break; + else + *q++ = tolower(*p++); + } + *q = '\0'; + if(*(q-1) == '.') + *(q-1) = '\0'; + } + } +#if 0 + strcpy (dirp->dd_buf, cp); +#endif + + dirp->dd_size = strlen (dirp->dd_buf); + dirp->dd_loc = 0; + } + + if (vms_dirp->status != RMS$_NORMAL) + return 0; + + dir_static.d_ino = -1; /* Couldn't care less... */ + dir_static.d_namlen = strlen (dirp->dd_buf); + dir_static.d_reclen = sizeof (struct direct) + - MAXNAMLEN + 3 + + dir_static.d_namlen - dir_static.d_namlen % 4; + strcpy (dir_static.d_name, dirp->dd_buf); + dir_static.d_name[dir_static.d_namlen] = '\0'; + dirp->dd_loc = dirp->dd_size; /* only one record at a time */ + + return &dir_static; +} + +/* ARGUSED */ +struct direct * +readdir (dirp) + register DIR *dirp; /* stream from opendir */ +{ + register struct direct *dp; + + for (; ;) + { + if (dirp->dd_loc >= dirp->dd_size) + dirp->dd_loc = dirp->dd_size = 0; + + dp = vms_low_readdir (dirp); + if (dp == 0 || dp == (struct direct *) -1) + return 0; + return dp; + } +} diff --git a/gnu/usr.bin/cvs/vms/ndir.h b/gnu/usr.bin/cvs/vms/ndir.h new file mode 100644 index 00000000000..1bc59f708b6 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/ndir.h @@ -0,0 +1,57 @@ +/* + <ndir.h> -- definitions for 4.2BSD-compatible directory access + + last edit: 28-dec-1994 Richard Levitte +*/ + +#if 0 +#ifndef FAB$C_BID +#include <fab.h> +#endif +#endif +#ifndef NAM$C_BID +#include <nam.h> +#endif +#if 0 +#ifndef RMS$_SUC +#include <rmsdef.h> +#endif +#include <dir.h> +#else +#define DIR$S_NAME 80 +#endif + +#define DIRBLKSIZ 512 /* size of directory block */ +#ifdef VMS +#define MAXNAMLEN (DIR$S_NAME + 7) /* 80 plus room for version #. */ +#define MAXFULLSPEC NAM$C_MAXRSS /* Maximum full spec */ +#else +#define MAXNAMLEN 15 /* maximum filename length */ +#endif /* VMS */ + /* NOTE: MAXNAMLEN must be one less than a multiple of 4 */ + +struct direct /* data from readdir() */ + { + long d_ino; /* inode number of entry */ + unsigned short d_reclen; /* length of this record */ + unsigned short d_namlen; /* length of string in d_name */ + char d_name[MAXNAMLEN+1]; /* name of file */ + }; + +typedef struct + { + int dd_fd; /* file descriptor */ + int dd_loc; /* offset in block */ + int dd_size; /* amount of valid data */ + char dd_buf[DIRBLKSIZ]; /* directory block */ + } DIR; /* stream data from opendir() */ + +extern DIR *opendir(); +extern struct direct *readdir(); +#ifndef VMS +extern long telldir(); +extern void seekdir(); +#endif +extern void closedir(); + +#define rewinddir( dirp ) seekdir( dirp, 0L ) diff --git a/gnu/usr.bin/cvs/vms/options.h b/gnu/usr.bin/cvs/vms/options.h new file mode 100644 index 00000000000..92a03426ad4 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/options.h @@ -0,0 +1,279 @@ +/* + * Copyright (c) 1992, Brian Berliner and Jeff Polk + * Copyright (c) 1989-1992, Brian Berliner + * + * You may distribute under the terms of the GNU General Public License as + * specified in the README file that comes with the CVS 1.4 kit. + * + * This file holds (most of) the configuration tweaks that can be made to + * customize CVS for your site. CVS comes configured for a typical SunOS 4.x + * environment. The comments for each configurable item are intended to be + * self-explanatory. All #defines are tested first to see if an over-riding + * option was specified on the "make" command line. + * + * If special libraries are needed, you will have to edit the Makefile.in file + * or the configure script directly. Sorry. + */ + +/* + * CVS provides the most features when used in conjunction with the Version-5 + * release of RCS. Thus, it is the default. This also assumes that GNU diff + * Version-1.15 is being used as well -- you will have to configure your RCS + * V5 release separately to make this the case. If you do not have RCS V5 and + * GNU diff V1.15, comment out this define. You should not try mixing and + * matching other combinations of these tools. + */ +#ifndef HAVE_RCS5 +#define HAVE_RCS5 +#endif + +/* + * If, before installing this version of CVS, you were running RCS V4 AND you + * are installing this CVS and RCS V5 and GNU diff 1.15 all at the same time, + * you should turn on the following define. It only exists to try to do + * reasonable things with your existing checked out files when you upgrade to + * RCS V5, since the keyword expansion formats have changed with RCS V5. + * + * If you already have been running with RCS5, or haven't been running with CVS + * yet at all, or are sticking with RCS V4 for now, leave the commented out. + */ +#ifndef HAD_RCS4 +/* #define HAD_RCS4 */ +#endif + +/* + * For portability and heterogeneity reasons, CVS is shipped by default using + * my own text-file version of the ndbm database library in the src/myndbm.c + * file. If you want better performance and are not concerned about + * heterogeneous hosts accessing your modules file, turn this option off. + */ +#ifndef MY_NDBM +#define MY_NDBM +#endif + +/* + * The "diff" program to execute when creating patch output. This "diff" + * must support the "-c" option for context diffing. Specify a full + * pathname if your site wants to use a particular diff. If you are + * using the GNU version of diff (version 1.15 or later), this should + * be "diff -a". + * + * NOTE: this program is only used for the ``patch'' sub-command (and + * for ``update'' if you are using the server). The other commands + * use rcsdiff which will use whatever version of diff was specified + * when rcsdiff was built on your system. + */ + +#ifndef DIFF +#define DIFF "/usr/local/bin/diff -a" +#endif + +/* + * The "grep" program to execute when checking to see if a merged file had + * any conflicts. This "grep" must support a standard basic + * regular expression as an argument. Specify a full pathname if your site + * wants to use a particular grep. + */ + +#ifndef GREP +#define GREP "grep" +#endif + +/* + * The "patch" program to run when using the CVS server and accepting + * patches across the network. Specify a full pathname if your site + * wants to use a particular patch. + */ +#ifndef PATCH_PROGRAM +#define PATCH_PROGRAM "patch" +#endif + +/* + * By default, RCS programs are executed with the shell or through execlp(), + * so the user's PATH environment variable is searched. If you'd like to + * bind all RCS programs to a certain directory (perhaps one not in most + * people's PATH) then set the default in RCSBIN_DFLT. Note that setting + * this here will cause all RCS programs to be executed from this directory, + * unless the user overrides the default with the RCSBIN environment variable + * or the "-b" option to CVS. + * + * If you use the password-authenticating server, then you need to + * make sure that the server can find the RCS programs to invoke them. + * The authenticating server starts out running as root, and then + * switches to run as the appropriate user once authentication is + * complete. But no actual shell is ever started by that user, so the + * PATH environment variable may not contain the directory with the + * RCS binaries, even though if that user logged in normally, PATH + * would include the directory. + * + * One way to solve this problem is to set RCSBIN_DFLT here. An + * alternative is to make sure that root has the right directory in + * its path already. Another, probably better alternative is to + * specify -b in /etc/inetd.conf. + * + * This define should be either the empty string ("") or a full pathname to the + * directory containing all the installed programs from the RCS distribution. */ +#ifndef RCSBIN_DFLT +#define RCSBIN_DFLT "" +#endif + +/* + * The password-authenticating server creates a temporary checkout of + * the affected files. The variable TMPDIR_DFLT (or even better, the + * command-line option "-T" in the line for CVS in /etc/inetd.conf) + * can be used to specify the used directory. This directory will + * also be used for other temporary files. + */ +#ifndef TMPDIR_DFLT +#define TMPDIR_DFLT "sys$scratch" +#endif + +/* + * The default editor to use, if one does not specify the "-e" option to cvs, + * or does not have an EDITOR environment variable. I set this to just "vi", + * and use the shell to find where "vi" actually is. This allows sites with + * /usr/bin/vi or /usr/ucb/vi to work equally well (assuming that your PATH + * is reasonable). + */ +#ifndef EDITOR_DFLT +#define EDITOR_DFLT "" +#endif + +/* + * The default umask to use when creating or otherwise setting file or + * directory permissions in the repository. Must be a value in the + * range of 0 through 0777. For example, a value of 002 allows group + * rwx access and world rx access; a value of 007 allows group rwx + * access but no world access. This value is overridden by the value + * of the CVSUMASK environment variable, which is interpreted as an + * octal number. + */ +#ifndef UMASK_DFLT +#define UMASK_DFLT 002 +#endif + +/* + * The cvs admin command is restricted to the members of the group + * CVS_ADMIN_GROUP. If this group does not exist, all users are + * allowed to run cvs admin. To disable the cvs admin for all users, + * create an empty group CVS_ADMIN_GROUP. To disable access control for + * cvs admin, comment out the define below. + */ +#ifndef CVS_ADMIN_GROUP +/* #define CVS_ADMIN_GROUP "cvsadmin" */ +#endif + +/* + * The Repository file holds the path to the directory within the source + * repository that contains the RCS ,v files for each CVS working directory. + * This path is either a full-path or a path relative to CVSROOT. + * + * The only advantage that I can see to having a relative path is that One can + * change the physical location of the master source repository, change one's + * CVSROOT environment variable, and CVS will work without problems. I + * recommend using full-paths. + */ +#ifndef RELATIVE_REPOS +/* #define RELATIVE_REPOS */ +#endif + +/* + * When committing or importing files, you must enter a log message. + * Normally, you can do this either via the -m flag on the command line or an + * editor will be started for you. If you like to use logging templates (the + * rcsinfo file within the $CVSROOT/CVSROOT directory), you might want to + * force people to use the editor even if they specify a message with -m. + * Enabling FORCE_USE_EDITOR will cause the -m message to be appended to the + * temp file when the editor is started. + */ +#ifndef FORCE_USE_EDITOR +/* #define FORCE_USE_EDITOR */ +#endif + +/* + * When locking the repository, some sites like to remove locks and assume + * the program that created them went away if the lock has existed for a long + * time. This used to be the default for previous versions of CVS. CVS now + * attempts to be much more robust, so lock files should not be left around + * by mistake. The new behaviour will never remove old locks (they must now + * be removed by hand). Enabling CVS_FUDGELOCKS will cause CVS to remove + * locks that are older than CVSLCKAGE seconds. + * Use of this option is NOT recommended. + */ +#ifndef CVS_FUDGELOCKS +/* #define CVS_FUDGELOCKS */ +#endif + +/* + * When committing a permanent change, CVS and RCS make a log entry of + * who committed the change. If you are committing the change logged in + * as "root" (not under "su" or other root-priv giving program), CVS/RCS + * cannot determine who is actually making the change. + * + * As such, by default, CVS disallows changes to be committed by users + * logged in as "root". You can disable this option by commenting + * out the lines below. + */ +#ifndef CVS_BADROOT +#define CVS_BADROOT +#endif + +/* + * The "cvs diff" command accepts all the single-character options that GNU + * diff (1.15) accepts. Except -D. GNU diff uses -D as a way to put + * cpp-style #define's around the output differences. CVS, by default, uses + * -D to specify a free-form date (like "cvs diff -D '1 week ago'"). If + * you would prefer that the -D option of "cvs diff" work like the GNU diff + * option, then comment out this define. + */ +#ifndef CVS_DIFFDATE +#define CVS_DIFFDATE +#endif + +/* + * Yes, we can do the authenticated client. + */ +#define AUTH_CLIENT_SUPPORT 1 + +/* + * define this to enable the SETXID support. Probably has no effect on VMS. + */ +#ifndef SETXID_SUPPORT +/* #define SETXID_SUPPORT */ +#endif + +/* + * If you are working with a large remote repository and a 'cvs checkout' is + * swamping your network and memory, define these to enable flow control. + * You will end up with even less guarantees of a consistant checkout, + * but that may be better than no checkout at all. The master server process + * will monitor how far it is getting behind, if it reaches the high water + * mark, it will signal the child process to stop generating data when + * convenient (ie: no locks are held, currently at the beginning of a + * new directory). Once the buffer has drained sufficiently to reach the + * low water mark, it will be signalled to start again. + * -- EXPERIMENTAL! -- A better solution may be in the works. + * You may override the default hi/low watermarks here too. + */ +#ifndef SERVER_FLOWCONTROL +/* #define SERVER_FLOWCONTROL */ +/* #define SERVER_HI_WATER (2 * 1024 * 1024) */ +/* #define SERVER_LO_WATER (1 * 1024 * 1024) */ +#endif + +/* End of CVS configuration section */ + +/* + * Externs that are included in libc, but are used frequently enough to + * warrant defining here. + */ +#ifndef STDC_HEADERS +extern void exit (); +#endif + +#ifndef getwd +extern char *getwd (); +#endif + +#define NO_SOCKET_TO_FD 1 +#include "vms.h" diff --git a/gnu/usr.bin/cvs/vms/pathnames.h b/gnu/usr.bin/cvs/vms/pathnames.h new file mode 100644 index 00000000000..a4d2aada45f --- /dev/null +++ b/gnu/usr.bin/cvs/vms/pathnames.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)pathnames.h 5.2 (Berkeley) 4/9/90 + * $Id: pathnames.h,v 1.1 1996/10/18 03:37:10 tholo Exp $ + */ + +#define _PATH_RLOGIN "/usr/bin/rlogin" diff --git a/gnu/usr.bin/cvs/vms/pc.c b/gnu/usr.bin/cvs/vms/pc.c new file mode 100644 index 00000000000..5868a7f8494 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/pc.c @@ -0,0 +1,62 @@ +#include <stdio.h> +#include <unixio.h> +#include <stdlib.h> +#include <string.h> + +int trace = 1; + +extern int piped_child(); +extern int piped_child_shutdown(); + +main (argc, argv) + int argc; + char ** argv; +{ + static char line[512]; + char *linep[] = {line, NULL}; + int pid; + int tofd, fromfd; + FILE *in, *out; + + while (1) + { + printf("\nEnter a command to run: "); + line[0] = '\0'; + fgets(line, 511, stdin); + if (!strlen(line)) + exit(2); + + line[strlen(line)-1] = '\0'; + pid = piped_child(linep, &tofd, &fromfd); + + in = fdopen(fromfd, "r"); + out = fdopen(tofd, "w"); + +#if 0 + out = fdopen(tofd, "w"); + fclose(out); +#endif + + do + { + if(!feof(stdin)) + { + fprintf(stdout, "> "); + fgets(line, 511, stdin); + fputs(line, out); + } + else + { + fclose(out); + close(tofd); + } + + fgets(line, 511, in); + fputs(line, stdout); + line[0] = '\0'; + } while (!feof(in)); + + fprintf(stderr, "waiting for child to stop\n"); + piped_child_shutdown(pid); + } +} diff --git a/gnu/usr.bin/cvs/vms/pipe.c b/gnu/usr.bin/cvs/vms/pipe.c new file mode 100644 index 00000000000..d6078df8e0e --- /dev/null +++ b/gnu/usr.bin/cvs/vms/pipe.c @@ -0,0 +1,440 @@ +/* + * Copyright © 1994 the Free Software Foundation, Inc. + * + * Author: Roland B. Roberts (roberts@nsrl.rochester.edu) + * + * This file is a part of GNU VMSLIB, the GNU library for porting GNU + * software to VMS. + * + * GNU VMSLIB 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 of the License, or + * (at your option) any later version. + * + * GNU VMSLIB 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. + * + * You should have received a copy of the GNU General Public License + * along with GNU VMSLIB; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Modification History + * 13 Sep 94 - RBR + * Use event flag one -- zero seems to cause sys$synch to hang. + * 12 Sep 94 - RBR + * All pipes now use event flag zero. + * Removed the limit on the number of pipes. + * Added members to PIPE structure and memory corruption tests. + */ + +/* This won't work with GCC, but it won't cause any problems either. */ +#define MODULE PIPE +#define VERSION "V1.5" + +#ifdef __DECC +#pragma module MODULE VERSION +#else +#ifdef VAXC +#module MODULE VERSION +#endif +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <iodef.h> +#include <ssdef.h> +#include <syidef.h> +#include <clidef.h> +#include <stsdef.h> +#include <dvidef.h> +#include <nam.h> +#include <descrip.h> +#include <errno.h> +#include <file.h> +#include <lib$routines.h> +#include <starlet.h> +#include <setjmp.h> +#include "vms-types.h" + +/* A linked list of pipes, for internal use only */ +struct PIPE +{ + struct PIPE *next; /* next pipe in the chain */ + struct PIPE *prev; /* previous pipe in the chain */ + struct PIPE *self; /* self reference */ + int mode; /* pipe I/O mode (read or write) */ + long status; /* subprocess completion status */ + struct IOSB iosb; /* pipe I/O status block */ + FILE *file; /* pipe file structure */ + int pid; /* pipe process id */ + short chan; /* pipe channel */ + jmp_buf jmpbuf; /* jump buffer, if needed */ + int has_jmpbuf; /* flag */ +}; + +/* Head of the pipe chain */ +static struct PIPE *phead = NULL, *ptail = NULL; + +static unsigned char evf = 1; + +/* + * Exit handler for current process, established by popen(). + * Force the current process to wait for the completion of children + * which were started via popen(). + * Since + */ +static int +pwait (status) + int status; +{ + struct IOSB iosb; + struct PIPE *this; + int ret = 0; + + this = phead; + while (this) + { + if (this->self != this) + { + ret = -1; + continue; + } + if (!this->iosb.status) + { + fflush (this->file); + if (this->mode == O_WRONLY) + sys$qio (0, this->chan, IO$_WRITEOF, &iosb, + 0, 0, 0, 0, 0, 0, 0, 0); + fclose (this->file); + sys$synch (evf, &this->iosb); + } + else + fclose(this->file); + sys$dassgn (this->chan); + this = this->next; + } + return ret; +} + +/* + * Close a "pipe" created by popen() + * Return codes + * >0 VMS exit status of process + * 0 success, pipe was closed + * -1 stream not found in list of pipes + * -2 memory corruption detected + */ +int +pclose (stream) + FILE *stream; +{ + struct IOSB iosb; + struct PIPE *this = phead; + + while (this && this->self == this && this->file != stream) + this = this->next; + + /* Pipe not found or failed sanity check */ + if (!this) + return -1; + else if (this->self != this) + return -2; + + /* Flush the I/O buffer and wait for the close to complete */ + if (!this->iosb.status) + { + fflush (this->file); + if (this->mode == O_WRONLY) + sys$qio (0, this->chan, IO$_WRITEOF, &iosb, + 0, 0, 0, 0, 0, 0, 0, 0); + fclose (this->file); + sys$synch (evf, &this->iosb); + } + else + fclose (this->file); + sys$dassgn (this->chan); + + /* Remove `this' from the list of pipes and free its storage */ + if (this == ptail) + ptail = this->prev; + if (this == phead) + phead = this->next; + if (this->prev) + this->prev->next = this->next; + if (this->next) + this->next->prev = this->prev; + free (this); + + if (this->status & STS$M_SUCCESS != STS$M_SUCCESS) + return this->status; + else + return 0; +} + +/* + * Subprocess AST completion routine + * Indicate successful completion in the iosb and clear the pid. + * Note that the channel is *not* deassigned and the file is + * *not* closed. + */ +void +pdone (this) + struct PIPE *this; +{ + struct IOSB iosb; + + if (this->self != this) + return; + this->iosb.status = 1; + this->pid = 0; + if (this->has_jmpbuf) + { + this->has_jmpbuf = 0; + longjmp (this->jmpbuf, 1); + } +} + +int +pipe_set_fd_jmpbuf (fd, jmpbuf) + int fd; + jmp_buf jmpbuf; +{ + struct PIPE *this = phead; + + while (this) + if (fileno (this->file) == fd) + { + memcpy (this->jmpbuf, jmpbuf, sizeof (jmp_buf)); + this->has_jmpbuf = 1; + if (this->pid == 0) + { + this->has_jmpbuf = 0; + longjmp (this->jmpbuf, 1); + } + return 0; + } + else + this = this->next; + return 1; +} + +pipe_unset_fd_jmpbuf (fd) + int fd; +{ + struct PIPE *this = phead; + + while (this) + if (fileno (this->file) == fd) + { + this->has_jmpbuf = 0; + return 0; + } + else + this = this->next; + return 1; +} + +/* Exit handler control block for the current process. */ +static struct EXHCB pexhcb = { 0, pwait, 1, &pexhcb.exh$l_status, 0 }; + +struct Vstring +{ + short length; + char body[NAM$C_MAXRSS+1]; +}; + +/* + * Emulate a unix popen() call using lib$spawn + * + * if mode == "w", lib$spawn uses the mailbox for sys$input + * if mode == "r", lib$spawn uses the mailbox for sys$output + * + * Don't now how to handle both read and write + * + * Returns + * FILE * file pointer to the pipe + * NULL indicates an error ocurred, check errno value + */ +FILE * +popen (cmd, mode) + const char *cmd; + const char *mode; +{ + int i, status, flags, mbxsize; + struct IOSB iosb; + struct dsc$descriptor_s cmddsc, mbxdsc; + struct Vstring mbxname = { sizeof(mbxname.body) }; + struct itm$list3 mbxlist[2] = { + { sizeof(mbxname.body)-1, DVI$_DEVNAM, &mbxname.body, &mbxname.length }, + { 0, 0, 0, 0} }; + struct itm$list3 syilist[2] = { + { sizeof(mbxsize), SYI$_MAXBUF, &mbxsize, (void *) 0 }, + { 0, 0, 0, 0} }; + static int noExitHandler = 1; + struct PIPE *this; + + /* First allocate space for the new pipe */ + this = (struct PIPE *) calloc (1, sizeof(struct PIPE)); + if (!this) + { + errno = ENOMEM; + return NULL; + } + + /* Sanity check value */ + this->self = this; + + /* Use the smaller of SYI$_MAXBUF and 2048 for the mailbox size */ + status = sys$getsyiw(0, 0, 0, syilist, &iosb, 0, 0, 0); + if (status != SS$_NORMAL && !(iosb.status & STS$M_SUCCESS)) + { + vaxc$errno = iosb.status; + errno = EVMSERR; + free (this); + perror ("popen, $GETSYIW failure for SYI$_MAXBUF"); + return NULL; + } + + if (mbxsize > 2048) + mbxsize = 2048; + + status = sys$crembx (0, &this->chan, mbxsize, mbxsize, 0, 0, 0, 0); + if (status != SS$_NORMAL) + { + vaxc$errno = status; + errno = EVMSERR; + free (this); + perror ("popen, $CREMBX failure"); + return NULL; + } + + /* Retrieve mailbox name, use for fopen */ + status = sys$getdviw (0, this->chan, 0, &mbxlist, &iosb, 0, 0, 0); + if (status != SS$_NORMAL && !(iosb.status & STS$M_SUCCESS)) + { + vaxc$errno = iosb.status; + errno = EVMSERR; + sys$dassgn (this->chan); + free (this); + perror ("popen, $GETDVIW failure"); + return NULL; + } + + /* Spawn the command using the mailbox as the name for sys$input */ + mbxname.body[mbxname.length] = 0; + mbxdsc.dsc$w_length = mbxname.length; + mbxdsc.dsc$b_dtype = DSC$K_DTYPE_T; + mbxdsc.dsc$b_class = DSC$K_CLASS_S; + mbxdsc.dsc$a_pointer = mbxname.body; + + cmddsc.dsc$w_length = strlen(cmd); + cmddsc.dsc$b_dtype = DSC$K_DTYPE_T; + cmddsc.dsc$b_class = DSC$K_CLASS_S; + cmddsc.dsc$a_pointer = (char *)cmd; + flags = CLI$M_NOWAIT; + if (strcmp(mode,"w") == 0) + { + status = lib$spawn (&cmddsc, &mbxdsc, 0, &flags, 0, &this->pid, + &this->status, &evf, &pdone, this->self); + this->mode = O_WRONLY; + } + else + { + status = lib$spawn (&cmddsc, 0, &mbxdsc, &flags, 0, &this->pid, + &this->status, &evf, &pdone, this->self); + this->mode = O_RDONLY; + } + if (status != SS$_NORMAL) + { + vaxc$errno = status; + errno = EVMSERR; + sys$dassgn (this->chan); + free (this); + perror("popen, LIB$SPAWN failure"); + return NULL; + } + + /* Set up an exit handler so the subprocess isn't prematurely killed */ + if (noExitHandler) + { + status = sys$dclexh (&pexhcb); + if (status != SS$_NORMAL) + { + vaxc$errno = status; + errno = EVMSERR; + sys$dassgn (this->chan); + sys$delprc (&this->pid, 0); + free (this); + perror("popen, $DCLEXH failure"); + return NULL; + } + noExitHandler = 0; + } + + /* Pipes are always binary mode devices */ + if (this->mode == O_WRONLY) + this->file = fopen (mbxname.body, "wb"); + else + this->file = fopen (mbxname.body, "rb"); + + /* Paranoia, check for failure again */ + if (!this->file) + { + sys$dassgn (this->chan); + sys$delprc (this->pid); + free (this); + perror ("popen, fopen failure"); + return NULL; + } + + this->has_jmpbuf = 0; + + /* Insert the new pipe into the list of open pipes */ + if (phead) + { + ptail->next = this; + this->prev = ptail; + ptail = this; + } + else + phead = ptail = this; + + return (this->file); +} + + +#ifdef TEST_PIPE +int +main (argc, argv) + int argc; + char **argv; +{ + FILE *stdpipe; + char line[512]; + + while (1) + { + printf ("\nEnter a command to run >> "); + fgets (line, 511, stdin); + if (!strlen(line)) + exit (1); + line[strlen(line)-1] = 0; + stdpipe = popen (line, "r"); + if (!stdpipe) + { + fprintf (stderr, "popen failed.\n"); + exit(44); + } + do { + fgets (line, 511, stdpipe); + fputs (line, stdout); + } while (!feof(stdpipe)); + pclose (stdpipe); + } +} +#endif diff --git a/gnu/usr.bin/cvs/vms/pipe.h b/gnu/usr.bin/cvs/vms/pipe.h new file mode 100644 index 00000000000..6a88c1d716d --- /dev/null +++ b/gnu/usr.bin/cvs/vms/pipe.h @@ -0,0 +1,27 @@ +/* + * Copyright © 1994 the Free Software Foundation, Inc. + * + * Author: Richard Levitte (levitte@e.kth.se) + * + * This file is a part of GNU VMSLIB, the GNU library for porting GNU + * software to VMS. + * + * GNU VMSLIB 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 of the License, or + * (at your option) any later version. + * + * GNU VMSLIB 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. + * + * You should have received a copy of the GNU General Public License + * along with GNU VMSLIB; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdio.h> + +int pclose (FILE *); +FILE *popen (const char *, const char *); diff --git a/gnu/usr.bin/cvs/vms/piped_child.c b/gnu/usr.bin/cvs/vms/piped_child.c new file mode 100644 index 00000000000..af0266a5e0e --- /dev/null +++ b/gnu/usr.bin/cvs/vms/piped_child.c @@ -0,0 +1,382 @@ +/* + * piped_child.c + * + * An experimental VMS implementation of the same routine in [-.src]run.c + * <benjamin@cyclic.com> + * + * Derived in part from pipe.c, in this directory. + */ + +#include "vms.h" +#include "vms-types.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <iodef.h> +#include <ssdef.h> +#include <syidef.h> +#include <clidef.h> +#include <stsdef.h> +#include <dvidef.h> +#include <nam.h> +#include <descrip.h> +#include <errno.h> +#include <file.h> +#include <lib$routines.h> +#include <starlet.h> + +extern int trace; + +/* Subprocess IO structure */ +typedef struct _SUBIO { + struct _SUBIO *self; + struct _SUBIO *prev; + struct _SUBIO *next; + short read_chan; + short write_chan; + FILE *read_fp; + FILE *write_fp; + struct IOSB read_iosb; + struct IOSB write_iosb; + int pid; + int return_status; + unsigned long event_flag; + unsigned char event_flag_byte; +} SUBIO; + +static SUBIO *siop_head = NULL, *siop_tail = NULL; + +static int piped_child_exith(int); + +static struct EXHCB piped_child_exit_handler_block = + {0, piped_child_exith, 1, &piped_child_exit_handler_block.exh$l_status, 0}; + +typedef struct +{ + short length; + char body[NAM$C_MAXRSS+1]; +} Vstring; + +/* Subprocess Completion AST */ +void piped_child_done(siop) + SUBIO *siop; +{ + struct IOSB iosb; + int status; + + if (siop->self != siop) + return; + siop->read_iosb.status = SS$_NORMAL; + siop->write_iosb.status = SS$_NORMAL; + +} + +/* Exit handler, established by piped_child() */ +static int +piped_child_exith(status) + int status; +{ + struct IOSB iosb; + SUBIO *siop; + int return_value = 0; + + siop = siop_head; + while (siop) + { + if (siop->self != siop) + { + return_value = -1; + continue; + } + + /* Finish pending reads and shutdown */ + if(!siop->read_iosb.status) + { + fflush (siop->read_fp); + fclose (siop->read_fp); + } + else + fclose (siop->read_fp); + sys$dassgn (siop->read_chan); + + /* Finish pending writes and shutdown */ + if(!siop->write_iosb.status) + { + fflush (siop->write_fp); + sys$qio (0, siop->write_chan, IO$_WRITEOF, &iosb, + 0, 0, 0, 0, 0, 0, 0, 0); + fclose (siop->write_fp); + } + else + fclose (siop->write_fp); + sys$dassgn (siop->write_chan); + + sys$synch (siop->event_flag, &siop->write_iosb); + + siop = siop->next; + } + return return_value; +} + +int piped_child(command, tofdp, fromfdp) +char **command; +int *tofdp, *fromfdp; +{ + static int exit_handler = 0; + struct IOSB iosb1, iosb2; + int rs1, rs2, i; + unsigned long flags, vmspid, return_status; + char cmd[1024]; + struct dsc$descriptor_s cmddsc; + struct dsc$descriptor_s read_mbxdsc, write_mbxdsc; + SUBIO *siop; + static Vstring read_mbxname, write_mbxname; + static struct itm$list3 write_mbxlist[2] = { + {sizeof(write_mbxname.body)-1, DVI$_DEVNAM, + &write_mbxname.body, (size_t *) &write_mbxname.length}, + {0, 0, 0, 0} }; + static struct itm$list3 read_mbxlist[2] = { + {sizeof(read_mbxname.body)-1, DVI$_DEVNAM, + &read_mbxname.body, (size_t *) &read_mbxname.length}, + {0, 0, 0, 0} }; + + read_mbxname.length = sizeof(read_mbxname.body); + write_mbxname.length = sizeof(write_mbxname.body); + + siop = (SUBIO *) calloc(1, sizeof(SUBIO)); + if (!siop) + { + perror("piped_child: malloc failed\n"); + return -1; + } + + siop->self = siop; + + /* Construct command line by concatenating argument list */ + strcpy(cmd, command[0]); + for(i=1; command[i] != NULL; i++) + { + strcat(cmd, " "); + strcat(cmd, command[i]); + } + + if(trace) + fprintf(stderr, "piped_child: running '%s'\n", cmd); + + /* Allocate a pair of temporary mailboxes (2kB each) */ + rs1 = sys$crembx (0, &siop->read_chan, 2048, 2048, 0, 0, 0, 0); + rs2 = sys$crembx (0, &siop->write_chan, 2048, 2048, 0, 0, 0, 0); + + if (rs1 != SS$_NORMAL || rs2 != SS$_NORMAL) + { + vaxc$errno = rs1 | rs2; + errno = EVMSERR; + free (siop); + perror ("piped_child: $CREMBX failure"); + return -1; + } + + /* Get mailbox names, so we can fopen() them */ + rs1 = sys$getdviw (0, siop->read_chan, 0, &read_mbxlist, + &iosb1, 0, 0, 0); + + rs2 = sys$getdviw (0, siop->write_chan, 0, &write_mbxlist, + &iosb2, 0, 0, 0); + + if ((rs1 != SS$_NORMAL && !(iosb1.status & STS$M_SUCCESS)) || + (rs2 != SS$_NORMAL && !(iosb2.status & STS$M_SUCCESS))) + { + vaxc$errno = iosb1.status | iosb2.status; + errno = EVMSERR; + sys$dassgn (siop->read_chan); + sys$dassgn (siop->write_chan); + free (siop); + perror ("piped_child: $GETDVIW failure, could not get mailbox names"); + return -1; + } + + if (trace) + { + fprintf(stderr, "piped_child: $GETDVIW succeeded, got mailbox names\n"); + fprintf(stderr, "piped_child: ReadMBX: %s, WriteMBX: %s\n", + read_mbxname.body, write_mbxname.body); + } + + /* Make C happy */ + write_mbxname.body[write_mbxname.length] = '\0'; + read_mbxname.body[read_mbxname.length] = '\0'; + + /* Make VMS happy */ + write_mbxdsc.dsc$w_length = write_mbxname.length; + write_mbxdsc.dsc$b_dtype = DSC$K_DTYPE_T; + write_mbxdsc.dsc$b_class = DSC$K_CLASS_S; + write_mbxdsc.dsc$a_pointer = write_mbxname.body; + + read_mbxdsc.dsc$w_length = read_mbxname.length; + read_mbxdsc.dsc$b_dtype = DSC$K_DTYPE_T; + read_mbxdsc.dsc$b_class = DSC$K_CLASS_S; + read_mbxdsc.dsc$a_pointer = read_mbxname.body; + + /* Build descriptor for command line */ + cmddsc.dsc$w_length = strlen(cmd); + cmddsc.dsc$b_dtype = DSC$K_DTYPE_T; + cmddsc.dsc$b_class = DSC$K_CLASS_S; + cmddsc.dsc$a_pointer = (char *) cmd; + + flags = CLI$M_NOWAIT; + + /* Allocate an event flag to signal process termination */ + rs1 = lib$get_ef(&siop->event_flag); + if (rs1 != SS$_NORMAL) + { + vaxc$errno = rs1; + errno = EVMSERR; + sys$dassgn(siop->read_chan); + sys$dassgn(siop->write_chan); + perror("piped_child: LIB$GET_EF failed"); + return -1; + } + + /* Save the EFN as a byte for later calls to other routines */ + siop->event_flag_byte = 0xff & siop->event_flag; + + if (trace) + fprintf(stderr, "piped_child: Got an EFN: %d\n", siop->event_flag_byte); + + rs1 = lib$spawn(&cmddsc, &write_mbxdsc, &read_mbxdsc, &flags, 0, + &siop->pid, &siop->return_status, &siop->event_flag_byte, + &piped_child_done, siop->self); + + if (rs1 != SS$_NORMAL) + { + vaxc$errno = rs1; + errno = EVMSERR; + sys$dassgn(siop->read_chan); + sys$dassgn(siop->write_chan); + perror("piped_child: LIB$SPAWN failure"); + return -1; + } + + if (trace) + fprintf(stderr, "piped_child: LIB$SPAWN succeeded, pid is %08x.\n", + siop->pid); + + /* Establish an exit handler so the process isn't prematurely terminated */ + if (!exit_handler) + { + rs1 = sys$dclexh (&piped_child_exit_handler_block); + if (rs1 != SS$_NORMAL) + { + vaxc$errno = rs1; + errno = EVMSERR; + sys$dassgn (siop->read_chan); + sys$dassgn (siop->write_chan); + sys$delprc (siop->pid, 0); + free (siop); + perror("piped_child: $DCLEXH failure"); + return -1; + } + exit_handler = 1; + } + + /* Let's open some files */ + siop->read_fp = fopen (read_mbxname.body, "r"); + siop->write_fp = fopen (write_mbxname.body, "w"); + + if (!siop->read_fp || !siop->write_fp) + { + sys$dassgn (siop->read_chan); + sys$dassgn (siop->write_chan); + sys$delprc (siop->pid); + free (siop); + perror("piped_child: fopen() failed"); + return -1; + } + + *fromfdp = fileno(siop->read_fp); + *tofdp = fileno(siop->write_fp); + + if (trace) + fprintf(stderr, "piped_child: file open successful: tofd=%d fromfd=%d\n", + *tofdp, *fromfdp); + + /* Keep track of active subprocess I/O (SUBIO) structures */ + if (siop_head) + { + siop_tail->next = siop; + siop->prev = siop_tail; + siop_tail = siop; + } + else + siop_head = siop_tail = siop; + + return siop->pid; +} + +/* + * Return codes + * >0 VMS exit status of subprocess + * 0 success, subprocess was shutdown + * -1 pid not found in list of subprocesses + * -2 memory corruption detected + */ +int +piped_child_shutdown(pid) + pid_t pid; +{ + int return_status; + struct IOSB iosb; + SUBIO *siop = siop_head; + + while (siop && siop->self == siop && siop->pid != pid) + siop = siop->next; + + if (!siop) + return -1; + else if (siop->self != siop) + return -2; + + /* Finish reading and writing and shutdown */ + if (siop->read_iosb.status) + { + fflush (siop->read_fp); + fclose (siop->read_fp); + } + else + fclose(siop->read_fp); + sys$dassgn (siop->read_chan); + + if (siop->write_iosb.status) + { + fflush (siop->write_fp); + sys$qio (0, siop->write_chan, IO$_WRITEOF, &iosb, + 0, 0, 0, 0, 0, 0, 0, 0); + fclose (siop->write_fp); + } + else + fclose(siop->write_fp); + sys$dassgn (siop->write_chan); + + sys$synch (siop->event_flag, &siop->write_iosb); + lib$free_ef(&siop->event_flag); + + /* Ditch SUBIO structure */ + if (siop == siop_tail) + siop_tail = siop->prev; + if (siop == siop_head) + siop_head = siop->next; + if (siop->prev) + siop->prev->next = siop->next; + if (siop->next) + siop->next->prev = siop->prev; + + if (siop->return_status) + return_status = siop->return_status; + else + return_status = 0; + + free (siop); + + return return_status; +} diff --git a/gnu/usr.bin/cvs/vms/pwd.c b/gnu/usr.bin/cvs/vms/pwd.c new file mode 100644 index 00000000000..97b5c5ca1b1 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/pwd.c @@ -0,0 +1,29 @@ +#include "pwd.h" +#include <stdio.h> +#include <unixlib.h> + +static struct passwd pw; + +struct passwd *getpwuid(uid_t uid) +{ + pw.pw_name = getlogin(); + pw.pw_uid = getuid(); + pw.pw_gid = getgid(); + + return &pw; +} + +struct passwd *getpwnam(char *name) +{ + pw.pw_name = getlogin(); + pw.pw_uid = getuid(); + pw.pw_gid = getgid(); + + return &pw; +} + +char *getlogin() +{ + static char login[256]; + return cuserid(login); +} diff --git a/gnu/usr.bin/cvs/vms/pwd.h b/gnu/usr.bin/cvs/vms/pwd.h new file mode 100644 index 00000000000..da0ed334a4c --- /dev/null +++ b/gnu/usr.bin/cvs/vms/pwd.h @@ -0,0 +1,20 @@ +#ifndef _PWD_H +#define _PWD_H + +#define uid_t unsigned int +#define gid_t unsigned int +#define pid_t int + +struct passwd { + char *pw_name; + uid_t pw_uid; + gid_t pw_gid; + char *pw_dir; + }; + +struct passwd *getpwuid(uid_t); +struct passwd *getpwnam(char *); +char *getlogin(void); + +#else +#endif /* _PWD_H */ diff --git a/gnu/usr.bin/cvs/vms/rcmd.c b/gnu/usr.bin/cvs/vms/rcmd.c new file mode 100644 index 00000000000..e403021a30e --- /dev/null +++ b/gnu/usr.bin/cvs/vms/rcmd.c @@ -0,0 +1,115 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unixio.h> + +#include <errno.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> + +int rcmd(char **remote_hostname, int remote_port, + char *local_user, char *remote_user, + char *command, int zero) +{ + struct hostent *remote_hp; + struct hostent *local_hp; + struct sockaddr_in remote_isa; + struct sockaddr_in local_isa; + char local_hostname[80]; + char ch; + int s; + int local_port; + int rs; + + remote_hp = gethostbyname(*remote_hostname); + if(!remote_hp) + { + perror("couldn't get remote host address"); + exit(-1); + } + + /* Copy remote IP address into socket address structure */ + remote_isa.sin_family = AF_INET; + remote_isa.sin_port = htons(remote_port); + memcpy(&remote_isa.sin_addr, remote_hp->h_addr, sizeof(remote_isa.sin_addr)); + + gethostname(local_hostname, 80); + local_hp = gethostbyname(local_hostname); + if(!local_hp) + { + perror("couldn't get local host address"); + exit(-1); + } + + /* Copy local IP address into socket address structure */ + local_isa.sin_family = AF_INET; + memcpy(&local_isa.sin_addr, local_hp->h_addr, sizeof(local_isa.sin_addr)); + + /* Create the local socket */ + s = socket(AF_INET, SOCK_STREAM, 0); + if(s < 0) + { + perror("socket failed\n"); + exit(-1); + } + + /* Bind local socket with a port from IPPORT_RESERVED/2 to IPPORT_RESERVED - 1 + this requires the OPER privilege under VMS -- to allow communication with + a stock rshd under UNIX */ + + for(local_port = IPPORT_RESERVED - 1; local_port >= IPPORT_RESERVED/2; local_port--) + { + local_isa.sin_port = htons(local_port); + rs = bind(s, (struct sockaddr *)&local_isa, sizeof(local_isa)); + if(rs == 0) + break; + } + + /* Bind local socket to an unprivileged port. A normal rshd will drop the + connection; you must be running a patched rshd invoked through inetd for + this connection method to work */ + + if (rs != 0) + for(local_port = IPPORT_USERRESERVED - 1; + local_port > IPPORT_RESERVED; + local_port--) + { + local_isa.sin_port = htons(local_port); + rs = bind(s, (struct sockaddr *)&local_isa, sizeof(local_isa)); + if(rs == 0) + break; + } + + rs = connect(s, (struct sockaddr *) &remote_isa, sizeof(remote_isa)); + if(rs == -1) + { + fprintf(stderr, "connect: errno = %d\n", errno); + close(s); + exit(-2); + } + + /* Now supply authentication information */ + + /* Auxiliary port number for error messages, we don't use it */ + write(s, "0\0", 2); + + /* Who are we */ + write(s, local_user, strlen(local_user) + 1); + + /* Who do we want to be */ + write(s, remote_user, strlen(remote_user) + 1); + + /* What do we want to run */ + write(s, command, strlen(command) + 1); + + /* NUL is sent back to us if information is acceptable */ + read(s, &ch, 1); + if(ch != '\0') + { + errno = EPERM; + return -1; + } + + return s; +} diff --git a/gnu/usr.bin/cvs/vms/readlink.c b/gnu/usr.bin/cvs/vms/readlink.c new file mode 100644 index 00000000000..1d844d738c6 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/readlink.c @@ -0,0 +1,5 @@ +int readlink(char *path, char *buf, int bufsiz) +{ + /* OpenVMS dosen't have symbolic links in the UNIX sense */ + return -1; +} diff --git a/gnu/usr.bin/cvs/vms/rmdir.c b/gnu/usr.bin/cvs/vms/rmdir.c new file mode 100644 index 00000000000..050580e0878 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/rmdir.c @@ -0,0 +1,10 @@ +#include <stdio.h> +#include <unixio.h> + +int rmdir(path) +char *path; +{ + chmod(path, 0777); + return remove(path); +} + diff --git a/gnu/usr.bin/cvs/vms/startserver.c b/gnu/usr.bin/cvs/vms/startserver.c new file mode 100644 index 00000000000..c213aab4d28 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/startserver.c @@ -0,0 +1,56 @@ +#include <socket.h> +#include <netdb.h> +#include <errno.h> + +#include "options.h" + +static char *cvs_server; +static char *command; + +extern int trace; + +void +vms_start_server (int *tofd, int *fromfd, + char *client_user, char *server_user, + char *server_host, char *server_cvsroot) +{ + int fd, port; + char *portenv; + struct servent *sptr; + + if (! (cvs_server = getenv ("CVS_SERVER"))) + cvs_server = "cvs"; + command = xmalloc (strlen (cvs_server) + + strlen (server_cvsroot) + + 50); + sprintf(command, "%s server", cvs_server); + + portenv = getenv("CVS_RCMD_PORT"); + if (portenv) + port = atoi(portenv); + else if ((sptr = getservbyname("shell", "tcp")) != NULL) + port = sptr->s_port; + else + port = 514; /* shell/tcp */ + + if(trace) + { + fprintf(stderr, "vms_start_server(): connecting to %s:%d\n", + server_host, port); + fprintf(stderr, "local_user = %s, remote_user = %s, CVSROOT = %s\n", + client_user, (server_user ? server_user : client_user), + server_cvsroot); + } + + fd = rcmd(&server_host, port, + client_user, + (server_user ? server_user : client_user), + command, 0); + + if (fd < 0) + error (1, errno, "cannot start server via rcmd()"); + + *tofd = fd; + *fromfd = fd; + free (command); +} diff --git a/gnu/usr.bin/cvs/vms/stat.c b/gnu/usr.bin/cvs/vms/stat.c new file mode 100644 index 00000000000..336247fb73f --- /dev/null +++ b/gnu/usr.bin/cvs/vms/stat.c @@ -0,0 +1,26 @@ +#include <string.h> +#include <stat.h> +#include <unixlib.h> + +int wrapped_stat (path, buffer) +const char *path; +struct stat *buffer; +{ + char statpath[1024]; + int rs; + + strcpy(statpath, path); + strip_path(statpath); + if(strcmp(statpath, ".") == 0) + getwd(statpath); + + if ((rs = stat (statpath, buffer)) < 0) + { + /* If stat() fails try again after appending ".dir" to the filename + this allows you to stat things like "bloogle/CVS" from VMS 6.1 */ + strcat(statpath, ".dir"); + rs = stat (statpath, buffer); + } + + return rs; +} diff --git a/gnu/usr.bin/cvs/vms/unlink.c b/gnu/usr.bin/cvs/vms/unlink.c new file mode 100644 index 00000000000..8bda6554863 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/unlink.c @@ -0,0 +1,22 @@ +#include <unixio.h> + +/* UNIX-like file deletion, deletes previous VMS file versions so UNIX + style locking through files dosen't lose. */ +int unlink(char *path) +{ + int rs, junk_rs; + + rs = remove(path); + while(remove(path) >= 0); + + return rs; +} + +int link(char *from, char *to) +{ + int rs = -1; + + /* Link always fails */ + + return rs; +} diff --git a/gnu/usr.bin/cvs/vms/utime.c b/gnu/usr.bin/cvs/vms/utime.c new file mode 100644 index 00000000000..999aecb748a --- /dev/null +++ b/gnu/usr.bin/cvs/vms/utime.c @@ -0,0 +1,42 @@ +/* This is REALLY gross, but at least it is a full implementation */ + +#include <ctype.h> +#include <time.h> +#include "vmsmunch.h" + +#define ASCTIMEMAX 23 + +struct utimbuf { + long actime; + long modtime; + }; + +utime(file, buf) +char *file; +struct utimbuf *buf; +{ + static struct VMStimbuf vtb; + static char conversion_buf[80]; + static char vms_actime[80]; + static char vms_modtime[80]; + + strcpy(conversion_buf, ctime(&buf->actime)); + conversion_buf[ASCTIMEMAX + 1] = '\0'; + sprintf(vms_actime, "%2.2s-%3.3s-%4.4s %8.5s.00", + &(conversion_buf[8]), &(conversion_buf[4]), + &(conversion_buf[20]), &(conversion_buf[11])); + vms_actime[4] = _toupper(vms_actime[4]); + vms_actime[5] = _toupper(vms_actime[5]); + + strcpy(conversion_buf, ctime(&buf->modtime)); + conversion_buf[ASCTIMEMAX + 1] = '\0'; + sprintf(vms_modtime, "%2.2s-%3.3s-%4.4s %8.5s.00", + &(conversion_buf[8]), &(conversion_buf[4]), + &(conversion_buf[20]), &(conversion_buf[11])); + vms_modtime[4] = _toupper(vms_modtime[4]); + vms_modtime[4] = _toupper(vms_modtime[5]); + + vtb.actime = vms_actime; + vtb.modtime = vms_modtime; + VMSmunch(file, SET_TIMES, &vtb); +} diff --git a/gnu/usr.bin/cvs/vms/vms-types.h b/gnu/usr.bin/cvs/vms/vms-types.h new file mode 100644 index 00000000000..658b1e2801c --- /dev/null +++ b/gnu/usr.bin/cvs/vms/vms-types.h @@ -0,0 +1,45 @@ +#ifndef __types_loaded__ +#define __types_loaded__ 1 + +#include <stddef.h> + +/* + * Miscellaneous VMS types that are not normally defined + * in any consistent fashion. + */ + +/* VMS I/O status block */ +struct IOSB +{ + short status, count; + long devinfo; +}; + +/* VMS Item List 3 structure */ +struct itm$list3 +{ + short buflen; + short itemcode; + void *buffer; + size_t *retlen; +}; + +/* VMS Lock status block with value block */ +struct LOCK +{ + short status, reserved; + long lockid; + long value[4]; +}; + +/* VMS Exit Handler Control block */ +struct EXHCB +{ + struct exhcb *exh$a_link; + int (*exh$a_routine)(); + long exh$l_argcount; + long *exh$a_status; + long exh$l_status; +}; + +#endif /* __types_loaded__ 1 */ diff --git a/gnu/usr.bin/cvs/vms/vms.h b/gnu/usr.bin/cvs/vms/vms.h new file mode 100644 index 00000000000..7483c4748a6 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/vms.h @@ -0,0 +1,31 @@ +/* Determined from CC RTL function prototypes in online documentation */ + +#define mode_t unsigned int + +#define fork(x) vfork(x) + +#include <sys/types.h> +#include <unixio.h> +#include <unixlib.h> +#include <stdlib.h> +#include <processes.h> +#include <socket.h> + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +extern int fnmatch(char *pattern, char *string, int options); + +#include "ndir.h" +#include "pwd.h" +#include "pipe.h" + +int unlink(char *path); +int link(char *from, char *to); + +int rmdir(char *path); + +#define stat(a, b) wrapped_stat(a, b) + +#undef POSIX diff --git a/gnu/usr.bin/cvs/vms/vmsmunch.c b/gnu/usr.bin/cvs/vms/vmsmunch.c new file mode 100644 index 00000000000..198d45e9593 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/vmsmunch.c @@ -0,0 +1,370 @@ +/*--------------------------------------------------------------------------- + + VMSmunch.c version 1.3 28 Apr 1992 + + This routine is a blatant and unrepentent appropriation of all the nasty + and difficult-to-do and complicated VMS shenanigans which Joe Meadows has + so magnificently captured in his FILE utility. Not only that, it's even + allowed! (see below). But let it be clear at the outset that Joe did all + the work; yea, verily, he is truly a godlike unit. + + The appropriations and modifications herein were performed primarily by + him known as "Cave Newt," although the Info-ZIP working group probably had + their fingers in it somewhere along the line. The idea is to put the raw + power of Joe's original routine at the disposal of various routines used + by UnZip (and Zip, possibly), not least among them the utime() function. + Read on for details... + + 18-JUL-1994 Hunter Goatley <goathunter@WKU.EDU> + Fixed IO$_ACCESS call. + + 18-Jul-1994 Richard Levitte levitte@e.kth.se + Changed VMSmunch() to deassign the channel before + returning when an error has occured. + + 02-Apr-1994 Jamie Hanrahan jeh@cmkrnl.com + Moved definition of VMStimbuf struct from here + to vmsmunch.h + --------------------------------------------------------------------------- + + Usage (i.e., "interface," in geek-speak): + + int VMSmunch( char *filename, int action, char *ptr ); + + filename the name of the file on which to be operated, obviously + action an integer which specifies what action to take + ptr pointer to any extra item which may be needed (else NULL) + + The possible values for the action argument are as follows: + + GET_TIMES get the creation and revision dates of filename; ptr + must point to an empty VMStimbuf struct, as defined + in vmsmunch.h + (with room for at least 24 characters, including term.) + SET_TIMES set the creation and revision dates of filename (utime + option); ptr must point to a valid VMStimbuf struct, + as defined in vmsmunch.h + GET_RTYPE get the record type of filename; ptr must point to an + integer which, on return, is set to the type (as defined + in VMSmunch.h: FAT$C_* defines) + CHANGE_RTYPE change the record type to that specified by the integer + to which ptr points; save the old record type (later + saves overwrite earlier ones) + RESTORE_RTYPE restore the record type to the previously saved value; + or, if none, set it to "fixed-length, 512-byte" record + format (ptr not used) + + --------------------------------------------------------------------------- + + Comments from FILE.C, a utility to modify file characteristics: + + Written by Joe Meadows Jr, at the Fred Hutchinson Cancer Research Center + BITNET: JOE@FHCRCVAX + PHONE: (206) 467-4970 + + There are no restrictions on this code, you may sell it, include it + with any commercial package, or feed it to a whale.. However, I would + appreciate it if you kept this comment in the source code so that anyone + receiving this code knows who to contact in case of problems. Note that + I do not demand this condition.. + + ---------------------------------------------------------------------------*/ + + + + +/*****************************/ +/* Includes, Defines, etc. */ +/*****************************/ + +#include <descrip.h> +#include <rms.h> +#include <stdio.h> +#include <iodef.h> +#include <string.h> +#include <starlet.h> +#include <atrdef.h> /* this gets created with the c3.0 compiler */ +#include <fibdef.h> /* this gets created with the c3.0 compiler */ + +#include "VMSmunch.h" /* GET/SET_TIMES, RTYPE, etc. */ +#include "VMSmunch_private.h" /* fatdef.h, etc. */ + +#define RTYPE fat$r_rtype_overlay.fat$r_rtype_bits +#define RATTRIB fat$r_rattrib_overlay.fat$r_rattrib_bits + +static void asctim(); +static void bintim(); + +/* from <ssdef.h> */ +#ifndef SS$_NORMAL +# define SS$_NORMAL 1 +# define SS$_BADPARAM 20 +#endif + + + + + +/*************************/ +/* Function VMSmunch() */ +/*************************/ + +int VMSmunch( filename, action, ptr ) + char *filename, *ptr; + int action; +{ + + /* original file.c variables */ + + static struct FAB Fab; + static struct NAM Nam; + static struct fibdef Fib; /* short fib */ + + static struct dsc$descriptor FibDesc = + {sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,(char *)&Fib}; + static struct dsc$descriptor_s DevDesc = + {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]}; + static struct fatdef Fat; + static union { + struct fchdef fch; + long int dummy; + } uchar; + static struct fjndef jnl; + static long int Cdate[2],Rdate[2],Edate[2],Bdate[2]; + static short int revisions; + static unsigned long uic; + static union { + unsigned short int value; + struct { + unsigned system : 4; + unsigned owner : 4; + unsigned group : 4; + unsigned world : 4; + } bits; + } prot; + + static struct atrdef Atr[] = { + {ATR$S_RECATTR,ATR$C_RECATTR,&Fat}, /* record attributes */ + {ATR$S_UCHAR,ATR$C_UCHAR,&uchar}, /* File characteristics */ + {ATR$S_CREDATE,ATR$C_CREDATE,&Cdate[0]}, /* Creation date */ + {ATR$S_REVDATE,ATR$C_REVDATE,&Rdate[0]}, /* Revision date */ + {ATR$S_EXPDATE,ATR$C_EXPDATE,&Edate[0]}, /* Expiration date */ + {ATR$S_BAKDATE,ATR$C_BAKDATE,&Bdate[0]}, /* Backup date */ + {ATR$S_ASCDATES,ATR$C_ASCDATES,&revisions}, /* number of revisions */ + {ATR$S_FPRO,ATR$C_FPRO,&prot}, /* file protection */ + {ATR$S_UIC,ATR$C_UIC,&uic}, /* file owner */ + {ATR$S_JOURNAL,ATR$C_JOURNAL,&jnl}, /* journal flags */ + {0,0,0} + } ; + + static char EName[NAM$C_MAXRSS]; + static char RName[NAM$C_MAXRSS]; + static struct dsc$descriptor_s FileName = + {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; + static struct dsc$descriptor_s string = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; + static short int DevChan; + static short int iosb[4]; + + static long int i,status; +/* static char *retval; */ + + + /* new VMSmunch variables */ + + static int old_rtype=FAT$C_FIXED; /* storage for record type */ + + + +/*--------------------------------------------------------------------------- + Initialize attribute blocks, parse filename, resolve any wildcards, and + get the file info. + ---------------------------------------------------------------------------*/ + + /* initialize RMS structures, we need a NAM to retrieve the FID */ + Fab = cc$rms_fab; + Fab.fab$l_fna = filename; + Fab.fab$b_fns = strlen(filename); + Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */ + Nam = cc$rms_nam; + Nam.nam$l_esa = EName; /* expanded filename */ + Nam.nam$b_ess = sizeof(EName); + Nam.nam$l_rsa = RName; /* resultant filename */ + Nam.nam$b_rss = sizeof(RName); + + /* do $PARSE and $SEARCH here */ + status = sys$parse(&Fab); + if (!(status & 1)) return(status); + + /* search for the first file.. If none signal error */ + status = sys$search(&Fab); + if (!(status & 1)) return(status); + + while (status & 1) { + /* initialize Device name length, note that this points into the NAM + to get the device name filled in by the $PARSE, $SEARCH services */ + DevDesc.dsc$w_length = Nam.nam$t_dvi[0]; + + status = sys$assign(&DevDesc,&DevChan,0,0); + if (!(status & 1)) return(status); + + FileName.dsc$a_pointer = Nam.nam$l_name; + FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver; + + /* Initialize the FIB */ + for (i=0;i<3;i++) +#ifdef VAXC + Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i]; +#else + Fib.fib$w_fid[i]=Nam.nam$w_fid[i]; +#endif + for (i=0;i<3;i++) +#ifdef VAXC + Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i]; +#else + Fib.fib$w_did[i]=Nam.nam$w_did[i]; +#endif + + /* Use the IO$_ACCESS function to return info about the file */ + /* Note, used this way, the file is not opened, and the expiration */ + /* and revision dates are not modified */ + status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0, + &FibDesc,&FileName,0,0,&Atr,0); + if (!(status & 1)) + { + sys$dassgn(DevChan); + return(status); + } + status = iosb[0]; + if (!(status & 1)) + { + sys$dassgn(DevChan); + return(status); + } + + /*----------------------------------------------------------------------- + We have the current information from the file: now see what user + wants done with it. + -----------------------------------------------------------------------*/ + + switch (action) { + + case GET_TIMES: + asctim(((struct VMStimbuf *)ptr)->modtime, Cdate); + asctim(((struct VMStimbuf *)ptr)->actime, Rdate); + break; + + case SET_TIMES: + bintim(((struct VMStimbuf *)ptr)->modtime, Cdate); + bintim(((struct VMStimbuf *)ptr)->actime, Rdate); + break; + + case GET_RTYPE: /* non-modifying */ + *(int *)ptr = Fat.RTYPE.fat$v_rtype; + return RMS$_NORMAL; /* return to user */ + break; + + case CHANGE_RTYPE: + old_rtype = Fat.RTYPE.fat$v_rtype; /* save current one */ + if ((*(int *)ptr < FAT$C_UNDEFINED) || + (*(int *)ptr > FAT$C_STREAMCR)) + Fat.RTYPE.fat$v_rtype = FAT$C_STREAMLF; /* Unix I/O happy */ + else + Fat.RTYPE.fat$v_rtype = *(int *)ptr; + break; + + case RESTORE_RTYPE: + Fat.RTYPE.fat$v_rtype = old_rtype; + break; + + default: + return SS$_BADPARAM; /* anything better? */ + } + + /*----------------------------------------------------------------------- + Go back and write modified data to the file header. + -----------------------------------------------------------------------*/ + + /* note, part of the FIB was cleared by earlier QIOW, so reset it */ +#ifdef VAXC + Fib.fib$r_acctl_overlay.fib$l_acctl = FIB$M_NORECORD; +#else + Fib.fib$l_acctl = FIB$M_NORECORD; +#endif + for (i=0;i<3;i++) +#ifdef VAXC + Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i]; +#else + Fib.fib$w_fid[i]=Nam.nam$w_fid[i]; +#endif + for (i=0;i<3;i++) +#ifdef VAXC + Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i]; +#else + Fib.fib$w_did[i]=Nam.nam$w_did[i]; +#endif + + /* Use the IO$_MODIFY function to change info about the file */ + /* Note, used this way, the file is not opened, however this would */ + /* normally cause the expiration and revision dates to be modified. */ + /* Using FIB$M_NORECORD prohibits this from happening. */ + status = sys$qiow(0,DevChan,IO$_MODIFY,&iosb,0,0, + &FibDesc,&FileName,0,0,&Atr,0); + if (!(status & 1)) + { + sys$dassgn(DevChan); + return(status); + } + + status = iosb[0]; + if (!(status & 1)) + { + sys$dassgn(DevChan); + return(status); + } + + status = sys$dassgn(DevChan); + if (!(status & 1)) return(status); + + /* look for next file, if none, no big deal.. */ + status = sys$search(&Fab); + } +} /* end function VMSmunch() */ + + + + + +/***********************/ +/* Function bintim() */ +/***********************/ + +void asctim(time,binval) /* convert 64-bit binval to string, put in time */ + char *time; + long int binval[2]; +{ + static struct dsc$descriptor date_str={23,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; + /* dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer */ + + date_str.dsc$a_pointer = time; + sys$asctim(0, &date_str, binval, 0); + time[23] = '\0'; +} + + + + + +/***********************/ +/* Function bintim() */ +/***********************/ + +void bintim(time,binval) /* convert time string to 64 bits, put in binval */ + char *time; + long int binval[2]; +{ + static struct dsc$descriptor date_str={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; + + date_str.dsc$w_length = strlen(time); + date_str.dsc$a_pointer = time; + sys$bintim(&date_str, binval); +} diff --git a/gnu/usr.bin/cvs/vms/vmsmunch.h b/gnu/usr.bin/cvs/vms/vmsmunch.h new file mode 100644 index 00000000000..cc304c9120c --- /dev/null +++ b/gnu/usr.bin/cvs/vms/vmsmunch.h @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------- + + VMSmunch.h + + A few handy #defines, plus the contents of three header files from Joe + Meadows' FILE program. Used by VMSmunch and by various routines which + call VMSmunch (e.g., in Zip and UnZip). + + 02-Apr-1994 Jamie Hanrahan jeh@cmkrnl.com + Moved definition of VMStimbuf struct from vmsmunch.c + to here. + + 06-Apr-1994 Jamie Hanrahan jeh@cmkrnl.com + Moved "contents of three header files" (not needed by + callers of vmsmunch) to vmsmunch_private.h . + + 07-Apr-1994 Richard Levitte levitte@e.kth.se + Inserted a forward declaration of VMSmunch. + ---------------------------------------------------------------------------*/ + +#define GET_TIMES 4 +#define SET_TIMES 0 +#define GET_RTYPE 1 +#define CHANGE_RTYPE 2 +#define RESTORE_RTYPE 3 + +struct VMStimbuf { /* VMSmunch */ + char *actime; /* VMS revision date, ASCII format */ + char *modtime; /* VMS creation date, ASCII format */ +}; + +extern int VMSmunch(); diff --git a/gnu/usr.bin/cvs/vms/vmsmunch_private.h b/gnu/usr.bin/cvs/vms/vmsmunch_private.h new file mode 100644 index 00000000000..33577c1e095 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/vmsmunch_private.h @@ -0,0 +1,176 @@ +/*--------------------------------------------------------------------------- + + VMSmunch_private.h + + Contents of three header files from Joe + Meadows' FILE program. Used by VMSmunch + + 06-Apr-1994 Jamie Hanrahan jeh@cmkrnl.com + Moved "contents of three header files" from + vmsmunch.h to vmsmunch_private.h . + ---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + fatdef.h + ---------------------------------------------------------------------------*/ + +/* This header file was created by Joe Meadows, and is not copyrighted + in any way. No guarantee is made as to the accuracy of the contents + of this header file. This header file was last modified on Sep. 22th, + 1987. (Modified to include this statement) */ +#define FAT$K_LENGTH 32 +#define FAT$C_LENGTH 32 +#define FAT$S_FATDEF 32 + +struct fatdef { + union { + unsigned char fat$b_rtype; + struct { + unsigned fat$v_rtype : 4; + unsigned fat$v_fileorg : 4; + } fat$r_rtype_bits; + } fat$r_rtype_overlay; +# define FAT$S_RTYPE 4 +# define FAT$V_RTYPE 0 +# define FAT$C_UNDEFINED 0 +# define FAT$C_FIXED 1 +# define FAT$C_VARIABLE 2 +# define FAT$C_VFC 3 +# define FAT$C_STREAM 4 +# define FAT$C_STREAMLF 5 +# define FAT$C_STREAMCR 6 +# define FAT$S_FILEORG 4 +# define FAT$V_FILEORG 4 +# define FAT$C_SEQUENTIAL 0 +# define FAT$C_RELATIVE 1 +# define FAT$C_INDEXED 2 +# define FAT$C_DIRECT 3 + union { + unsigned char fat$b_rattrib; + struct { + unsigned fat$v_fortrancc : 1; + unsigned fat$v_impliedcc : 1; + unsigned fat$v_printcc : 1; + unsigned fat$v_nospan : 1; + } fat$r_rattrib_bits; + } fat$r_rattrib_overlay; +# define FAT$V_FORTRANCC 0 +# define FAT$M_FORTRANCC 1 +# define FAT$V_IMPLIEDCC 1 +# define FAT$M_IMPLIEDCC 2 +# define FAT$V_PRINTCC 2 +# define FAT$M_PRINTCC 4 +# define FAT$V_NOSPAN 3 +# define FAT$M_NOSPAN 8 + unsigned short int fat$w_rsize; + union + { + unsigned long int fat$l_hiblk; + struct + { + unsigned short int fat$w_hiblkh; + unsigned short int fat$w_hiblkl; + } fat$r_hiblk_fields; + } fat$r_hiblk_overlay; + union + { + unsigned long int fat$l_efblk; + struct + { + unsigned short int fat$w_efblkh; + unsigned short int fat$w_efblkl; + } fat$r_efblk_fields; + } fat$r_efblk_overlay; + unsigned short int fat$w_ffbyte; + unsigned char fat$b_bktsize; + unsigned char fat$b_vfcsize; + unsigned short int fat$w_maxrec; + unsigned short int fat$w_defext; + unsigned short int fat$w_gbc; + char fat$fill[8]; + unsigned short int fat$w_versions; +}; + +/*--------------------------------------------------------------------------- + fchdef.h + ---------------------------------------------------------------------------*/ + +/* This header file was created by Joe Meadows, and is not copyrighted + in any way. No guarantee is made as to the accuracy of the contents + of this header file. This header file was last modified on Sep. 22th, + 1987. (Modified to include this statement) */ + +#define FCH$V_BADACL 0x00B +#define FCH$M_BADACL (1 << FCH$V_ACL) +#define FCH$V_BADBLOCK 0x00E +#define FCH$M_BADBLOCK (1 << FCH$V_BADBLOCK) +#define FCH$V_CONTIG 0x007 +#define FCH$M_CONTIG (1 << FCH$V_CONTIG) +#define FCH$V_CONTIGB 0x005 +#define FCH$M_CONTIGB (1 << FCH$V_CONTIGB) +#define FCH$V_DIRECTORY 0x00D +#define FCH$M_DIRECTORY (1 << FCH$V_DIRECTORY) +#define FCH$V_ERASE 0x011 +#define FCH$M_ERASE (1 << FCH$V_ERASE) +#define FCH$V_LOCKED 0x006 +#define FCH$M_LOCKED (1 << FCH$V_LOCKED) +#define FCH$V_MARKDEL 0x00F +#define FCH$M_MARKDEL (1 << FCH$V_MARKDEL) +#define FCH$V_NOBACKUP 0x001 +#define FCH$M_NOBACKUP (1 << FCH$V_NOBACKUP) +#define FCH$V_NOCHARGE 0x010 +#define FCH$M_NOCHARGE (1 << FCH$V_NOCHARGE) +#define FCH$V_READCHECK 0x003 +#define FCH$M_READCHECK (1 << FCH$V_READCHECK) +#define FCH$V_SPOOL 0x00C +#define FCH$M_SPOOL (1 << FCH$V_SPOOL) +#define FCH$V_WRITCHECK 0x004 +#define FCH$M_WRITCHECK (1 << FCH$V_WRITCHECK) +#define FCH$V_WRITEBACK 0x002 +#define FCH$M_WRITEBACK (1 << FCH$V_WRITEBACK) + +struct fchdef { + unsigned : 1; + unsigned fch$v_nobackup : 1 ; + unsigned fch$v_writeback : 1; + unsigned fch$v_readcheck : 1; + unsigned fch$v_writcheck : 1; + unsigned fch$v_contigb : 1; + unsigned fch$v_locked : 1; + unsigned fch$v_contig : 1; + unsigned : 3; + unsigned fch$v_badacl : 1; + unsigned fch$v_spool : 1; + unsigned fch$v_directory : 1; + unsigned fch$v_badblock : 1; + unsigned fch$v_markdel : 1; + unsigned fch$v_nocharge : 1; + unsigned fch$v_erase : 1; +}; + +/*--------------------------------------------------------------------------- + fjndef.h + ---------------------------------------------------------------------------*/ + +/* This header file was created by Joe Meadows, and is not copyrighted + in any way. No guarantee is made as to the accuracy of the contents + of this header file. This header file was last modified on Sep. 22th, + 1987. (Modified to include this statement) */ + +#define FJN$M_ONLY_RU 1 +#define FJN$M_RUJNL 2 +#define FJN$M_BIJNL 4 +#define FJN$M_AIJNL 8 +#define FJN$M_ATJNL 16 +#define FJN$M_NEVER_RU 32 +#define FJN$M_JOURNAL_FILE 64 +#define FJN$S_FJNDEF 1 +struct fjndef { + unsigned fjn$v_only_ru : 1; + unsigned fjn$v_rujnl : 1; + unsigned fjn$v_bijnl : 1; + unsigned fjn$v_aijnl : 1; + unsigned fjn$v_atjnl : 1; + unsigned fjn$v_never_ru : 1; + unsigned fjn$v_journal_file:1; +} ; diff --git a/gnu/usr.bin/cvs/vms/waitpid.c b/gnu/usr.bin/cvs/vms/waitpid.c new file mode 100644 index 00000000000..95d27b3eb31 --- /dev/null +++ b/gnu/usr.bin/cvs/vms/waitpid.c @@ -0,0 +1,68 @@ +/* Emulate waitpid on systems that just have wait. + Copyright (C) 1994 Free Software Foundation, Inc. + +This file is part of GNU DIFF. + +GNU DIFF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU DIFF 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. + +You should have received a copy of the GNU General Public License +along with GNU DIFF; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "vms.h" + +#define WAITPID_CHILDREN 8 +static pid_t waited_pid[WAITPID_CHILDREN]; +static int waited_status[WAITPID_CHILDREN]; + +pid_t +waitpid (pid, stat_loc, options) + pid_t pid; + int *stat_loc; + int options; +{ + int i; + pid_t p; + + if (!options && (0 < pid || pid == -1)) + { + /* If we have already waited for this child, return it immediately. */ + for (i = 0; i < WAITPID_CHILDREN; i++) + { + p = waited_pid[i]; + if (p && (p == pid || pid == -1)) + { + waited_pid[i] = 0; + goto success; + } + } + + /* The child has not returned yet; wait for it, accumulating status. */ + for (i = 0; i < WAITPID_CHILDREN; i++) + if (! waited_pid[i]) + { + p = wait (&waited_status[i]); + if (p < 0) + return p; + if (p == pid || pid == -1) + goto success; + waited_pid[i] = p; + } + } + + /* We cannot emulate this wait call, e.g. because of too many children. */ + abort (); + +success: + if (stat_loc) + *stat_loc = waited_status[i]; + return p; +} diff --git a/gnu/usr.bin/cvs/windows-NT/.cvsignore b/gnu/usr.bin/cvs/windows-NT/.cvsignore index f3c7a7c5da6..311409c80d7 100644 --- a/gnu/usr.bin/cvs/windows-NT/.cvsignore +++ b/gnu/usr.bin/cvs/windows-NT/.cvsignore @@ -1 +1,3 @@ Makefile +check.log +check.plog diff --git a/gnu/usr.bin/cvs/windows-NT/ChangeLog b/gnu/usr.bin/cvs/windows-NT/ChangeLog index 300ad830f41..9589a96dab7 100644 --- a/gnu/usr.bin/cvs/windows-NT/ChangeLog +++ b/gnu/usr.bin/cvs/windows-NT/ChangeLog @@ -1,3 +1,123 @@ +Wed Sep 25 14:31:51 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * options.h (TMPDIR_DFLT): Change from c:\temp to c:\\temp. + +Tue Sep 24 14:37:29 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * options.h: Add TMPDIR_DFLT. + +Tue Sep 10 19:20:25 1996 Mark A. Solinski <markso@mcs.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + This is said to be the last set of changes needed for Win95: + * rcmd.c: Include cvs.h. + (rcmd_authenticate): Use send/recv instead of read/write. + (rcmd): Don't call _open_osfhandle; just return the socket. + * options.h: Move NO_SOCKET_TO_FD from here... + * config.h: ...to here. Update comment. + * config.h (START_SERVER_RETURNS_SOCKET, SEND_NEVER_PARTIAL): + Define. + * startserver.c (shutdown_fd): Remove; it is unused. + (wnt_start_server): Don't dup the file descriptor; instead set + both *tofd and *fromfd to read_fd. + (wnt_shutdown_server): Don't call _get_osfhandle; just use the + argument as the socket. + +Wed Sep 4 1996 Jim Kingdon <kingdon@cyclic.com> + + * filesubr.c (mkdir_if_needed): mkdir on NT only takes one, + not two, arguments. + +Thu Aug 29 09:47:33 1996 Mark A. Solinski <markso@mcs.com> + and Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (deep_remove_dir, unlink_file_dir): ENOENT can also + mean that we tried to unlink a directory (Win95). + +Mon Aug 26 12:47:58 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (mkdir_if_needed): Added. + +Thu Aug 22 19:12:17 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + The following changes are said to be necessary (but not + sufficient) for Win95: + * config.h (sleep): Use "unsigned int" not just "unsigned". + * filesubr.c (deep_remove_dir): Treat EACCES as well as ENOTEMPTY + as an indication that we need to remove the directory. + +Fri Aug 16 16:06:22 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * Makefile.in (installdirs): new (empty) target + +Mon Aug 12 14:45:16 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * config.h: Remove CLIENT_ONLY; it is nowhere used. + +Mon Jul 15 1996 Jim Kingdon <kingdon@cyclic.com> + + * README: Add note about tab stop setting. + +Fri Jun 7 13:07:37 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * config.h: Change INITIALIZE_SOCKET_SUBSYSTEM to + SYSTEM_INITIALIZE to reflect change in ../src/main.c. + +Mon Jun 03 01:00:08 1996 noel <noel@BOAT_ANCHOR> + + * sanity.sh: include new tests from ../src/sanity.sh. + + * filesubr.c (copy_file): use open with O_CREAT instead of creat + so we can also use O_BINARY -- we don't want to do any LF -> CR/LF + translations when we copy files. + +Fri May 17 11:53:13 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * README: In a few places it used to say "server" when it meant + "client". Fix it. Say explicitly that there is no server on NT. + Fix typos (4,0 -> 4.0; CVS.system -> CVS). + +Thu May 16 16:52:45 1996 Noel Cragg <noel@gargle.rain.org> + + * README: explain which utilities are required for client support + and local support in separate paragraphs. + + * filesubr.c (expand_wild): rename max to cvs_max to avoid + conflicts with other already-defined routines. + (get_homedir): rename min to cvs_min. + +Thu May 16 01:18:22 1996 noel <noel@BOAT_ANCHOR> + + * sanity.sh: Hacked version of src/sanity.sh for use under + CYGWIN32. + + * filesubr.c (expand_wild): Since FindFirstFile and FindNextFile + don't return the pathname of a file, we need to keep track of it + ourselves. + + * options.h: Fix defines for DIFF and GREP. + + * run.c (run_exec): Flush stdout and stderr so we end up with the + correct interleaving of output for sanity.sh. This can be removed + later, if desired. + +Wed May 15 23:51:49 1996 Noel Cragg <noel@gargle.rain.org> + + * README: mention that grep is mandatory. + +Tue May 14 1996 Jim Kingdon <kingdon@cyclic.com> + + * filesubr.c (cvs_temp_name): Call _tempnam not tmpnam. + +Tue May 14 13:38:51 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * filesubr.c (cvs_temp_name): New function.. + +Wed May 01 01:28:41 1996 noel <noel@BOAT_ANCHOR> + + * filesubr.c (get_homedir): use both HOMEDRIVE and HOMEPATH to + construct the user's home directory. + Tue Apr 9 20:56:14 1996 Jim Kingdon <kingdon@harvey.cyclic.com> * README: Mention CRLF for src/server.c. diff --git a/gnu/usr.bin/cvs/windows-NT/Makefile.in b/gnu/usr.bin/cvs/windows-NT/Makefile.in index 0275e27249a..2fd0d3a9197 100644 --- a/gnu/usr.bin/cvs/windows-NT/Makefile.in +++ b/gnu/usr.bin/cvs/windows-NT/Makefile.in @@ -39,6 +39,9 @@ all: .PHONY: all install uninstall all install uninstall: +installdirs: +.PHONY: installdirs + .PHONY: tags TAGS tags TAGS: diff --git a/gnu/usr.bin/cvs/windows-NT/README b/gnu/usr.bin/cvs/windows-NT/README index 0f9035985e5..057320e0bb7 100644 --- a/gnu/usr.bin/cvs/windows-NT/README +++ b/gnu/usr.bin/cvs/windows-NT/README @@ -5,10 +5,8 @@ Check the ../INSTALL file for information on the most recent version of CVS which has been known to be tested with NT. -The port implements the full set of CVS commands, but is client only, -not server or local ("local" meaning accessing repositories on a -filesystem mounted on the local machine). The repository must live on -another machine (a Unix box, say) which runs a complete port of CVS. +This port implements the full set of CVS commands, both local and +client. It does not provide a CVS server for NT. We don't distribute a .ZIP source distribution partly because, as far as I can tell, PKZIP insists on munging long file names, which would @@ -20,27 +18,63 @@ the sources get extracted without carriage returns and you must add carriage returns to the end of every line in cvsnt.mak. I also had to add them to src/server.c. It doesn't seem to be necessary to add them to any other file. This makefile was generated with Visual C++ 2.1. -As far as is known, it should work with Visual C++ 4,0 also. +As far as is known, it should work with Visual C++ 4.0 also. Send bug reports to bug-cvs@prep.ai.mit.edu. -As of August 20, 1995, this port passed the test in src/sanity.sh. -(We ran the checks by hand, since we couldn't find a port of the -Bourne shell good enough to execute the script). Sanity.sh provides -pretty minimal feature coverage, but still gives me some confidence it -isn't totally broken. +This port passes all of the tests in src/sanity.sh, save the one that +deals with reserved all-upper-case tags (BASE and HEAD), due to a +limitation in the NT command shell. sanity.sh provides pretty minimal +feature coverage, but still gives me some confidence it isn't totally +broken. -You will also need GNU patch installed on your system. GZIP is useful -but not required. The Congruent ports of these packages to Windows -NT, binary and source, are available in: +To operate in client mode, you will need GNU patch. gzip is useful +but not required. - ftp://microlib.cc.utexas.edu/microlib/nt/gnu +To operate in local mode, you will need GNU patch, GNU diffutils, a +version of grep, and rcs version 5.7 installed on your system. Make +sure NOT to get a version of rcs less than 5.7 (gr564bnt.zip was +particularly bad), because those versions insist on putting their +files in their own directory structure, making them incompatible with +CVS. -If you'd like to finish off the port of local CVS, Morten Hindsholm's -port of CVS 1.4A2 to Windows NT might be helpful; it is available as +Noel Cragg, who did the latest mods to the Windows NT port, used the +following packages: + + ftp://wuarchive.wustl.edu/systems/ibmpc/gnuish/grep15.zip + ** use grepb.exe and egrepb.exe, but install as + ** grep.exe and egrep.exe respectively) + ftp://wuarchive.wustl.edu/systems/ibmpc/gnuish/patch212.zip + ftp://ftp.netcom.com/pub/al/alexande/rcs57nt.zip + ftp://ftp.netcom.com/pub/al/alexande/diff57nt.zip + +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 +and source: + + ftp://microlib.cc.utexas.edu/microlib/nt/gnu/ + +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 +sanity.sh: + + http://www.cygnus.com/misc/gnu-win32/ + +Morten Hindsholm's port of CVS 1.4A2 to Windows NT may be useful if +you're modifying CVS itself: ftp://ftp.digex.net/pub/access/schueman/cvs/cvsnt14b.zip +Mark A. Solinski <markso@www.mcs.net> has ported CVS 1.7 to Windows +95. You can find his source code at: + + http://www.mcs.net/~markso/cvs/cvs95.html + +Here are some other things which may be of interest for unix junkies: + + http://www.halcyon.com/gvr/vim/ (VI clone) + ftp://wuarchive.wustl.edu/systems/ibmpc/gnuish/less177.zip The following harmless warnings are known: @@ -50,3 +84,9 @@ The following harmless warnings are known: .\lib\getdate.c(760) : warning C4013: 'getdate_yyparse' undefined; assuming extern returning int .\lib\getdate.c(1612) : warning C4102: 'yyerrlab' : unreferenced label .\lib\getdate.c(1612) : warning C4102: 'yynewstate' : unreferenced label + +If you want to browse/edit the sources using Visual C++, we recommend +setting tab stops to 8 spaces, since that is what the CVS sources +expect. The tab stop setting is in the "Editor" section of the "Options..." +dialog which is in the "Tools..." menu. + diff --git a/gnu/usr.bin/cvs/windows-NT/config.h b/gnu/usr.bin/cvs/windows-NT/config.h index e65c1172b89..736390a7b4b 100644 --- a/gnu/usr.bin/cvs/windows-NT/config.h +++ b/gnu/usr.bin/cvs/windows-NT/config.h @@ -11,12 +11,6 @@ We just want to avoid a redefinition error message. */ #undef _ALL_SOURCE -/* Define if type char is unsigned and you are not using gcc. */ -/* We wrote a little test program whose output suggests that char is - signed on this system. Go back and check the verdict when CVS - is configured on floss... */ -#undef __CHAR_UNSIGNED__ - /* Define to empty if the keyword does not work. */ /* Const is working. */ #undef const @@ -40,11 +34,6 @@ I have neither the CD-ROM nor a CD-ROM drive to put it in. */ #define HAVE_UTIME_NULL 1 -/* Define as __inline if that's what the C compiler calls it. */ -/* We apparently do have inline functions. The 'inline' keyword is only - available from C++, though. You have to use '__inline' in C code. */ -#define inline __inline - /* Define if on MINIX. */ /* Hah. */ #undef _MINIX @@ -274,7 +263,7 @@ extern pid_t getpid (void); #define USE_PROTOTYPES 1 /* This is just a call to the Win32 Sleep function. */ -unsigned sleep (unsigned); +unsigned int sleep (unsigned int); /* Don't worry, Microsoft, it's okay for these functions to be in our namespace. */ @@ -316,12 +305,6 @@ extern void convert_file (char *INFILE, int INFLAGS, /* This is where old bits go to die under Windows NT. */ #define DEVNULL "nul" -/* Make sure that we don't try to perform operations on RCS files on the - local machine. I think I neglected to apply some changes from - MHI's port in that area of code, or found some issues I didn't want - to deal with. */ -#define CLIENT_ONLY - /* Don't use an rsh subprocess to connect to the server, because the rsh does inappropriate translations on the data (CR-LF/LF). */ #define RSH_NOT_TRANSPARENT 1 @@ -334,7 +317,24 @@ extern void wnt_shutdown_server (int fd); #define START_SERVER wnt_start_server #define SHUTDOWN_SERVER wnt_shutdown_server -#define INITIALIZE_SOCKET_SUBSYSTEM init_winsock +#define SYSTEM_INITIALIZE(pargc,pargv) init_winsock() extern void init_winsock(); #define HAVE_WINSOCK_H + +/* This tells the client that it must use send()/recv() to talk to the + server if it is connected to the server via a socket; Win95 needs + it because _open_osfhandle doesn't work. */ +#define NO_SOCKET_TO_FD 1 + +/* 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 + (SOCKET) <= sizeof (int) on win32, even the 64-bit variants. */ +#define START_SERVER_RETURNS_SOCKET 1 + +/* Is this true on NT? Seems like I remember reports that NT 3.51 has + problems with 200K writes (of course, the issue of large writes is + moot since the use of buffer.c ensures that writes will only be as big + as the buffers). */ +#define SEND_NEVER_PARTIAL 1 diff --git a/gnu/usr.bin/cvs/windows-NT/filesubr.c b/gnu/usr.bin/cvs/windows-NT/filesubr.c index e3cb9c398df..926e06799d5 100644 --- a/gnu/usr.bin/cvs/windows-NT/filesubr.c +++ b/gnu/usr.bin/cvs/windows-NT/filesubr.c @@ -26,14 +26,6 @@ #include "cvs.h" -/* - * I don't know of a convenient way to test this at configure time, or else - * I'd certainly do it there. - */ -#if defined(NeXT) -#define LOSING_TMPNAM_FUNCTION -#endif - static int deep_remove_dir PROTO((const char *path)); /* @@ -62,7 +54,8 @@ copy_file (from, to) error (1, errno, "cannot open %s for copying", from); if (fstat (fdin, &sb) < 0) error (1, errno, "cannot fstat %s", from); - if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0) + if ((fdout = open (to, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, + (int) sb.st_mode & 07777)) < 0) error (1, errno, "cannot create %s for copying", to); if (sb.st_size > 0) { @@ -307,6 +300,33 @@ make_directories (name) (void) mkdir (name); } +/* Create directory NAME if it does not already exist; fatal error for + other errors. Returns 0 if directory was created; 1 if it already + existed. */ +int +mkdir_if_needed (name) + char *name; +{ + if (mkdir (name) < 0) + { + if (errno != EEXIST +#ifdef EACCESS + /* This was copied over from the OS/2 code; I would guess it + isn't needed here but that has not been verified. */ + && errno != EACCESS +#endif +#ifdef EACCES + /* This is said to be needed by NT on Alpha or PowerPC + (not sure what version) --August, 1996. */ + && errno != EACCES +#endif + ) + error (1, errno, "cannot make directory %s", name); + return 1; + } + return 0; +} + /* * Change the mode of a file, either adding write permissions, or removing * all write permissions. Adding write permissions honors the current umask @@ -461,8 +481,8 @@ unlink_file_dir (f) if (unlink (f) != 0) { /* under Windows NT, unlink returns EACCES if the path - is a directory. */ - if (errno == EISDIR || errno == EACCES) + is a directory. Under Windows 95, ENOENT. */ + if (errno == EISDIR || errno == EACCES || errno == ENOENT) return deep_remove_dir (f); else /* The file wasn't a directory and some other @@ -486,7 +506,9 @@ deep_remove_dir (path) struct dirent *dp; char buf[PATH_MAX]; - if ( rmdir (path) != 0 && errno == ENOTEMPTY ) + /* ENOTEMPTY for NT (obvious) but EACCES for Win95 (not obvious) */ + if (rmdir (path) != 0 + && (errno == ENOTEMPTY || errno == EACCES)) { if ((dirp = opendir (path)) == NULL) /* If unable to open the directory return @@ -506,7 +528,14 @@ deep_remove_dir (path) chmod (buf, _S_IWRITE); if (unlink (buf) != 0 ) { - if (errno == EISDIR || errno == EACCES) + /* Under Windows NT, unlink returns EACCES if the path + is a directory. Under Windows 95, ENOENT. It + isn't really clear to me whether checking errno is + better or worse than using _stat to check for a directory. + We aren't really trying to prevent race conditions here + (e.g. what if something changes between readdir and + unlink?) */ + if (errno == EISDIR || errno == EACCES || errno == ENOENT) { if (deep_remove_dir (buf)) { @@ -728,7 +757,21 @@ fnfold (char *filename) } } + +/* Generate a unique temporary filename. Returns a pointer to a newly + malloc'd string containing the name. Returns successfully or not at + all. */ +char * +cvs_temp_name () +{ + char *retval; + retval = _tempnam (NULL, NULL); + if (retval == NULL) + error (1, errno, "cannot generate temporary filename"); + return retval; +} + /* Return non-zero iff FILENAME is absolute. Trivial under Unix, but more complicated under other systems. */ int @@ -787,10 +830,37 @@ convert_file (char *infile, int inflags, error (0, errno, "warning: couldn't close %s", infile); } + +/* NT has two evironment variables, HOMEPATH and HOMEDRIVE, which, + when combined as ${HOMEDRIVE}${HOMEPATH}, give the unix equivalent + of HOME. Some NT users are just too unixy, though, and set the + HOME variable themselves. Therefore, we check for HOME first, and + then try to combine the other two if that fails. */ + char * get_homedir () { - return getenv ("HOMEPATH"); + static char pathbuf[PATH_MAX * 2]; + char *hd, *hp; + + if ((hd = getenv ("HOME"))) + return hd; + else if ((hd = getenv ("HOMEDRIVE")) && (hp = getenv ("HOMEPATH"))) + { + /* Watch for buffer overruns. */ + +#define cvs_min(x,y) ((x <= y) ? (x) : (y)) + + int ld = cvs_min (PATH_MAX, strlen (hd)); + int lp = cvs_min (PATH_MAX, strlen (hp)); + + strncpy (pathbuf, hd, ld); + strncpy (pathbuf + ld, hp, lp); + + return pathbuf; + } + else + return NULL; } /* See cvs.h for description. */ @@ -817,6 +887,34 @@ expand_wild (argc, argv, pargc, pargv) HANDLE h; WIN32_FIND_DATA fdata; + /* These variables help us extract the directory name from the + given pathname. */ + + char *last_forw_slash, *last_back_slash, *end_of_dirname; + int dirname_length = 0; + + /* 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 + of the path. For example, + /a/path/q*.h valid + /w32/q*.dir/cant/do/this/q*.h invalid */ + + /* Win32 can handle both forward and backward slashes as + filenames -- check for both. */ + + last_forw_slash = strrchr (argv[i], '/'); + last_back_slash = strrchr (argv[i], '\\'); + +#define cvs_max(x,y) ((x >= y) ? (x) : (y)) + + end_of_dirname = cvs_max (last_forw_slash, last_back_slash); + + if (end_of_dirname == NULL) + dirname_length = 0; /* no directory name */ + else + dirname_length = end_of_dirname - argv[i] + 1; /* include slash */ + h = FindFirstFile (argv[i], &fdata); if (h == INVALID_HANDLE_VALUE) { @@ -842,7 +940,26 @@ expand_wild (argc, argv, pargc, pargv) { while (1) { - new_argv [new_argc++] = xstrdup (fdata.cFileName); + new_argv[new_argc] = + (char *) xmalloc (strlen (fdata.cFileName) + 1 + + dirname_length); + + /* Copy the directory name, if there is one. */ + + if (dirname_length) + { + strncpy (new_argv[new_argc], argv[i], dirname_length); + new_argv[new_argc][dirname_length] = '\0'; + } + else + new_argv[new_argc][0] = '\0'; + + /* Copy the file name. */ + + strcat (new_argv[new_argc], fdata.cFileName); + + new_argc++; + if (new_argc == max_new_argc) { max_new_argc *= 2; diff --git a/gnu/usr.bin/cvs/windows-NT/options.h b/gnu/usr.bin/cvs/windows-NT/options.h index c85e9d7763b..793a8a06c96 100644 --- a/gnu/usr.bin/cvs/windows-NT/options.h +++ b/gnu/usr.bin/cvs/windows-NT/options.h @@ -65,7 +65,7 @@ */ #ifndef DIFF -#define DIFF "@gdiff_path@" +#define DIFF "diff" #endif /* @@ -76,7 +76,7 @@ */ #ifndef GREP -#define GREP "@ggrep_path@" +#define GREP "grep" #endif /* @@ -119,6 +119,17 @@ #endif /* + * The password-authenticating server creates a temporary checkout of + * the affected files. The variable TMPDIR_DFLT (or even better, the + * command-line option "-T" in the line for CVS in /etc/inetd.conf) + * can be used to specify the used directory. This directory will + * also be used for other temporary files. + */ +#ifndef TMPDIR_DFLT +#define TMPDIR_DFLT "c:\\temp" +#endif + +/* * The default editor to use, if one does not specify the "-e" option to cvs, * or does not have an EDITOR environment variable. I set this to just "vi", * and use the shell to find where "vi" actually is. This allows sites with @@ -232,16 +243,6 @@ */ #define AUTH_CLIENT_SUPPORT 1 -/* - * This tells the client that it must use send()/recv() to talk to the - * server if it is connected to the server via a socket; Win95 is said to - * need it because _open_osfhandle doesn't work. This is only - * implemented for pserver, not rsh. Furthermore, NT doesn't seem to have send() - * and recv(), or maybe one has to link against a different library or something, - * I don't know. So this is commented out. - */ -#define NO_SOCKET_TO_FD 1 - /* End of CVS configuration section */ /* diff --git a/gnu/usr.bin/cvs/windows-NT/rcmd.c b/gnu/usr.bin/cvs/windows-NT/rcmd.c index 7e5ed3d8254..e0f3619ae45 100644 --- a/gnu/usr.bin/cvs/windows-NT/rcmd.c +++ b/gnu/usr.bin/cvs/windows-NT/rcmd.c @@ -9,6 +9,7 @@ #include <stdio.h> #include <assert.h> +#include "cvs.h" #include "rcmd.h" void @@ -151,17 +152,17 @@ rcmd_authenticate (int fd, char *locuser, char *remuser, char *command) server first, but that doesn't seem to work. Transmitting the client username first does. Go figure. The Linux man pages get it right --- hee hee. */ - if (write (fd, "0\0", 2) < 0 - || write (fd, locuser, strlen (locuser) + 1) < 0 - || write (fd, remuser, strlen (remuser) + 1) < 0 - || write (fd, command, strlen (command) + 1) < 0) + if ((send (fd, "0\0", 2, 0) == SOCKET_ERROR) + || (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; /* They sniff our butt, and send us a '\0' character if they like us. */ { char c; - if (read (fd, &c, 1) <= 0 + if (recv (fd, &c, 1, 0) == SOCKET_ERROR || c != '\0') { errno = EPERM; @@ -182,7 +183,6 @@ rcmd (const char **ahost, { struct sockaddr_in sai; SOCKET s; - int fd; assert (fd2p == 0); @@ -206,14 +206,8 @@ rcmd (const char **ahost, return -1; #endif - /* When using WinSock under Windows NT, sockets are low-level Windows - NT handles. Turn the socket we've made into a Unix-like file - descriptor. */ - if ((fd = _open_osfhandle (s, _O_BINARY)) < 0) + if (rcmd_authenticate (s, locuser, remuser, cmd) < 0) return -1; - if (rcmd_authenticate (fd, locuser, remuser, cmd) < 0) - return -1; - - return fd; + return s; } diff --git a/gnu/usr.bin/cvs/windows-NT/run.c b/gnu/usr.bin/cvs/windows-NT/run.c index 777b1521978..e0b01466af2 100644 --- a/gnu/usr.bin/cvs/windows-NT/run.c +++ b/gnu/usr.bin/cvs/windows-NT/run.c @@ -211,6 +211,14 @@ run_exec (stin, stout, sterr, flags) run_print (stderr); (void) fprintf (stderr, ")\n"); } + + /* Flush standard output and standard error, or otherwise we end + up with strange interleavings of stuff called from CYGWIN + vs. CMD. */ + + fflush (stderr); + fflush (stdout); + if (noexec && (flags & RUN_REALLY) == 0) /* if in noexec mode */ return (0); @@ -307,6 +315,13 @@ run_exec (stin, stout, sterr, flags) (void) close( saerr); } + /* Flush standard output and standard error, or otherwise we end + up with strange interleavings of stuff called from CYGWIN + vs. CMD. */ + + fflush (stderr); + fflush (stdout); + /* Recognize the return code for an interrupted subprocess. */ if (rval == CONTROL_C_EXIT) return 2; diff --git a/gnu/usr.bin/cvs/windows-NT/startserver.c b/gnu/usr.bin/cvs/windows-NT/startserver.c index e3460d0674b..3de8cca6a7b 100644 --- a/gnu/usr.bin/cvs/windows-NT/startserver.c +++ b/gnu/usr.bin/cvs/windows-NT/startserver.c @@ -10,20 +10,6 @@ #include <io.h> #include <errno.h> - -/* Apply the Winsock shutdown function to a CRT file descriptor. */ -static void -shutdown_fd (int fd, int how) -{ - SOCKET s; - - if ((s = _get_osfhandle (fd)) < 0) - error (1, errno, "couldn't get socket handle from file descriptor"); - if (shutdown (s, how) == SOCKET_ERROR) - error (1, 0, "couldn't shut down socket half"); -} - - void wnt_start_server (int *tofd, int *fromfd, char *client_user, @@ -35,7 +21,7 @@ wnt_start_server (int *tofd, int *fromfd, char *command; struct servent *sptr; unsigned short port; - int read_fd, write_fd; + int read_fd; char *portenv; if (! (cvs_server = getenv ("CVS_SERVER"))) @@ -61,19 +47,8 @@ wnt_start_server (int *tofd, int *fromfd, 0); if (read_fd < 0) error (1, errno, "cannot start server via rcmd"); - - /* Split the socket into a reading and a writing half. */ - if ((write_fd = dup (read_fd)) < 0) - error (1, errno, "duplicating server connection"); -#if 0 - /* This ought to be legal, since I've duped it, but shutting - down the writing end of read_fd seems to terminate the - whole connection. */ - shutdown_fd (read_fd, 1); - shutdown_fd (write_fd, 0); -#endif - - *tofd = write_fd; + + *tofd = read_fd; *fromfd = read_fd; free (command); } @@ -83,9 +58,8 @@ void wnt_shutdown_server (int fd) { SOCKET s; - - if ((s = _get_osfhandle (fd)) < 0) - error (1, errno, "couldn't get handle of server connection"); + + s = fd; if (shutdown (s, 2) == SOCKET_ERROR) error (1, 0, "couldn't shutdown server connection"); if (closesocket (s) == SOCKET_ERROR) diff --git a/gnu/usr.bin/cvs/zlib/ChangeLog b/gnu/usr.bin/cvs/zlib/ChangeLog new file mode 100644 index 00000000000..0db0b1a8f09 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/ChangeLog @@ -0,0 +1,250 @@ +Wed Sep 11 00:59:44 1996 Jim Kingdon <kingdon@harvey.cyclic.com> + + * build_zlib.com: Add infblock.c and infcodes.c. + + * build_zlib.com: New file. + + * Makefile.in (DISTFILES): Add build_zlib.com. + +Fri Aug 16 16:07:38 1996 Norbert Kiesel <nk@col.sw-ley.de> + + * Makefile.in (installdirs): new (empty) target + + ChangeLog file for zlib + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/gnu/usr.bin/cvs/zlib/INDEX b/gnu/usr.bin/cvs/zlib/INDEX new file mode 100644 index 00000000000..bb1e3f0b135 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/INDEX @@ -0,0 +1,51 @@ +ChangeLog history of changes +INDEX this file +Make_vms.com script for Vax/VMS +Makefile makefile for Unix (generated by configure) +Makefile.b32 makefile for Borland C++ 32-bit +Makefile.bor makefile for Borland C/C++ 16-bit +Makefile.dj2 makefile for DJGPP 2.x +Makefile.in makefile for Unix (template for configure) +Makefile.msc makefile for Microsoft C 16-bit +Makefile.riscos makefile for RISCOS +Makefile.sas makefile for Amiga SAS/C +Makefile.tc makefile for Turbo C +Makefile.wat makefile for Watcom C +README guess what +algorithm.doc description of the compression & decompression algorithms +configure configure script for Unix +descrip.mms makefile for Vax/VMS +zlib.def definition file for Windows DLL +zlib.rc definition file for Windows DLL + + + zlib public header files (must be kept): +zconf.h +zlib.h + + private source files used to build the zlib library: +adler32.c +compress.c +crc32.c +deflate.c +deflate.h +gzio.c +infblock.c +infblock.h +infcodes.c +infcodes.h +inffast.c +inffast.h +inflate.c +inftrees.c +inftrees.h +infutil.c +infutil.h +trees.c +uncompr.c +zutil.c +zutil.h + + source files for sample programs: +example.c +minigzip.c diff --git a/gnu/usr.bin/cvs/zlib/Make_vms.com b/gnu/usr.bin/cvs/zlib/Make_vms.com new file mode 100644 index 00000000000..0008d00bb68 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Make_vms.com @@ -0,0 +1,115 @@ +$! make libz under VMS +$! written by Martin P.J. Zinser <m.zinser@gsi.de> +$! +$! Look for the compiler used +$! +$ ccopt = "" +$ if f$getsyi("HW_MODEL").ge.1024 +$ then +$ ccopt = "/prefix=all"+ccopt +$ comp = "__decc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" +$ then +$ comp = "__vaxc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: +$ ccopt = "/decc/prefix=all"+ccopt +$ comp = "__decc__=1" +$ endif +$ endif +$! +$! Build the thing plain or with mms +$! +$ write sys$output "Compiling Zlib sources ..." +$ if f$search("SYS$SYSTEM:MMS.EXE").eqs."" +$ then +$ dele example.obj;*,minigzip.obj;* +$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - + adler32.c zutil.h zlib.h zconf.h +$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - + compress.c zlib.h zconf.h +$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - + crc32.c zutil.h zlib.h zconf.h +$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - + deflatec.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" - + gsio.c zutil.h zlib.h zconf.h +$ CALL MAKE infblock.OBJ "CC ''CCOPT' infblock" - + infblock.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE infcodes.OBJ "CC ''CCOPT' infcodes" - + infcodes.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - + inffast.c zutil.h zlib.h zconf.h inffast.h +$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - + inflate.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - + inftrees.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE infutil.OBJ "CC ''CCOPT' infutil" - + infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h +$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - + trees.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - + uncompr.c zlib.h zconf.h +$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - + zutil.c zutil.h zlib.h zconf.h +$ write sys$output "Building Zlib ..." +$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ +$ write sys$output "Building example..." +$ CALL MAKE example.OBJ "CC ''CCOPT' example" - + example.c zlib.h zconf.h +$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb +$ write sys$output "Building minigzip..." +$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" - + minigzip.c zlib.h zconf.h +$ call make minigzip.exe - + "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - + minigzip.obj libz.olb +$ else +$ mms/macro=('comp') +$ endif +$ write sys$output "Zlib build completed" +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/gnu/usr.bin/cvs/zlib/Makefile b/gnu/usr.bin/cvs/zlib/Makefile new file mode 100644 index 00000000000..722cffa5e04 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Makefile @@ -0,0 +1,150 @@ +# Generated automatically from Makefile.in by configure. +# Makefile for zlib +# Copyright (C) 1995-1996 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +srcdir = . +top_srcdir = .. + +# To compile and test, type: +# ./configure; make test +# The call of configure is optional if you don't have special requirements + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +LDFLAGS=-L. -lz +LDSHARED=$(CC) + +VER=1.0.4 +LIBS=libz.a + +# For CVS, separate AR and ARFLAGS. +AR=ar +RANLIB=ranlib +TAR=tar + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +# build_zlib.com added for CVS +DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] descrip.mms \ + zlib.def zlib.rc algorithm.doc *.[ch] \ + build_zlib.com + +# For CVS, just build libz.a +all: libz.a + +test: all + ./example + echo hello world | ./minigzip | ./minigzip -d + +# For CVS, use an explict rc after $(AR). +libz.a: $(OBJS) + $(AR) rc $@ $(OBJS) + -@ ($(RANLIB) $@ || true) 2>/dev/null + +libz.so.$(VER): $(OBJS) + $(LDSHARED) -o $@ $(OBJS) + rm -f libz.so; ln -s $@ libz.so + +example: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +# For CVS, remove the install and uninstall targets. +install: +uninstall: +.PHONY: install uninstall + +installdirs: +.PHONY: installdirs + +# mostlyclean added for CVS. +clean mostlyclean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz + +# distclean and realclean added for CVS. +distclean realclean: clean + rm -f Makefile +.PHONY: distclean realclean + +# dist-dir added for CVS. +dist-dir: + mkdir ${DISTDIR} + for i in `cd $(srcdir); echo ${DISTFILES}`; do \ + ln $(srcdir)/$${i} ${DISTDIR}; \ + done +.PHONY: dist-dir + +# ls added for CVS. +ls: + @echo $(DISTFILES) +.PHONY: ls + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +# Makefile target added for CVS. +subdir = zlib +Makefile: ../config.status Makefile.in + cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/gnu/usr.bin/cvs/zlib/Makefile.b32 b/gnu/usr.bin/cvs/zlib/Makefile.b32 new file mode 100644 index 00000000000..fc3ac689892 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Makefile.b32 @@ -0,0 +1,104 @@ +# Makefile for zlib +# Borland C++ + +# This version of the zlib makefile was adapted by Chris Young for use +# with Borland C 4.5x with the Dos Power Pack for a 32-bit protected mode +# flat memory model. It was created for use with POV-Ray ray tracer and +# you may choose to edit the CFLAGS to suit your needs but the +# switches -WX and -DMSDOS are required. +# -- Chris Young 76702.1655@compuserve.com + +# To use, do "make -fmakefile.b32" + +# See zconf.h for details about the memory requirements. + +# ------------- Borland C++ ------------- +MODEL=-WX +CFLAGS= $(MODEL) -P-C -K -N- -k- -d -3 -r- -v- -f -DMSDOS +CC=bcc32 +LD=bcc32 +LIB=tlib +LDFLAGS= $(MODEL) +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +all: test + +adler32.obj: adler32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) + del zlib.lib + $(LIB) zlib +$(OBJP1) + $(LIB) zlib +$(OBJP2) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/gnu/usr.bin/cvs/zlib/Makefile.bor b/gnu/usr.bin/cvs/zlib/Makefile.bor new file mode 100644 index 00000000000..2116563d6fc --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Makefile.bor @@ -0,0 +1,105 @@ +# Makefile for zlib +# Borland C++ ************ UNTESTED *********** + +# To use, do "make -fmakefile.bor" +# To compile in small model, set below: MODEL=-ms + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to CFLAGS below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Turbo C++, Borland C++ ------------- +MODEL=-ml +CFLAGS=-O2 -Z $(MODEL) +CC=bcc +LD=bcc +LIB=tlib +# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version +LDFLAGS=$(MODEL) +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +all: test + +adler32.obj: adler32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) + del zlib.lib + $(LIB) zlib +$(OBJP1) + $(LIB) zlib +$(OBJP2) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/gnu/usr.bin/cvs/zlib/Makefile.dj2 b/gnu/usr.bin/cvs/zlib/Makefile.dj2 new file mode 100644 index 00000000000..398f28bbee3 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Makefile.dj2 @@ -0,0 +1,93 @@ +# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96. +# Copyright (C) 1995-1996 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.dj2; make test -fmakefile.dj2 +# +# To install libz.a, zconf.h and zlib.h in the djgpp directories, type: +# +# make install -fmakefile.dj2 +# +# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as +# in the sample below if the pattern of the DJGPP distribution is to +# be followed. Remember that, while <sp>'es around <=> are ignored in +# makefiles, they are *not* in batch files or in djgpp.env. +# - - - - - +# [make] +# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include +# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib +# BUTT=-m486 +# - - - - - +# Alternately, these variables may be defined below, overriding the values +# in djgpp.env, as +INCLUDE_PATH=c:\usr\include + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is not found, replace with copy /Y . +CP=cp -f +# If install.exe is not found, replace with $(CP). +INSTALL=install +# The default value of RM is "rm -f." If "rm.exe" is not found, uncomment: +# RM=del +LDLIBS=-L. -lz +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=libz.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +libz.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + +# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env . + +.PHONY : uninstall clean + +install: $(INCL) $(LIBS) + -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH) + -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH) + for %%f in ($(INCL)) do $(INSTALL) %%f $(INCLUDE_PATH) + for %%p in ($(LIBS)) do $(INSTALL) %%p $(LIBRARY_PATH) + +uninstall: + for %%f in ($(INCL)) do $(RM) $(INCLUDE_PATH)\%%f + for %%p in ($(LIBS)) do $(RM) $(LIBRARY_PATH)\%%p + +clean: + for %%p in (*.d *.o *.exe libz.a libz.so* foo.gz) do $(RM) %%p + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/gnu/usr.bin/cvs/zlib/Makefile.in b/gnu/usr.bin/cvs/zlib/Makefile.in new file mode 100644 index 00000000000..7b585adad35 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Makefile.in @@ -0,0 +1,150 @@ +# Makefile for zlib +# Copyright (C) 1995-1996 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +# To compile and test, type: +# ./configure; make test +# The call of configure is optional if you don't have special requirements + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +LDFLAGS=-L. -lz +LDSHARED=$(CC) + +VER=1.0.4 +LIBS=libz.a + +# For CVS, separate AR and ARFLAGS. +AR=ar +RANLIB=ranlib +TAR=tar + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +# build_zlib.com added for CVS +DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] descrip.mms \ + zlib.def zlib.rc algorithm.doc *.[ch] \ + build_zlib.com + +# For CVS, just build libz.a +all: libz.a + +test: all + ./example + echo hello world | ./minigzip | ./minigzip -d + +# For CVS, use an explict rc after $(AR). +libz.a: $(OBJS) + $(AR) rc $@ $(OBJS) + -@ ($(RANLIB) $@ || true) 2>/dev/null + +libz.so.$(VER): $(OBJS) + $(LDSHARED) -o $@ $(OBJS) + rm -f libz.so; ln -s $@ libz.so + +example: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +# For CVS, remove the install and uninstall targets. +install: +uninstall: +.PHONY: install uninstall + +installdirs: +.PHONY: installdirs + +# mostlyclean added for CVS. +clean mostlyclean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz + +# distclean and realclean added for CVS. +distclean realclean: clean + rm -f Makefile +.PHONY: distclean realclean + +# dist-dir added for CVS. +dist-dir: + mkdir ${DISTDIR} + for i in `cd $(srcdir); echo ${DISTFILES}`; do \ + ln $(srcdir)/$${i} ${DISTDIR}; \ + done +.PHONY: dist-dir + +# ls added for CVS. +ls: + @echo $(DISTFILES) +.PHONY: ls + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +# Makefile target added for CVS. +subdir = zlib +Makefile: ../config.status Makefile.in + cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/gnu/usr.bin/cvs/zlib/Makefile.msc b/gnu/usr.bin/cvs/zlib/Makefile.msc new file mode 100644 index 00000000000..112684af0f5 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Makefile.msc @@ -0,0 +1,101 @@ +# Makefile for zlib +# Microsoft C 5.1 or later + +# To use, do "make makefile.msc" +# To compile in small model, set below: MODEL=-AS + +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to CFLAGS below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Microsoft C 5.1 and later ------------- +MODEL=-AL +CFLAGS=-Oait -Gs -nologo -W3 $(MODEL) +#-Ox generates bad code with MSC 5.1 +CC=cl +LD=link +LDFLAGS=/e/st:0x1000/noe +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +all: zlib.lib example.exe minigzip.exe + +adler32.obj: adler32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) + if exist zlib.lib del zlib.lib + lib zlib $(OBJ1); + lib zlib $(OBJ2); + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj,,,zlib.lib; + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj,,,zlib.lib; + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/gnu/usr.bin/cvs/zlib/Makefile.riscos b/gnu/usr.bin/cvs/zlib/Makefile.riscos new file mode 100644 index 00000000000..0f10aa8918c --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Makefile.riscos @@ -0,0 +1,46 @@ +# Project: zlib_1_03 + + +# Toolflags: +CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fnah +C++flags = -c -depend !Depend -IC: -throwback +Linkflags = -aif -c++ -o $@ +ObjAsmflags = -throwback -NoCache -depend !Depend +CMHGflags = +LibFileflags = -c -l -o $@ +Squeezeflags = -o $@ + + +# Final targets: +@.zlib_lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \ + @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \ + @.o.uncompress @.o.zutil + LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \ + @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \ + @.o.trees @.o.uncompress @.o.zutil +@.test: @.tests.minigzip @.tests.example + echo Please run "Test" in directory tests +@.tests.minigzip: @.o.minigzip @.zlib_lib C:o.Stubs + Link $(Linkflags) @.o.minigzip @.zlib_lib C:o.Stubs +@.tests.example: @.o.example @.zlib_lib C:o.Stubs + Link $(Linkflags) @.o.example @.zlib_lib C:o.Stubs + + +# User-editable dependencies: +.c.o: + cc $(ccflags) -o $@ $< + +# Static dependencies: +@.o.example: @.tests.c.example + cc $(ccflags) -o @.o.example @.tests.c.example +@.o.minigzip: @.tests.c.minigzip + cc $(ccflags) -o @.o.minigzip @.tests.c.minigzip + + +# Dynamic dependencies: +o.minigzip: tests.c.minigzip +o.minigzip: h.zlib +o.minigzip: h.zconf +o.example: tests.c.example +o.example: h.zlib +o.example: h.zconf diff --git a/gnu/usr.bin/cvs/zlib/Makefile.sas b/gnu/usr.bin/cvs/zlib/Makefile.sas new file mode 100644 index 00000000000..5323e821708 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Makefile.sas @@ -0,0 +1,64 @@ +# SMakefile for zlib +# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly +# Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi> +# Amiga, SAS/C 6.56 & Smake + +CC=sc +CFLAGS=OPT +#CFLAGS=OPT CPU=68030 +#CFLAGS=DEBUG=LINE +LDFLAGS=LIB z.lib + +SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \ + NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: SCOPTIONS example minigzip + +test: all + `cd`/example + echo hello world | minigzip | minigzip -d + +install: z.lib + copy zlib.h zconf.h INCLUDE: clone + copy z.lib LIB: clone + +z.lib: $(OBJS) + oml z.lib r $(OBJS) + +example: example.o z.lib + $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS) + +minigzip: minigzip.o z.lib + $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS) + +clean: + -delete force quiet *.o example minigzip z.lib foo.gz *.lnk SCOPTIONS + +SCOPTIONS: Smakefile + copy to $@ <from < +$(SCOPTIONS) +< + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zutil.h zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zutil.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/gnu/usr.bin/cvs/zlib/Makefile.tc b/gnu/usr.bin/cvs/zlib/Makefile.tc new file mode 100644 index 00000000000..a46ce736783 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Makefile.tc @@ -0,0 +1,105 @@ +# Makefile for zlib +# TurboC 2.0 + +# To use, do "make -fmakefile.tc" +# To compile in small model, set below: MODEL=-ms + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to CFLAGS below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Turbo C 2.0 ------------- +MODEL=-ml +# CFLAGS=-O2 -G -Z $(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +CFLAGS=-O2 -G -Z $(MODEL) +CC=tcc -I\tc\include +LD=tcc -L\tc\lib +LIB=tlib +LDFLAGS=$(MODEL) -f- +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +all: test + +adler32.obj: adler32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) + del zlib.lib + $(LIB) zlib +$(OBJP1) + $(LIB) zlib +$(OBJP2) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) -eexample.exe example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) -eminigzip.exe minigzip.obj zlib.lib + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/gnu/usr.bin/cvs/zlib/Makefile.wat b/gnu/usr.bin/cvs/zlib/Makefile.wat new file mode 100644 index 00000000000..2a3b629d3df --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/Makefile.wat @@ -0,0 +1,103 @@ +# Makefile for zlib +# Watcom 10a + +# This version of the zlib makefile was adapted by Chris Young for use +# with Watcom 10a 32-bit protected mode flat memory model. It was created +# for use with POV-Ray ray tracer and you may choose to edit the CFLAGS to +# suit your needs but the -DMSDOS is required. +# -- Chris Young 76702.1655@compuserve.com + +# To use, do "wmake -f makefile.wat" + +# See zconf.h for details about the memory requirements. + +# ------------- Watcom 10a ------------- +MODEL=-mf +CFLAGS= $(MODEL) -fpi87 -fp5 -zp4 -5r -w5 -oneatx -DMSDOS +CC=wcc386 +LD=wcl386 +LIB=wlib -b -c +LDFLAGS= +O=.obj + +# variables +OBJ1=adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) +OBJ2=trees$(O) zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) +OBJ3=infutil$(O) inffast$(O) +OBJP1=adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O) +OBJP2=trees$(O)+zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O) +OBJP3=infutil$(O)+inffast$(O) + +all: test + +adler32.obj: adler32.c zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +crc32.obj: crc32.c zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h & + infcodes.h infutil.h + $(CC) $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h & + infcodes.h inffast.h + $(CC) $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) $(OBJ3) + del zlib.lib + $(LIB) zlib.lib +$(OBJP1) + $(LIB) zlib.lib +$(OBJP2) + $(LIB) zlib.lib +$(OBJP3) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib + +test: minigzip.exe example.exe + example + echo hello world | minigzip | minigzip -d >test + type test + +#clean: +# del *.obj +# del *.exe diff --git a/gnu/usr.bin/cvs/zlib/README b/gnu/usr.bin/cvs/zlib/README new file mode 100644 index 00000000000..28adc90b218 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/README @@ -0,0 +1,99 @@ +zlib 1.0.4 is a general purpose data compression library. All the code +is reentrant (thread safe). The data format used by the zlib library +is described by RFCs (Request for Comments) 1950 to 1952 in the files +ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate +format) and rfc1952.txt (gzip format). These documents are also available in +other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file +zlib.h. A usage example of the library is given in the file example.c +which also tests that the library is working correctly. Another +example is given in the file minigzip.c. The compression library itself +is composed of all source files except example.c and minigzip.c. + +To compile all files and run the test program, follow the instructions +given at the top of Makefile. In short "make test; make install" +should work for most machines. For MSDOS, use one of the special +makefiles such as Makefile.msc; for VMS, use Make_vms.com or descrip.mms. + +Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov> or, +if this fails, to the addresses given below in the Copyright section. +The zlib home page is http://quest.jpl.nasa.gov/zlib/ + +The changes made in version 1.0.4 are documented in the file ChangeLog. +The main changes since 1.0.3 are: + +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) + + +A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk> +is in the CPAN (Comprehensive Perl Archive Network) sites, such as: +ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib* + + +Notes for some targets: + +- For Turbo C the small model is supported only with reduced performance to + avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 + +- For 64-bit Iris, deflate.c must be compiled without any optimization. + With -O, one libpng test fails. The test works in 32 bit mode (with + the -32 compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 + it works when compiled with cc. + +- zlib doesn't work on HP-UX 9.05 with one cc compiler (the one not + accepting the -O option). It works with the other cc compiler. + +- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc + and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL + For help on building a zlib DLL, contact Alessandro Iacopetti + <iaco@email.alessandria.alpcom.it> http://lisa.unial.it/iaco , + or contact Brad Clarke <bclarke@cyberus.ca>. + +- gzdopen is not supported on RISCOS + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate + and zlib specifications were written by Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; + they are too numerous to cite here. + +Copyright notice: + + (C) 1995-1996 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + gzip@prep.ai.mit.edu madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. diff --git a/gnu/usr.bin/cvs/zlib/adler32.c b/gnu/usr.bin/cvs/zlib/adler32.c new file mode 100644 index 00000000000..d651187e44b --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/adler32.c @@ -0,0 +1,48 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: adler32.c,v 1.1.1.1 1996/10/18 03:35:04 tholo Exp $ */ + +#include "zlib.h" + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +uLong adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff --git a/gnu/usr.bin/cvs/zlib/algorithm.doc b/gnu/usr.bin/cvs/zlib/algorithm.doc new file mode 100644 index 00000000000..01902aff666 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/algorithm.doc @@ -0,0 +1,105 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by zlib (also zip and gzip) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for a +longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the longer match is emitted afterwards. Otherwise, +the original match is kept, and the next match search is attempted only +N steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +The real question is, given a Huffman tree, how to decode fast. The most +important realization is that shorter codes are much more common than +longer codes, so pay attention to decoding the short codes fast, and let +the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and set it +for the maximum speed. + +inflate() sends new trees relatively often, so it is possibly set for a +smaller first level table than an application that has only one tree for +all the data. For inflate, which has 286 possible codes for the +literal/length tree, the size of the first table is nine bits. Also the +distance trees have 30 possible values, and the size of the first table is +six bits. Note that for each of those cases, the table ended up one bit +longer than the ``average'' code length, i.e. the code length of an +approximately flat code which would be a little more than eight bits for +286 symbols and a little less than five bits for 30 symbols. It would be +interesting to see if optimizing the first level table for other +applications gave values within a bit or two of the flat code size. + + +Jean-loup Gailly Mark Adler +gzip@prep.ai.mit.edu madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +ftp://ds.internic.net/rfc/rfc1951.txt diff --git a/gnu/usr.bin/cvs/zlib/build_zlib.com b/gnu/usr.bin/cvs/zlib/build_zlib.com new file mode 100644 index 00000000000..cd998fc4918 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/build_zlib.com @@ -0,0 +1,18 @@ +$ CC :== CC/DEBUG/NOOPTIMIZE/STANDARD=VAXC/DEFINE=HAVE_CONFIG_H- +/INCLUDE_DIRECTORY=([-],[-.LIB],[-.SRC],[-.VMS])/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES +$ CC adler32.c +$ CC compress.c +$ CC crc32.c +$ CC uncompr.c +$ CC deflate.c +$ CC trees.c +$ CC zutil.c +$ CC inflate.c +$ CC infblock.c +$ CC inftrees.c +$ CC infcodes.c +$ CC infutil.c +$ CC inffast.c +$ library/create zlib.olb adler32.obj,- +compress.obj,crc32.obj,uncompr.obj,deflate.obj,trees.obj,zutil.obj,- +inflate.obj,infblock.obj,inftrees.obj,infcodes.obj,infutil.obj,inffast.obj diff --git a/gnu/usr.bin/cvs/zlib/compress.c b/gnu/usr.bin/cvs/zlib/compress.c new file mode 100644 index 00000000000..6f8c42ff684 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/compress.c @@ -0,0 +1,57 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: compress.c,v 1.1.1.1 1996/10/18 03:35:04 tholo Exp $ */ + +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 8 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ +int compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, Z_DEFAULT_COMPRESSION); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} diff --git a/gnu/usr.bin/cvs/zlib/configure b/gnu/usr.bin/cvs/zlib/configure new file mode 100644 index 00000000000..a354e4cf407 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/configure @@ -0,0 +1,86 @@ +#!/bin/sh +# configure script for zlib. This script is needed only if +# you wish to build a shared library and your system supports them, +# of if you need special compiler, flags or install directory. +# Otherwise, you can just use directly "make test; make install" +# +# To impose specific compiler or flags or install directory, use for example: +# prefix=$HOME CC=cc CFLAGS="-O4" ./configure +# or for csh/tcsh users: +# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) +# LDSHARED is the command to be used to create a shared library + +LIBS=libz.a +VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` +AR=${AR-"ar rc"} +RANLIB=${RANLIB-"ranlib"} +prefix=${prefix-/usr/local} +exec_prefix=${exec_prefix-$prefix} + +test -z "$CC" && echo Checking for gcc... +test=ztest$$ +cat > $test.c <<EOF +int hello() { printf("hello\n"); } +EOF +if test -z "$CC" && (gcc -c -O3 $test.c) 2>/dev/null; then + CC=gcc + SFLAGS=${CFLAGS-"-fPIC -O3"} + CFLAGS=${CFLAGS-"-O3"} + LDSHARED=${LDSHARED-"gcc -shared"} +else + # find system name and corresponding cc options + CC=${CC-cc} + case `(uname -sr || echo unknown) 2>/dev/null` in + SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."} + CFLAGS=${CFLAGS-"-fast -xcg89"} + LDSHARED=${LDSHARED-"cc -G"};; + SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} + CFLAGS=${CFLAGS-"-O2"} + LDSHARED=${LDSHARED-"ld"};; + IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} + CFLAGS=${CFLAGS-"-ansi -O2"} + LDSHARED=${LDSHARED-"cc -shared"};; + QNX*) SFLAGS=${CFLAGS-"-4 -O"} + CFLAGS=${CFLAGS-"-4 -O"} + LDSHARED=${LDSHARED-"cc"} + RANLIB=${RANLIB-"true"} + AR="cc -A";; + SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} + CFLAGS=${CFLAGS-"-O3"} + LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};; + HP-UX*) SFLAGS=${CFLAGS-"-O +z"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"ld -b"} + SHAREDLIBS='libz.sl';; + # send working options for other systems to gzip@prep.ai.mit.edu + *) SFLAGS=${CFLAGS-"-O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -shared"};; + esac +fi + +echo Checking for shared library support... +# we must test in two steps (cc then ld), required at least on SunOS 4.x +if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" && + test "`($LDSHARED -o $test.so $test.o) 2>&1`" = ""; then + CFLAGS="$SFLAGS" + LIBS='libz.so.$(VER)' + echo Building shared library libz.so.$VER with $CC. +else + LDSHARED="$CC" + echo Building static library $LIBS version $VER with $CC. +fi +rm -f $test.[co] $test.so + +# udpate Makefile +sed < Makefile.in " +/^CC *=/s/=.*/=$CC/ +/^CFLAGS *=/s/=.*/=$CFLAGS/ +/^LDSHARED *=/s/=.*/=$LDSHARED/ +/^LIBS *=/s,=.*,=$LIBS, +/^AR *=/s/=.*/=$AR/ +/^RANLIB *=/s,=.*,=$RANLIB, +/^VER *=/s/=.*/=$VER/ +/^prefix *=/s,=.*,=$prefix, +/^exec_prefix *=/s,=.*,=$exec_prefix, +" > Makefile diff --git a/gnu/usr.bin/cvs/zlib/crc32.c b/gnu/usr.bin/cvs/zlib/crc32.c new file mode 100644 index 00000000000..57f40c7dd9b --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/crc32.c @@ -0,0 +1,162 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: crc32.c,v 1.1.1.1 1996/10/18 03:35:04 tholo Exp $ */ + +#include "zlib.h" + +#define local static + +#ifdef DYNAMIC_CRC_TABLE + +local int crc_table_empty = 1; +local uLongf crc_table[256]; +local void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +local void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +local uLongf crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +#endif + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +uLongf *get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif + return (uLongf *)crc_table; +} + +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong crc32(crc, buf, len) + uLong crc; + const Bytef *buf; + uInt len; +{ + if (buf == Z_NULL) return 0L; +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} diff --git a/gnu/usr.bin/cvs/zlib/deflate.c b/gnu/usr.bin/cvs/zlib/deflate.c new file mode 100644 index 00000000000..4f19327ac0f --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/deflate.c @@ -0,0 +1,1207 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* $Id: deflate.c,v 1.1.1.1 1996/10/18 03:35:04 tholo Exp $ */ + +#include "deflate.h" + +char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_slow OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, charf *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +local config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int noheader = 0; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == Z_NULL) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == Z_NULL) strm->zfree = zcfree; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; + + if (windowBits < 0) { /* undocumented feature: suppress zlib header */ + noheader = 1; + windowBits = -windowBits; + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->noheader = noheader; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->status != INIT_STATE) return Z_STREAM_ERROR; + + s = strm->state; + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); + dictionary += dictLength - length; + } + zmemcpy((charf *)s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->noheader < 0) { + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ + } + s->status = s->noheader ? BUSY_STATE : INIT_STATE; + strm->adler = 1; + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + + if (level == Z_DEFAULT_COMPRESSION) { + level = 6; + } + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the zlib header */ + if (s->status == INIT_STATE) { + + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags = (s->level-1) >> 1; + + if (level_flags > 3) level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = 1L; + } + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUFF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->noheader) return Z_STREAM_END; + + /* Write the zlib trailer (adler32) */ + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + s->noheader = -1; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + status = strm->state->status; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= */ +int deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + *dest = *source; + return Z_STREAM_ERROR; /* to be implemented */ +#if 0 + dest->state = (struct internal_state FAR *) + (*dest->zalloc)(1, sizeof(deflate_state)); + if (dest->state == Z_NULL) return Z_MEM_ERROR; + + *(dest->state) = *(source->state); + return Z_OK; +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + charf *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (!strm->state->noheader) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +} + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp((charf *)s->window + match, + (charf *)s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + } else if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy((charf *)s->window, (charf *)s->window+wsize, + (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage): + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); + + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead, + more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Stored blocks are limited to 0xffff bytes: */ + if (s->strstart == 0 || s->strstart > 0xfffe) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = s->strstart - 0xffff; + s->strstart = 0xffff; + } + + /* Emit a stored block if it is large enough: */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + bflush = _tr_tally(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in hash table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + bflush = _tr_tally (s, 0, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED || + (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + bflush = _tr_tally(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + if (_tr_tally (s, 0, s->window[s->strstart-1])) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally (s, 0, s->window[s->strstart-1]); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/gnu/usr.bin/cvs/zlib/deflate.h b/gnu/usr.bin/cvs/zlib/deflate.h new file mode 100644 index 00000000000..9aed780d1d4 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/deflate.h @@ -0,0 +1,275 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-1996 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* $Id: deflate.h,v 1.1.1.1 1996/10/18 03:35:04 tholo Exp $ */ + +#ifndef _DEFLATE_H +#define _DEFLATE_H + +#include "zutil.h" + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + Bytef *pending_out; /* next pending byte to output to the stream */ + int pending; /* nb of bytes in the pending buffer */ + int noheader; /* suppress zlib header and adler32 */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + ulg compressed_len; /* total bit length of compressed file */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg bits_sent; /* bit length of the compressed data */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +#endif diff --git a/gnu/usr.bin/cvs/zlib/descrip.mms b/gnu/usr.bin/cvs/zlib/descrip.mms new file mode 100644 index 00000000000..9d364598a27 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/descrip.mms @@ -0,0 +1,48 @@ +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser <m.zinser@gsi.de> + +cc_defs = +c_deb = + +.ifdef __DECC__ +pref = /prefix=all +.endif + +OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\ + inftrees.obj, infcodes.obj, infutil.obj, inffast.obj + +CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF) + +all : example.exe minigzip.exe + @ write sys$output " Example applications available" +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib + +clean : + delete *.obj;*,libz.olb;* + + +# Other dependencies. +adler32.obj : zutil.h zlib.h zconf.h +compress.obj : zlib.h zconf.h +crc32.obj : zutil.h zlib.h zconf.h +deflate.obj : deflate.h zutil.h zlib.h zconf.h +example.obj : zlib.h zconf.h +gzio.obj : zutil.h zlib.h zconf.h +infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.obj : zutil.h zlib.h zconf.h infblock.h +inftrees.obj : zutil.h zlib.h zconf.h inftrees.h +infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.obj : zlib.h zconf.h +trees.obj : deflate.h zutil.h zlib.h zconf.h +uncompr.obj : zlib.h zconf.h +zutil.obj : zutil.h zlib.h zconf.h diff --git a/gnu/usr.bin/cvs/zlib/example.c b/gnu/usr.bin/cvs/zlib/example.c new file mode 100644 index 00000000000..4a025240c28 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/example.c @@ -0,0 +1,503 @@ +/* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: example.c,v 1.1.1.1 1996/10/18 03:35:04 tholo Exp $ */ + +#include <stdio.h> +#include "zlib.h" + +#ifdef STDC +# include <string.h> +# include <stdlib.h> +#else + extern void exit OF((int)); +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +const char hello[] = "hello, hello!"; +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ + +const char dictionary[] = "hello"; +uLong dictId; /* Adler32 value of the dictionary */ + +void test_compress OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_gzio OF((const char *out, const char *in, + Byte *uncompr, int uncomprLen)); +void test_deflate OF((Byte *compr, uLong comprLen)); +void test_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_deflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_flush OF((Byte *compr, uLong comprLen)); +void test_sync OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_dict_deflate OF((Byte *compr, uLong comprLen)); +void test_dict_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + uLong len = strlen(hello)+1; + + err = compress(compr, &comprLen, (const Bytef*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad uncompress\n"); + } else { + printf("uncompress(): %s\n", uncompr); + } +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(out, in, uncompr, uncomprLen) + const char *out; /* output file */ + const char *in; /* input file */ + Byte *uncompr; + int uncomprLen; +{ + int err; + int len = strlen(hello)+1; + gzFile file; + + file = gzopen(out, "wb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + + if (gzwrite(file, (const voidp)hello, (unsigned)len) != len) { + fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err)); + } + gzclose(file); + + file = gzopen(in, "rb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + } + strcpy((char*)uncompr, "garbage"); + + uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen); + if (uncomprLen != len) { + fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); + } + gzclose(file); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad gzread\n"); + } else { + printf("gzread(): %s\n", uncompr); + } +} + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_in = compr; + d_stream.next_out = uncompr; + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate\n"); + } else { + printf("inflate(): %s\n", uncompr); + } +} + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + } + + /* Feed in already compressed data and switch to no compression: */ + deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + c_stream.avail_in = (uInt)comprLen/2; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (uInt)uncomprLen; + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + comprLen/2) { + fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); + } else { + printf("large_inflate(): OK\n"); + } +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uInt)comprLen; + err = deflate(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_in = compr; + d_stream.next_out = uncompr; + d_stream.avail_in = 2; /* just read the zlib header */ + d_stream.avail_out = (uInt)uncomprLen; + + inflate(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ + err = inflateSync(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = inflate(&d_stream, Z_FINISH); + if (err != Z_DATA_ERROR) { + fprintf(stderr, "inflate should report DATA_ERROR\n"); + /* Because of incorrect adler32 */ + } + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", uncompr); +} + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = deflateSetDictionary(&c_stream, + (const Bytef*)dictionary, sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (Bytef*)hello; + c_stream.avail_in = (uInt)strlen(hello)+1; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + for (;;) { + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, + sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate with dict\n"); + } else { + printf("inflate with dictionary: %s\n", uncompr); + } +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + Byte *compr, *uncompr; + uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + uLong uncomprLen = comprLen; + + if (zlibVersion()[0] != ZLIB_VERSION[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { + fprintf(stderr, "warning: different zlib version\n"); + } + + compr = (Byte*)calloc((uInt)comprLen, 1); + uncompr = (Byte*)calloc((uInt)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == Z_NULL || uncompr == Z_NULL) { + printf("out of memory\n"); + exit(1); + } + + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : "foo.gz"), + (argc > 2 ? argv[2] : "foo.gz"), + uncompr, (int)uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + test_flush(compr, comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + exit(0); + return 0; /* to avoid warning */ +} diff --git a/gnu/usr.bin/cvs/zlib/gzio.c b/gnu/usr.bin/cvs/zlib/gzio.c new file mode 100644 index 00000000000..54c13e800b2 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/gzio.c @@ -0,0 +1,523 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: gzio.c,v 1.1 1996/10/18 03:35:05 tholo Exp $ */ + +#include <stdio.h> + +#include "zutil.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#define Z_BUFSIZE 4096 + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open return NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + err = inflateInit2(&(s->stream), -MAX_WBITS); + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? FOPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + } else { + check_header(s); /* skip the .gz header */ + } + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[20]; + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "<fd:%d>", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Check the gzip magic header */ + for (len = 0; len < 2; len++) { + c = get_byte(s); + if (c != gz_magic[len]) { + s->transparent = 1; + if (c != EOF) s->stream.avail_in++, s->stream.next_in--; + s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; + return; + } + } + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { + err = deflateEnd(&(s->stream)); + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + s->stream.next_out = next_out = buf; + s->stream.avail_out = len; + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, + s->file); + } + return (int)(len - s->stream.avail_out); + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc || getLong(s) != s->stream.total_out) { + s->z_err = Z_DATA_ERROR; + } else { + /* Check for concatenated .gz files: */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + return (int)(len - s->stream.avail_out); +} + +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int gzwrite (file, buf, len) + gzFile file; + const voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, buf, len); + + return (int)(len - s->stream.avail_in); +} + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ +int gzflush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->z_err = deflate(&(s->stream), flush); + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int gzclose (file) + gzFile file; +{ + int err; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { + err = gzflush (file, Z_FINISH); + if (err != Z_OK) return destroy(file); + + putLong (s->file, s->crc); + putLong (s->file, s->stream.total_in); + + } + return destroy(file); +} + +/* =========================================================================== + Returns the error message for the last error which occured on the + given compressed file. errnum is set to zlib error number. If an + error occured in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char* gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} diff --git a/gnu/usr.bin/cvs/zlib/infblock.c b/gnu/usr.bin/cvs/zlib/infblock.c new file mode 100644 index 00000000000..cc2e6745a78 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/infblock.c @@ -0,0 +1,402 @@ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* Table for deflate from PKZIP's appnote.txt. */ +local uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +void inflate_blocks_reset(s, z, c) +inflate_blocks_statef *s; +z_streamp z; +uLongf *c; +{ + if (s->checkfn != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + { + inflate_codes_free(s->sub.decode.codes, z); + inflate_trees_free(s->sub.decode.td, z); + inflate_trees_free(s->sub.decode.tl, z); + } + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0); + Trace((stderr, "inflate: blocks reset\n")); +} + + +inflate_blocks_statef *inflate_blocks_new(z, c, w) +z_streamp z; +check_func c; +uInt w; +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Trace((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, &s->check); + return s; +} + + +#ifdef DEBUG + extern uInt inflate_hufts; +#endif +int inflate_blocks(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Trace((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Trace((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.tl = Z_NULL; /* don't try to free these */ + s->sub.decode.td = Z_NULL; + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Trace((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if (t < 19) + t = 19; + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + s->mode = BAD; + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->word.what.Bits; + c = h->more.Base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + inflate_trees_free(s->sub.trees.tb, z); + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; +#ifdef DEBUG + inflate_hufts = 0; +#endif + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + s->mode = BAD; + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok, %d * %d bytes used\n", + inflate_hufts, sizeof(inflate_huft))); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + inflate_trees_free(td, z); + inflate_trees_free(tl, z); + r = Z_MEM_ERROR; + LEAVE + } + ZFREE(z, s->sub.trees.blens); + s->sub.decode.codes = c; + s->sub.decode.tl = tl; + s->sub.decode.td = td; + } + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + inflate_trees_free(s->sub.decode.td, z); + inflate_trees_free(s->sub.decode.tl, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +int inflate_blocks_free(s, z, c) +inflate_blocks_statef *s; +z_streamp z; +uLongf *c; +{ + inflate_blocks_reset(s, z, c); + ZFREE(z, s->window); + ZFREE(z, s); + Trace((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + + +void inflate_set_dictionary(s, d, n) +inflate_blocks_statef *s; +const Bytef *d; +uInt n; +{ + zmemcpy((charf *)s->window, d, n); + s->read = s->write = s->window + n; +} diff --git a/gnu/usr.bin/cvs/zlib/infblock.h b/gnu/usr.bin/cvs/zlib/infblock.h new file mode 100644 index 00000000000..3ecd50cd3a6 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/infblock.h @@ -0,0 +1,37 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Bytef *d, /* dictionary */ + uInt n)); /* dictionary length */ diff --git a/gnu/usr.bin/cvs/zlib/infcodes.c b/gnu/usr.bin/cvs/zlib/infcodes.c new file mode 100644 index 00000000000..3ae3818a194 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/infcodes.c @@ -0,0 +1,247 @@ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ + mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +z_streamp z; +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +int inflate_codes(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t->next; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t->next; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ +#ifndef __TURBOC__ /* Turbo C bug for following expression */ + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; +#else + f = q - c->sub.copy.dist; + if ((uInt)(q - s->window) < c->sub.copy.dist) + f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); +#endif + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +void inflate_codes_free(c, z) +inflate_codes_statef *c; +z_streamp z; +{ + ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +} diff --git a/gnu/usr.bin/cvs/zlib/infcodes.h b/gnu/usr.bin/cvs/zlib/infcodes.h new file mode 100644 index 00000000000..c2c38df2c06 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/infcodes.h @@ -0,0 +1,27 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + diff --git a/gnu/usr.bin/cvs/zlib/inffast.c b/gnu/usr.bin/cvs/zlib/inffast.c new file mode 100644 index 00000000000..86eee4a2992 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/inffast.c @@ -0,0 +1,168 @@ +/* inffast.c -- process literals and length/distance pairs fast + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} +#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +int inflate_fast(bl, bd, tl, td, s, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Bytef *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* offset before dest */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + } + else /* else offset after destination */ + { + e = d - (uInt)(q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +} diff --git a/gnu/usr.bin/cvs/zlib/inffast.h b/gnu/usr.bin/cvs/zlib/inffast.h new file mode 100644 index 00000000000..8cc644efb1f --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/inffast.h @@ -0,0 +1,17 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +extern int inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_streamp )); diff --git a/gnu/usr.bin/cvs/zlib/inflate.c b/gnu/usr.bin/cvs/zlib/inflate.c new file mode 100644 index 00000000000..74cc69c8684 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/inflate.c @@ -0,0 +1,345 @@ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" + +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ + +/* inflate private state */ +struct internal_state { + + /* mode */ + enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + DICT4, /* four dictionary check bytes to go */ + DICT3, /* three dictionary check bytes to go */ + DICT2, /* two dictionary check bytes to go */ + DICT1, /* one dictionary check byte to go */ + DICT0, /* waiting for inflateSetDictionary */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ + mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +int inflateReset(z) +z_streamp z; +{ + uLong c; + + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, &c); + Trace((stderr, "inflate: reset\n")); + return Z_OK; +} + + +int inflateEnd(z) +z_streamp z; +{ + uLong c; + + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z, &c); + ZFREE(z, z->state); + z->state = Z_NULL; + Trace((stderr, "inflate: end\n")); + return Z_OK; +} + + +int inflateInit2_(z, w, version, stream_size) +z_streamp z; +int w; +const char *version; +int stream_size; +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; + + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = zcalloc; + z->opaque = (voidpf)0; + } + if (z->zfree == Z_NULL) z->zfree = zcfree; + if ((z->state = (struct internal_state FAR *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Trace((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + +int inflateInit_(z, version, stream_size) +z_streamp z; +const char *version; +int stream_size; +{ + return inflateInit2_(z, DEF_WBITS, version, stream_size); +} + + +#define NEEDBYTE {if(z->avail_in==0)return r;r=Z_OK;} +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int inflate(z, f) +z_streamp z; +int f; +{ + int r; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0) + return Z_STREAM_ERROR; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = BAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + b = NEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Trace((stderr, "inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = BLOCKS; + break; + } + z->state->mode = DICT4; + case DICT4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = DICT3; + case DICT3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = DICT2; + case DICT2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = DICT1; + case DICT1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z->state->mode = BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r != Z_STREAM_END) + return r; + r = Z_OK; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Trace((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +} + + +int inflateSetDictionary(z, dictionary, dictLength) +z_streamp z; +const Bytef *dictionary; +uInt dictLength; +{ + uInt length = dictLength; + + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) + return Z_STREAM_ERROR; + + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; + z->adler = 1L; + + if (length >= ((uInt)1<<z->state->wbits)) + { + length = (1<<z->state->wbits)-1; + dictionary += dictLength - length; + } + inflate_set_dictionary(z->state->blocks, dictionary, length); + z->state->mode = BLOCKS; + return Z_OK; +} + + +int inflateSync(z) +z_streamp z; +{ + uInt n; /* number of bytes to look at */ + Bytef *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != BAD) + { + z->state->mode = BAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + if (*p == (Byte)(m < 2 ? 0 : 0xff)) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = BLOCKS; + return Z_OK; +} diff --git a/gnu/usr.bin/cvs/zlib/inftrees.c b/gnu/usr.bin/cvs/zlib/inftrees.c new file mode 100644 index 00000000000..90205bd1e57 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/inftrees.c @@ -0,0 +1,470 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ +struct internal_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + uIntf *, /* list of base values for non-simple codes */ + uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + z_streamp )); /* for zalloc function */ + +local voidpf falloc OF(( + voidpf, /* opaque pointer (not used) */ + uInt, /* number of items */ + uInt)); /* size of item */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* actually lengths - 2; also see note #13 above about 258 */ +local uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ +local uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local uInt cpdext[30] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ +#define N_MAX 288 /* maximum number of codes in any set */ + +#ifdef DEBUG + uInt inflate_hufts; +#endif + +local int huft_build(b, n, s, d, e, t, m, zs) +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ +uInt n; /* number of codes (assumed <= N_MAX) */ +uInt s; /* number of simple-valued codes (0..s-1) */ +uIntf *d; /* list of base values for non-simple codes */ +uIntf *e; /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t; /* result: starting table */ +uIntf *m; /* maximum lookup bits, returns actual */ +z_streamp zs; /* for zalloc function */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), Z_DATA_ERROR if the input is invalid (all zero length codes or an + over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + uInt v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate and link in new table */ + if ((q = (inflate_huft *)ZALLOC + (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) + { + if (h) + inflate_trees_free(u[0], zs); + return Z_MEM_ERROR; /* not enough memory */ + } +#ifdef DEBUG + inflate_hufts += z + 1; +#endif + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->next)) = Z_NULL; + u[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + r.next = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h-1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int inflate_trees_bits(c, bb, tb, z) +uIntf *c; /* 19 code lengths */ +uIntf *bb; /* bits tree desired/actual depth */ +inflate_huft * FAR *tb; /* bits tree result */ +z_streamp z; /* for zfree function */ +{ + int r; + + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR) + { + inflate_trees_free(*tb, z); + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + return r; +} + + +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) +uInt nl; /* number of literal/length codes */ +uInt nd; /* number of distance codes */ +uIntf *c; /* that many (total) code lengths */ +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +z_streamp z; /* for zfree function */ +{ + int r; + + /* build literal/length tree */ + if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r == Z_BUF_ERROR) + { + inflate_trees_free(*tl, z); + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + return r; + } + + /* build distance tree */ + if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + inflate_trees_free(*td, z); + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + inflate_trees_free(*tl, z); + return r; +#endif + } + + /* done */ + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +local int fixed_built = 0; +#define FIXEDH 530 /* number of hufts used by fixed tables */ +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; + + +local voidpf falloc(q, n, s) +voidpf q; /* opaque pointer */ +uInt n; /* number of items */ +uInt s; /* size of item */ +{ + Assert(s == sizeof(inflate_huft) && n <= *(intf *)q, + "inflate_trees falloc overflow"); + *(intf *)q -= n+s-s; /* s-s to avoid warning */ + return (voidpf)(fixed_mem + *(intf *)q); +} + + +int inflate_trees_fixed(bl, bd, tl, td) +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +{ + /* build fixed tables if not already (multiple overlapped executions ok) */ + if (!fixed_built) + { + int k; /* temporary variable */ + unsigned c[288]; /* length list for huft_build */ + z_stream z; /* for falloc function */ + int f = FIXEDH; /* number of hufts left in fixed_mem */ + + /* set up fake z_stream for memory routines */ + z.zalloc = falloc; + z.zfree = Z_NULL; + z.opaque = (voidpf)&f; + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 7; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); + + /* done */ + Assert(f == 0, "invalid build of fixed tables"); + fixed_built = 1; + } + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} + + +int inflate_trees_free(t, z) +inflate_huft *t; /* table to free */ +z_streamp z; /* for zfree function */ +/* Free the malloc'ed tables built by huft_build(), which makes a linked + list of the tables it made, with the links in a dummy first entry of + each table. */ +{ + register inflate_huft *p, *q, *r; + + /* Reverse linked list */ + p = Z_NULL; + q = t; + while (q != Z_NULL) + { + r = (q - 1)->next; + (q - 1)->next = p; + p = q; + q = r; + } + /* Go through linked list, freeing from the malloced (t[-1]) address. */ + while (p != Z_NULL) + { + q = (--p)->next; + ZFREE(z,p); + p = q; + } + return Z_OK; +} diff --git a/gnu/usr.bin/cvs/zlib/inftrees.h b/gnu/usr.bin/cvs/zlib/inftrees.h new file mode 100644 index 00000000000..b06613ddd3f --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/inftrees.h @@ -0,0 +1,59 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit machines) */ + union { + uInt Base; /* literal, length base, or distance base */ + inflate_huft *Next; /* pointer to next level of table */ + } more; +}; + +#ifdef DEBUG + extern uInt inflate_hufts; +#endif + +extern int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + z_streamp )); /* for zalloc, zfree functions */ + +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_streamp )); /* for zalloc, zfree functions */ + +extern int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *)); /* distance tree result */ + +extern int inflate_trees_free OF(( + inflate_huft *, /* tables to free */ + z_streamp )); /* for zfree function */ + diff --git a/gnu/usr.bin/cvs/zlib/infutil.c b/gnu/usr.bin/cvs/zlib/infutil.c new file mode 100644 index 00000000000..eb21199c350 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/infutil.c @@ -0,0 +1,87 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +int inflate_flush(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt n; + Bytef *p; + Bytef *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} diff --git a/gnu/usr.bin/cvs/zlib/infutil.h b/gnu/usr.bin/cvs/zlib/infutil.h new file mode 100644 index 00000000000..702cd290c37 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/infutil.h @@ -0,0 +1,99 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_huft *tl; + inflate_huft *td; /* trees to free */ + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} +#define DUMPBITS(j) {b>>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +extern uInt inflate_mask[17]; + +/* copy as much as possible from the sliding window to the output area */ +extern int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#endif diff --git a/gnu/usr.bin/cvs/zlib/minigzip.c b/gnu/usr.bin/cvs/zlib/minigzip.c new file mode 100644 index 00000000000..5770ea7cff6 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/minigzip.c @@ -0,0 +1,246 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. On MSDOS, use only on file names without extension + * or in pipe mode. + */ + +/* $Id: minigzip.c,v 1.1.1.1 1996/10/18 03:35:05 tholo Exp $ */ + +#include <stdio.h> +#include "zlib.h" + +#ifdef STDC +# include <string.h> +# include <stdlib.h> +#else + extern void exit OF((int)); +#endif + + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) +# include <fcntl.h> +# include <io.h> +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#ifdef VMS +# define unlink delete +# define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +# define unlink remove +# define GZ_SUFFIX "-gz" +# define fileno(file) file->__file +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN sizeof(GZ_SUFFIX) + +extern int unlink OF((const char *)); + +#define BUFLEN 4096 +#define MAX_NAME_LEN 1024 + +#define local static +/* For MSDOS and other systems with limitation on stack size. For Unix, + #define local + works also. + */ + +char *prog; + +void error OF((const char *msg)); +void gz_compress OF((FILE *in, gzFile out)); +void gz_uncompress OF((gzFile in, FILE *out)); +void file_compress OF((char *file)); +void file_uncompress OF((char *file)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file) + char *file; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + strcpy(outfile, file); + strcat(outfile, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, "wb"); /* use "wb9" for maximal compression */ + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + int len = strlen(file); + + strcpy(buf, file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + strcat(infile, GZ_SUFFIX); + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-d] [files...] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + int uncompr = 0; + gzFile file; + + prog = argv[0]; + argc--, argv++; + + if (argc > 0) { + uncompr = (strcmp(*argv, "-d") == 0); + if (uncompr) { + argc--, argv++; + } + } + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), "wb"); /* "wb9" for max compr. */ + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + do { + if (uncompr) { + file_uncompress(*argv); + } else { + file_compress(*argv); + } + } while (argv++, --argc); + } + exit(0); + return 0; /* to avoid warning */ +} diff --git a/gnu/usr.bin/cvs/zlib/trees.c b/gnu/usr.bin/cvs/zlib/trees.c new file mode 100644 index 00000000000..76cc62c8e38 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/trees.c @@ -0,0 +1,1141 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-1996 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* $Id: trees.c,v 1.1.1.1 1996/10/18 03:35:05 tholo Exp $ */ + +#include "deflate.h" + +#ifdef DEBUG +# include <ctype.h> +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +local uch dist_code[512]; +/* distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +local uch length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +struct static_tree_desc_s { + ct_data *static_tree; /* static tree or NULL */ + intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +#define d_code(dist) \ + ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. dist_code[256] and dist_code[257] are never + * used. + */ + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +#define MAX(a,b) (a >= b ? a : b) +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. In a multi-threaded environment, + * this function may be called by two threads concurrently, but this is + * harmless since both invocations do exactly the same thing. + */ +local void tr_static_init() +{ + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1<<extra_lbits[code]); n++) { + length_code[length++] = (uch)code; + } + } + Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + length_code[length-1] = (uch)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<<extra_dbits[code]); n++) { + dist_code[dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; +} + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->compressed_len = 0L; + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + ct_data *stree = desc->stat_desc->static_tree; + intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if (tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = bi_reverse(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); + } +} + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +local void build_tree(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; + + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); + s->compressed_len += 10L; + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. This function + * returns the total compressed length for the file so far. + */ +ulg _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is ascii or binary */ + if (s->data_type == Z_UNKNOWN) set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute first the block length in bytes*/ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + /* If compression failed and this is the first and last block, + * and if the .zip file can be seeked (to rewrite the local header), + * the whole file is transformed into a stored file: + */ +#ifdef STORED_FILE_OK +# ifdef FORCE_STORED_FILE + if (eof && s->compressed_len == 0L) { /* force stored file */ +# else + if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { +# endif + /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ + if (buf == (charf*)0) error ("block vanished"); + + copy_block(buf, (unsigned)stored_len, 0); /* without header */ + s->compressed_len = stored_len << 3; + s->method = STORED; + } else +#endif /* STORED_FILE_OK */ + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); + s->compressed_len += 3 + s->static_len; + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); + s->compressed_len += 3 + s->opt_len; + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + init_block(s); + + if (eof) { + bi_windup(s); + s->compressed_len += 7; /* align on byte boundary */ + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); + + return s->compressed_len >> 3; +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + + /* Try to guess if it is profitable to stop the current block here */ + if (s->level > 2 && (s->last_lit & 0xfff) == 0) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to ASCII or BINARY, using a crude approximation: + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + * IN assertion: the fields freq of dyn_ltree are set and the total of all + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). + */ +local void set_data_type(s) + deflate_state *s; +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/gnu/usr.bin/cvs/zlib/uncompr.c b/gnu/usr.bin/cvs/zlib/uncompr.c new file mode 100644 index 00000000000..4c9dcebb090 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/uncompr.c @@ -0,0 +1,58 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: uncompr.c,v 1.1.1.1 1996/10/18 03:35:06 tholo Exp $ */ + +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/gnu/usr.bin/cvs/zlib/zconf.h b/gnu/usr.bin/cvs/zlib/zconf.h new file mode 100644 index 00000000000..c4be0e8ad1a --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/zconf.h @@ -0,0 +1,184 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: zconf.h,v 1.1.1.1 1996/10/18 03:35:06 tholo Exp $ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateReset z_inflateReset +# define compress z_compress +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC) +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + 1 << (windowBits+2) + 1 << (memLevel+9) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR __far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR __far +# endif +#endif +#ifndef FAR +# define FAR +#endif + +typedef unsigned char Byte; /* 8 bits */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#if defined(__BORLANDC__) && defined(SMALL_MEDIUM) + /* Borland C/C++ ignores FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL) +# include <windows.h> +# define EXPORT WINAPI +#else +# define EXPORT +#endif + +#endif /* _ZCONF_H */ diff --git a/gnu/usr.bin/cvs/zlib/zlib.def b/gnu/usr.bin/cvs/zlib/zlib.def new file mode 100644 index 00000000000..08c6d5501a4 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/zlib.def @@ -0,0 +1,46 @@ +LIBRARY "zlib" + +DESCRIPTION '"""zlib data compression library"""' + +EXETYPE NT + +SUBSYSTEM WINDOWS + +STUB 'WINSTUB.EXE' + +VERSION 1.04 + +CODE EXECUTE READ + +DATA READ WRITE + +HEAPSIZE 1048576,4096 + +EXPORTS + zlibVersion + deflate + deflateEnd + inflate + inflateEnd + deflateSetDictionary + deflateCopy + deflateReset + deflateParams + inflateSetDictionary + inflateSync + inflateReset + compress + uncompress + gzopen + gzdopen + gzread + gzwrite + gzflush + gzclose + gzerror + adler32 + crc32 + deflateInit_ + inflateInit_ + deflateInit2_ + inflateInit2_ diff --git a/gnu/usr.bin/cvs/zlib/zlib.h b/gnu/usr.bin/cvs/zlib/zlib.h new file mode 100644 index 00000000000..337fe9fe8a3 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/zlib.h @@ -0,0 +1,780 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.0.4, Jul 24th, 1996. + + Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + gzip@prep.ai.mit.edu madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "zconf.h" + +#define ZLIB_VERSION "1.0.4" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms may be added later and will have the same + stream interface. + + For compression the application must provide the output buffer and + may optionally provide the input buffer for optimization. For decompression, + the application must provide the input buffer and may optionally provide + the output buffer for optimization. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library does not install any signal handler. It is recommended to + add at least a handler for SIGSEGV when decompressing; the library checks + the consistency of the input data whenever possible but may go nuts + for some forms of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +extern const char * EXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +extern int EXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +extern int EXPORT deflate OF((z_streamp strm, int flush)); +/* + Performs one or both of the following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression + block is terminated and flushed to the output buffer so that the + decompressor can get all input data available so far. For method 9, a future + variant on method 8, the current block will be flushed but not terminated. + Z_SYNC_FLUSH has the same effect as partial flush except that the compressed + output is byte aligned (the compressor can clear its internal bit buffer) + and the current block is always terminated; this can be useful if the + compressor has to be restarted from scratch after an interruption (in which + case the internal state of the compressor may be lost). + If flush is set to Z_FULL_FLUSH, the compression block is terminated, a + special marker is output and the compression dictionary is discarded; this + is useful to allow the decompressor to synchronize if one compressed block + has been damaged (see inflateSync below). Flushing degrades compression and + so should be used only when necessary. Using Z_FULL_FLUSH too often can + seriously degrade the compression. If deflate returns with avail_out == 0, + this function must be called again with the same value of the flush + parameter and more output space (updated avail_out), until the flush is + complete (deflate returns with non-zero avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible. +*/ + + +extern int EXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +extern int EXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, inflateInit updates them to use default + allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_VERSION_ERROR if the zlib library version is incompatible + with the version assumed by the caller. msg is set to null if there is no + error message. inflateInit does not perform any decompression: this will be + done by inflate(). +*/ + + +extern int EXPORT inflate OF((z_streamp strm, int flush)); +/* + Performs one or both of the following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_PARTIAL_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_PARTIAL_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + inflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if the end of the + compressed data has been reached and all uncompressed output has been + produced, Z_NEED_DICT if a preset dictionary is needed at this point (see + inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted, + Z_STREAM_ERROR if the stream structure was inconsistent (for example if + next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in + the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the + application may then call inflateSync to look for a good compression block. + In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the + dictionary chosen by the compressor. +*/ + + +extern int EXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +extern int EXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. (Method 9 will allow a 64K history buffer and + partial block flushes.) + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library (the value 16 will be allowed for method 9). Larger + values of this parameter result in better compression at the expense of + memory usage. The default value is 15 if deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + If next_in is not null, the library will use this buffer to hold also + some history information; the buffer must either hold the entire input + data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in + is null, the library will allocate its own history buffer (and leave next_in + null). next_out need not be provided here but must be provided by the + application for the next call of deflate(). + + If the history buffer is provided by the application, next_in must + must never be changed by the application since the compressor maintains + information inside this buffer from call to call; the application + must provide more input only by increasing avail_in. next_in is always + reset by the library in this case. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was + not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as + an invalid method). msg is set to null if there is no error message. + deflateInit2 does not perform any compression: this will be done by + deflate(). +*/ + +extern int EXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary (history buffer) from the given + byte sequence without producing any compressed output. This function must + be called immediately after deflateInit or deflateInit2, before any call + of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and + can be predicted with good accuracy; the data can then be compressed better + than with the default empty dictionary. In this version of the library, + only the last 32K bytes of the dictionary are used. + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state + is inconsistent (for example if deflate has already been called for this + stream). deflateSetDictionary does not perform any compression: this will + be done by deflate(). +*/ + +extern int EXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. If + the source stream is using an application-supplied history buffer, a new + buffer is allocated for the destination stream. The compressed output + buffer is always application-supplied. It's the responsibility of the + application to provide the correct values of next_out and avail_out for the + next call of deflate. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +extern int EXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy)); +/* + Dynamically update the compression level and compression strategy. + This can be used to switch between compression and straight copy of + the input data, or to switch to a different kind of input data requiring + a different strategy. If the compression level is changed, the input + available so far is compressed with the old level (and may be flushed); + the new level will take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +extern int EXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with more compression options. The + fields next_out, zalloc, zfree and opaque must be initialized before by + the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library (the value 16 will be allowed soon). The + default value is 15 if inflateInit is used instead. If a compressed stream + with a larger window size is given as input, inflate() will return with + the error code Z_DATA_ERROR instead of trying to allocate a larger window. + + If next_out is not null, the library will use this buffer for the history + buffer; the buffer must either be large enough to hold the entire output + data, or have at least 1<<windowBits bytes. If next_out is null, the + library will allocate its own buffer (and leave next_out null). next_in + need not be provided here but must be provided by the application for the + next call of inflate(). + + If the history buffer is provided by the application, next_out must + never be changed by the application since the decompressor maintains + history information inside this buffer from call to call; the application + can only reset next_out to the beginning of the history buffer when + avail_out is zero and all output has been consumed. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was + not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as + windowBits < 8). msg is set to null if there is no error message. + inflateInit2 does not perform any decompression: this will be done by + inflate(). +*/ + +extern int EXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary (history buffer) from the given + uncompressed byte sequence. This function must be called immediately after + a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen + by the compressor can be determined from the Adler32 value returned by this + call of inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +extern int EXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until the special marker (see deflate() + above) can be found, or until all available input is skipped. No output + is provided. + + inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no marker has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +extern int EXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level, window size, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +extern int EXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +extern int EXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +extern gzFile EXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9"). gzopen can be used to read a file which is not in gzip format; + in this case gzread will directly read from the file without decompression. + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ + +extern gzFile EXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +extern int EXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +extern int EXPORT gzwrite OF((gzFile file, const voidp buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +extern int EXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +extern int EXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +extern const char * EXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +extern uLong EXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +extern int EXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +extern int EXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +extern int EXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, int strategy, + const char *version, int stream_size)); +extern int EXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ZLIB_H */ diff --git a/gnu/usr.bin/cvs/zlib/zlib.rc b/gnu/usr.bin/cvs/zlib/zlib.rc new file mode 100644 index 00000000000..2c0a3e4defc --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/zlib.rc @@ -0,0 +1,32 @@ +#include <windows.h> + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1,0,4,0 + PRODUCTVERSION 1,0,4,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", "1.0.4\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlib.lib\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments", "DLL support by Alessandro Iacopetti\0" + VALUE "LegalCopyright", "(C) 1995-1996 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/gnu/usr.bin/cvs/zlib/zutil.c b/gnu/usr.bin/cvs/zlib/zutil.c new file mode 100644 index 00000000000..40a74162235 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/zutil.c @@ -0,0 +1,211 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: zutil.c,v 1.1.1.1 1996/10/18 03:35:06 tholo Exp $ */ + +#include <stdio.h> + +#include "zutil.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#ifndef STDC +extern void exit OF((int)); +#endif + +const char *z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char *zlibVersion() +{ + return ZLIB_VERSION; +} + +#ifdef DEBUG +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + Bytef* s1; + Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifdef __TURBOC__ +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) +/* Small and medium model in Turbo C are for now limited to near allocation + * with reduced MAX_WBITS and MAX_MEM_LEVEL + */ +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} +#endif +#endif /* __TURBOC__ */ + + +#if defined(M_I86) && !defined(__32BIT__) +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER < 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* MSC */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/gnu/usr.bin/cvs/zlib/zutil.h b/gnu/usr.bin/cvs/zlib/zutil.h new file mode 100644 index 00000000000..c0be7445d09 --- /dev/null +++ b/gnu/usr.bin/cvs/zlib/zutil.h @@ -0,0 +1,203 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* $Id: zutil.h,v 1.1.1.1 1996/10/18 03:35:06 tholo Exp $ */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include "zlib.h" + +#if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS) +# include <stddef.h> +# include <errno.h> +#else + extern int errno; +#endif +#ifdef STDC +# include <string.h> +# include <stdlib.h> +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# ifdef __TURBOC__ +# include <alloc.h> +# else /* MSC or DJGPP */ +# include <malloc.h> +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Window 95 & Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define FOPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef MACOS +# define OS_CODE 0x07 +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef FOPEN +# define FOPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, Bytef* source, uInt len)); + extern int zmemcmp OF((Bytef* s1, Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include <stdio.h> +# ifndef verbose +# define verbose 0 +# endif + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len)); + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */ |