diff options
Diffstat (limited to 'patches')
-rw-r--r-- | patches/cvs-1.12.13.local.patch | 29 | ||||
-rw-r--r-- | patches/cvs-1.12.13_pre.local.patch | 16014 |
2 files changed, 16043 insertions, 0 deletions
diff --git a/patches/cvs-1.12.13.local.patch b/patches/cvs-1.12.13.local.patch new file mode 100644 index 00000000..5d024d6e --- /dev/null +++ b/patches/cvs-1.12.13.local.patch @@ -0,0 +1,29 @@ +diff -ru cvs-1.12.13.orig/src/main.c cvs-1.12.13/src/main.c +--- cvs-1.12.13.orig/src/main.c 2022-10-20 15:44:42.306215161 +0200 ++++ cvs-1.12.13/src/main.c 2022-10-20 15:50:55.838352069 +0200 +@@ -24,10 +24,6 @@ + #include "strftime.h" + #include "xgethostname.h" + +-#ifdef USE_LIBBSD +-uint32_t arc4random(void); +-#endif +- + const char *program_name; + const char *program_path; + const char *cvs_cmd_name; +@@ -749,10 +745,13 @@ + + /* Calculate the cvs global session ID */ + ++ int random; ++ getentropy(&random, sizeof(int)); ++ + global_session_id = Xasprintf("1%010llX%04X%04X", + (unsigned long long)time(NULL), + (unsigned int)(getpid() & 0xFFFF), +- (unsigned int)(arc4random() & 0xFFFF)); ++ (unsigned int)random & 0xFFFF); + + TRACE (TRACE_FUNCTION, "main: Session ID is %s", global_session_id); + diff --git a/patches/cvs-1.12.13_pre.local.patch b/patches/cvs-1.12.13_pre.local.patch new file mode 100644 index 00000000..b5954e0c --- /dev/null +++ b/patches/cvs-1.12.13_pre.local.patch @@ -0,0 +1,16014 @@ +diff -ru cvs-1.12.13.orig/src/Makefile.in cvs-1.12.13/src/Makefile.in +--- cvs-1.12.13.orig/src/Makefile.in 2005-10-03 15:37:18.000000000 +0200 ++++ cvs-1.12.13/src/Makefile.in 2022-10-20 16:25:44.014173101 +0200 +@@ -150,7 +150,7 @@ + release.$(OBJEXT) remove.$(OBJEXT) repos.$(OBJEXT) \ + root.$(OBJEXT) rsh-client.$(OBJEXT) run.$(OBJEXT) \ + scramble.$(OBJEXT) server.$(OBJEXT) stack.$(OBJEXT) \ +- status.$(OBJEXT) subr.$(OBJEXT) tag.$(OBJEXT) update.$(OBJEXT) \ ++ status.$(OBJEXT) subr.$(OBJEXT) suck.$(OBJEXT) tag.$(OBJEXT) update.$(OBJEXT) \ + version.$(OBJEXT) vers_ts.$(OBJEXT) watch.$(OBJEXT) \ + wrapper.$(OBJEXT) zlib.$(OBJEXT) + cvs_OBJECTS = $(am_cvs_OBJECTS) +@@ -304,8 +304,6 @@ + AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_builddir)/lib \ + -I$(top_srcdir)/diff $(ZLIB_CPPFLAGS) + +-bin_SCRIPTS = cvsbug +- + # The cvs executable + cvs_SOURCES = \ + add.c \ +@@ -361,6 +359,7 @@ + stack.c stack.h \ + status.c \ + subr.c subr.h \ ++ suck.c \ + tag.c \ + update.c \ + version.c \ +--- cvs-1.12.13+real.orig/AUTHORS ++++ cvs-1.12.13+real/AUTHORS +@@ -57,6 +57,12 @@ + There have been many, many contributions not listed here. Consult the + individual ChangeLog files in each directory for a more complete idea. + ++The de-facto (if not… yet… de-iure) new upstream of GNU CVS 1.12.x is ++MirBSD, which also provides the Debian packages incorporating original ++development work and fixes by mirabilos <m@mirbsd.org> and some inspired ++by changes to GNU CVS 1.11.1p1 from other BSDs and by changes from the ++previous Debian package. ++ + In addition to the above contributors, the following Beta testers + deserve special mention for their support. This is only a partial + list; if you have helped in this way and would like to be listed, let +@@ -88,3 +94,6 @@ + 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 tools/pcl-cvs. ++ ++ ++$MirOS: src/gnu/usr.bin/cvs/AUTHORS,v 1.7 2021/01/30 02:05:54 tg Exp $ +--- cvs-1.12.13+real.orig/DEVEL-CVS ++++ cvs-1.12.13+real/DEVEL-CVS +@@ -7,7 +7,8 @@ + Policies regarding the CVS source repository: + + By checking items into the repository, developers agree to permit +-distribution of such items under the terms of the GNU Public License. ++distribution of such items under the terms of the GNU General Public ++License. + + ---------------------------------------------------------------------- + Procedure for dealing with people who want to be developers: +--- cvs-1.12.13+real.orig/FAQ ++++ cvs-1.12.13+real/FAQ +@@ -3097,7 +3097,7 @@ + If you want to allow read access, check out an entire tree somewhere. + You have to do this anyway to build it. + +- Note: If you are using a stupid file system that can't inherit file ++ Note: If you are using a stupid filesystem that can't inherit file + groups from the parent directory (even with the "setgid" (Octal 2000) + bit set), you might have to modify CVS (or RCS) to reset the group + every time you create a new file. I have not tested this. +@@ -7234,7 +7234,7 @@ + + It will respond: + +- Directory /Repos/<dir> added to the repository ++ Directory /Repos/<dir> put under version control + + and will create both a matching directory in the Repository and a + ./CVS administrative directory within the local <dir> directory. +@@ -7541,7 +7541,7 @@ + available on Sun, HP, SGI and OSF/1 platforms. + + ClearCase uses a special Unix filesystem type, called "mvfs" for +- "multi-version file system". Conceptually, mvfs adds another dimension ++ "multi-version filesystem". Conceptually, mvfs adds another dimension + to a regular Unix filesystem. The new axis is used to store the + different versions of files and to provide a tree-hierarchical view of + a collection of objects that might be scattered across any number of +@@ -7644,7 +7644,7 @@ + + Shapetools includes a build mechanism (called Shape, not surprisingly) + that is aware of the version mechanism, and some dependency tracking. +- It is based on a file system extension called Attributed File System, ++ It is based on a filesystem extension called Attributed Filesystem, + which allows arbitrary-sized "attributes" to be associated with a + file. Files are version controlled in a manner similar to RCS. + Configurations are managed through the Shapefile, an extension of the +--- cvs-1.12.13+real.orig/MINOR-BUGS ++++ cvs-1.12.13+real/MINOR-BUGS +@@ -59,3 +59,15 @@ + belong under the "checkout" function? Perhaps it is more logically + grouped with the "history" function or we should create a new "info" + function? ++ ++ ++Note that it is the opinion of the MirBSD founder that the CVSROOT ++environment variable ought to *never* be set at all. This prevents ++a lot of trouble. Almost all CVS tutorials stating otherwise (or ++recommending pserver) are perceived bogus. ++ ++"cvs annotate -b" does not do what people would expect, I think, ++but neither does it do that under MidnightBSD/DragonFly, where ++it came from. ++ ++$MirOS: src/gnu/usr.bin/cvs/MINOR-BUGS,v 1.5 2016/11/08 23:04:31 tg Exp $ +--- cvs-1.12.13+real.orig/NEWS ++++ cvs-1.12.13+real/NEWS +@@ -1,3 +1,11 @@ ++Changes since 1.12.13: ++********************** ++ ++* many which are only documented in MirBSD CVS ++ ++* A new command line option, --allow-root-regexp, was added which allows ++ acceptable repositories to be specified using a list of regular expressions. ++ + Changes since 1.12.12: + ********************** + +@@ -669,7 +677,7 @@ + from the server. + + * The configure script now tests whether it is building CVS on a case +- insensitive file system. If it is, CVS assumes that all file systems on this ++ insensitive filesystem. If it is, CVS assumes that all filesystems on this + platform will be case insensitive. This is useful for getting the case + insensitivity flag set correctly when compiling on Mac OS X and under Cygwin + on Windows. Autodetection can be overridden using the +--- cvs-1.12.13+real.orig/TODO ++++ cvs-1.12.13+real/TODO +@@ -33,14 +33,14 @@ + 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. + +-72. Consider re-design of the module -t options to use the file system more ++72. Consider re-design of the module -t options to use the filesystem more + intuitively. + + 73. Consider an option (in .cvsrc?) to automatically add files that are new + and specified to commit. + + 79. Might be nice to have some sort of interface to Sun's Translucent +- (?) File System and tagged revisions. ++ (?) filesystem and tagged revisions. + + 82. Maybe the import stuff should allow an arbitrary revision to be + specified. +@@ -215,7 +215,7 @@ + machine or directory. But there are other cases, like where the + user might want to change from :pserver: to :ext:, use a different + server (if there are two server machines which share the +- repository using a networked file system), etc. ++ repository using a networked filesystem), etc. + + The status quo is a bit of a mess (as of, say, CVS 1.9). It is + that the -d global option has two moderately different uses. One +@@ -334,7 +334,7 @@ + + 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. ++ filesystems. Perhaps import should be a bit more cautious. + + 166. There really needs to be a "Getting Started" document which describes + some of the new CVS philosophies. Folks coming straight from SCCS or +--- cvs-1.12.13+real.orig/contrib/README ++++ cvs-1.12.13+real/contrib/README +@@ -74,6 +74,7 @@ + if it does not already. + Copied from the C-News distribution. + ++ /usr/share/doc/cvs/intro.txt in Debian: + intro.doc A user's view of what you need to know to get + started with CVS. + Contributed by <Steven.Pemberton@cwi.nl>. +--- cvs-1.12.13+real.orig/contrib/cvs_acls.html ++++ cvs-1.12.13+real/contrib/cvs_acls.html +@@ -280,7 +280,7 @@ + <p>A final note about the repository matching pattern. The example above + uses ``ALL'' but note that this means that the cvs_acls script will run + for each and every commit in your repository. Obviously, in a large +-repository this adds up to a lot of overhead that may not be necesary. ++repository this adds up to a lot of overhead that may not be necessary. + A better strategy is to use a repository pattern that is more specific + to the areas that you wish to secure.</p> + <p>3. Install this file as $CVSROOT/CVSROOT/cvs_acls and make it executable.</p> +--- cvs-1.12.13+real.orig/contrib/cvs_acls.in ++++ cvs-1.12.13+real/contrib/cvs_acls.in +@@ -309,7 +309,7 @@ + A final note about the repository matching pattern. The example above + uses "ALL" but note that this means that the cvs_acls script will run + for each and every commit in your repository. Obviously, in a large +-repository this adds up to a lot of overhead that may not be necesary. ++repository this adds up to a lot of overhead that may not be necessary. + A better strategy is to use a repository pattern that is more specific + to the areas that you wish to secure. + +--- cvs-1.12.13+real.orig/contrib/rcs2log.1 ++++ cvs-1.12.13+real/contrib/rcs2log.1 +@@ -1,3 +1,4 @@ ++.\" $MirOS: src/gnu/usr.bin/cvs/contrib/rcs2log.1,v 1.2 2011/05/06 22:44:59 tg Exp $ + .\" + .\" Copyright 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + .\" +@@ -25,17 +26,17 @@ + .Sh SYNOPSIS + .Nm rcs2log + .Bk -words ++.Op Fl nRv + .Op Fl c Ar changelog + .Op Fl h Ar hostname + .Op Fl i Ar indent + .Op Fl l Ar length +-.Op Fl R ++.Op Fl L Ar file + .Op Fl r Ar option + .Op Fl t Ar tabwidth + .Op Fl u Ar login<TAB>fullname<TAB>mailaddr +-.Op Fl v +-.Op Fl -help +-.Op Fl -version ++.Op Fl \-help ++.Op Fl \-version + .Op Ar file ... + .Ek + .Sh DESCRIPTION +@@ -62,6 +63,14 @@ + Try to limit log lines to + .Ar length + characters (default 79). ++.It Fl L Ar file ++Use rlog-format ++.Ar file ++for source of logs. ++.It Fl n ++Obsolete, use ++.Fl u ++instead (whose syntax differs). + .It Fl R + If no + .Ar file Ns Li (s) +@@ -83,9 +92,9 @@ + .Ar mailaddr . + .It Fl v + Append RCS revision to file names in log lines. +-.It Fl -help ++.It Fl \-help + Output help. +-.It Fl -version ++.It Fl \-version + Output version number. + .El + .Sh SEE ALSO +--- cvs-1.12.13+real.orig/contrib/rcs2log.sh ++++ cvs-1.12.13+real/contrib/rcs2log.sh +@@ -1,4 +1,5 @@ + #! /bin/sh ++# $MirOS: src/gnu/usr.bin/cvs/contrib/rcs2log.sh,v 1.6 2011/05/06 22:44:59 tg Exp $ + + # Copyright (C) 1995-2005 The Free Software Foundation, Inc. + +@@ -31,6 +32,7 @@ + -i INDENT Indent change log lines by INDENT spaces (default 8). + -l LENGTH Try to limit log lines to LENGTH characters (default 79). + -L FILE Use rlog-format FILE for source of logs. ++ -n Obsolete, use -u instead (whose syntax differs). + -R If no FILEs are given and RCS is used, recurse through working directory. + -r OPTION Pass OPTION to subsidiary log command. + -t TABWIDTH Tab stops are every TABWIDTH characters (default 8). +@@ -199,7 +201,7 @@ + m[9]="Oct"; m[10]="Nov"; m[11]="Dec" + ' + +-logdir=`$MKTEMP -d $TMPDIR/rcs2log.XXXXXX` ++logdir=$($MKTEMP -d $TMPDIR/rcs2log.XXXXXXXXXX) + test -n "$logdir" || exit + llogout=$logdir/l + trap exit 1 2 13 15 +@@ -632,7 +634,7 @@ + # Sort the log entries, first by date+time (in reverse order), + # then by author, then by log entry, and finally by file name and revision + # (just in case). +-sort -t"$SOH" +2 -4r +4 +0 | ++sort -t"$SOH" -k 3,4r -k 5 -k 1 | + + # Finally, reformat the sorted log entries. + $AWK -F"$SOH" ' +--- cvs-1.12.13+real.orig/contrib/sccs2rcs.in ++++ cvs-1.12.13+real/contrib/sccs2rcs.in +@@ -1,4 +1,5 @@ + #! @CSH@ -f ++# $MirOS: src/gnu/usr.bin/cvs/contrib/sccs2rcs.in,v 1.2 2011/05/06 21:50:27 tg Exp $ + + # Copyright (C) 1995-2005 The Free Software Foundation, Inc. + +@@ -219,7 +220,7 @@ + # we expected in the output we have other problems. + # Note: Solaris awk does not like the following line. Use gawk + # mawk, or nawk instead. +- set date = `sccs prs -r$rev $file | @AWK@ '/^D / {print (substr($3,0,2)+0<70?20:19) $3, $4; exit}'` ++ set date = `sccs prs -r$rev $file | @AWK@ '/^D / {print (substr($3,1,2)+0<70?20:19) $3, $4; exit}'` + set author = `sccs prs -r$rev $file | @AWK@ '/^D / {print $5; exit}'` + echo "" + echo "==> file $file, rev=$rev, date=$date, author=$author" +--- cvs-1.12.13+real.orig/debian/NEWS ++++ cvs-1.12.13+real/debian/NEWS +@@ -0,0 +1,88 @@ ++cvs (2:1.12.13+real-23) unstable; urgency=low ++ ++ Starting from this version, environment variables that are ++ defined but empty are handled the same as undefined ones, ++ except CVSREAD and CVSREADONLYFS (whose mere presence in ++ the environment enables the functionality). ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Fri, 28 Apr 2017 19:10:30 +0200 ++ ++cvs (2:1.12.13+real-22) unstable; urgency=low ++ ++ Newly created repositories (from “cvs init”) now rely on ++ CVSUMASK for the permissions of the “history” and “val-tags” ++ files instead of creating them as world-writable. ++ ++ Newly created repositories contain a LogHistory configuration ++ setting to only record write operations in the “history” file. ++ ++ If you are used to the previous behaviour, you can restore it ++ by altering (or removing, in which case the (commented-out) ++ default of logging everything will be used) the LogHistory ++ configuration setting and changing the permissions on the ++ “history” and “val-tags” files so that every user can write ++ into them. ++ ++ If you did not deliberately open your repository to all users ++ on your system, you might wish to change all existing repos ++ to this behaviour. To do this, check out the CVSROOT module, ++ edit the “config” file adding “LogHistory=TMAR”, check that ++ change in, release the CVSROOT module, and chmod the “history” ++ and “val-tags” files to either 0664 (if all users in the same ++ group should be able to commit) or 0644 (if only you wish to ++ commit), possibly 0660 or 0600 is non-committers should also ++ be denied reading. ++ ++ Contact me (mirabilos) in #cvs on irc.freenode.net if you have ++ any questions about this change or require further support. ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Tue, 28 Mar 2017 19:54:01 +0200 ++ ++cvs (2:1.12.13+real-7) unstable; urgency=high ++ ++ rcs2log no longer lives in the PATH, the contributed script ++ and its manpage are in /usr/share/cvs/contrib/rcs2log now. ++ ++ Some contrib files (and their documentation) are no longer ++ shipped with the binary package (antique, insecure, useless). ++ ++ -rHEAD in "cvs diff" now, consistently with all other cvs ++ subcommands, means "tip of the trunk (MAIN branch)"; to ++ access the tip of the another branch, use its name; as a ++ compatibility aid, -r.bhead (only in diff) points to the ++ tip of the sticky branch. ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sun, 04 Dec 2011 20:10:09 +0000 ++ ++cvs (2:1.12.13+real-5) unstable; urgency=low ++ ++ This cvs package is a totally new packaging and has almost ++ nothing in common with what was in Debian before. The most ++ visible changes are outlined below: ++ ++ pserver is no longer officially supported; the cvs package ++ does not install any service, inetd, or something similar. ++ If you want to set up a CVS server, use SSH, as shown in: ++ * http://www.stremler.net/Code/cvs_tricks/cvs-over-ssh.html ++ * http://www.stremler.net/Code/cvs_tricks/cvs-over-ssh-advanced.html ++ * http://www.stremler.net/Code/cvs_tricks/cvs-over-ssh-advanced2.html ++ ++ Consequentially, PAM is also no longer supported, and this ++ package does not set up or manage any repositories; that's ++ the system administrator's job now. ++ ++ For running "cvs admin" tasks the user must be a member of ++ the new "_cvsadmin" system group, or the repository be set ++ up (UserAdminOptions in CVSROOT/config) to allow everyone. ++ ++ The date format for $Id$ and similar in checkouts has been ++ switched back from ISO 8601 to the standard RCS format, to ++ keep checksums over checkouts/exports consistent. This, as ++ well as the fact that only the :local: and :extssh: access ++ methods are officially supported, is not negotiable. ++ ++ Please direct feature requests upstream, not to the BTS. I ++ do quite an amount of hacking CVS, but prefer to care only ++ about the packaging bits with "full power" in Debian. ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sat, 11 Jun 2011 05:01:49 +0000 +--- cvs-1.12.13+real.orig/debian/changelog ++++ cvs-1.12.13+real/debian/changelog +@@ -0,0 +1,335 @@ ++cvs (2:1.12.13+real-28) unstable; urgency=medium ++ ++ [ Helmut Grohne ] ++ * Reduce Build-Depends: (Closes: #981313) ++ - Drop unused bsdmainutils and procps ++ - Reduce texlive-{fonts,latex}-recommended to texlive-base ++ ++ [ Thorsten Glaser ] ++ * Bump Policy; keep dh5-style build system for now, though (the ++ “good reason” is that the freeze is near) ++ * Bump debhelper ++ * Use /usr/share/dpkg/buildtools.mk to determine ${CC} ++ * Modernise way of setting {C,CPP,LD}FLAGS ++ * Update maintainer scripts ++ * Fix hyphens in cvs-switchroot(1) ++ * Drop pre-wheezy code from maintainer scripts, package relationships ++ * Apply B-D reduction from Helmut Grohne ++ * Update lintian overrides; install (doc-base-referenced) intro.doc ++ to /usr/share/doc/cvs/ not /usr/share/cvs/contrib/ and as intro.txt ++ * Fix several warnings in the code spotted by newer GCC ++ * Reword texinfo documentation to plug overfull/underfull \hbox warnings ++ * Fix texinfo node links for commands (referenced in multiple places) ++ * Plug a memleak, a timing issue and a Y2038 issue on ILP32 and ensure time ++ can’t run backwards within a single invocation ++ * Fix bug in configure.in where old format string support wasn’t disabled ++ * Work around a bug in GCC’s warnings ++ * Retain support for old info format strings for now ++ * Note that running the sanity testsuite needs procps in a comment ++ * corresponding to MirBSD CVS 0AB9.1 ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sun, 31 Jan 2021 18:17:11 +0100 ++ ++cvs (2:1.12.13+real-27) unstable; urgency=low ++ ++ * Hardcode path to /bin/mktemp during configure to build reproducibly ++ * Policy 4.3.0.1 (verbosity changes; R³:no) ++ * Use new lintian source override location ++ * Update lintian overrides ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Tue, 05 Feb 2019 19:31:19 +0100 ++ ++cvs (2:1.12.13+real-26) unstable; urgency=low ++ ++ * Policy 4.1.3 (no changes) ++ * Debhelper 11, prompted by lintian… ++ * Update VCS-* to new repository caused by Alioth deprecation ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Fri, 05 Jan 2018 20:06:42 +0100 ++ ++cvs (2:1.12.13+real-25) unstable; urgency=low ++ ++ * Update from MirBSD (0AB8.4) ++ - support LOGM response ++ * Policy 4.1.1 (no changes) ++ * Use “?=” in debian/rules for dpkg-architecture fields (lintian) ++ * Update watch file ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sun, 19 Nov 2017 18:10:56 +0100 ++ ++cvs (2:1.12.13+real-24) unstable; urgency=high ++ ++ * Update from MirBSD ++ - fix for CVE-2017-12836 (Closes: #871810) ++ - more robust $CVSROOT parsing ++ * Policy 4.0.1 ++ - add nodoc build option ++ ‣ I’m unclear on how this mixes with build profiles and/or ++ Build-Depends exclusion; should I exclude ghostscript, ++ groff, texinfo, texlive-* with <!nodocs> now, or are ++ DEB_BUILD_OPTIONS=nodoc and the profile independent of ++ each other? Info and patches welcome. ++ * Drop explicit (thus redundant) autotools-dev B-D (lintian) ++ * Update lintian overrides ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sat, 12 Aug 2017 22:18:41 +0200 ++ ++cvs (2:1.12.13+real-23) unstable; urgency=low ++ ++ * Improve documentation: ++ - on CVSREADONLYFS ++ - regarding the formerly world-writable files ++ - fix typos, thanks lintian ++ * Remove testsuite logfiles on clean properly ++ * With most environment variables, handle them being defined but ++ empty as undefined, not enabled (fixes the testsuite creating ++ spurious ~/.in and ~/.out files); exceptions: ++ - CVS_PASSWORD (just triggers an error, as previously) ++ - CVSREAD, CVSREADONLYFS (mere presence enables them) ++ Note this in the Debian NEWS file ++ * Fix some spelling in the/and comments ++ * Emit better errors when multiple LogHistory config options occur ++ * Fix some corner cases in the testsuite ++ * Repair the noredirect-writeproxy testsuite mode ++ * Apply the OpenBSD patch for flowcontrol with fast HDD and slow network ++ * Override a false positive lintian warning ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Fri, 28 Apr 2017 21:33:27 +0200 ++ ++cvs (2:1.12.13+real-22) unstable; urgency=low ++ ++ * cvs init: Change default history logging configuration ++ to only log write operations by adding “LogHistory=TMAR” ++ * Testsuite: Alter to cope with this explicit option ++ * cvs init: Rely on CVSUMASK for history and val-tags files ++ in newly created repositories (Closes: #858769) ++ * Add a NEWS.Debian entry verbosely documenting this change ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Tue, 28 Mar 2017 20:01:39 +0200 ++ ++cvs (2:1.12.13+real-21) unstable; urgency=medium ++ ++ [ Sylvain Beucler ] ++ * Add --allow-root-regexp option, for Savannah ++ ++ [ Thorsten Glaser ] ++ * Always add --build=/--host= to avoid config.guess being too smart ++ * Fix testsuite for --allow-root-regexp in the “deny” case ++ * Some minor documentation fixes (wording and formatting) ++ * Remove unnecessary autopoint from Build-Depends; optimise them ++ * Harmonise PDF version 1.4 across all generated PDFs ++ * Generate all PDFs using the PA4 paper size (prints on Letter and A4) ++ * Disable parallel build because the testsuite is not safe ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Mon, 09 Jan 2017 23:19:38 +0000 ++ ++cvs (2:1.12.13+real-20) unstable; urgency=low ++ ++ * Do not spew into syslog when 'cvs pserver' is called from a tty ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Wed, 09 Nov 2016 04:17:18 +0100 ++ ++cvs (2:1.12.13+real-19) unstable; urgency=low ++ ++ * Update from MirBSD CVS: ++ - Fix some spelling mistakes ++ - Greatly improve the manpage introduction (even going so far ++ as to add a “how not to be totally lost in info” section) ++ - Improve documentation cross-references ++ - Apply TCP_NODELAY patch from CVS mailing list ++ * Switch (experimentally) to debhelper compat 10 ++ * Enhances cvs2svn (>= 2.4.0-4~) as it’s added relevant patches ++ * Make cross-buildable (Closes: #842847) ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Tue, 08 Nov 2016 23:22:39 +0000 ++ ++cvs (2:1.12.13+real-18) unstable; urgency=low ++ ++ [ esr ] ++ * Correct a bug in the manpage ++ ++ [ Sergei Trofimovich ] ++ * Fix a memory leak ++ ++ [ Thorsten Glaser ] ++ * Several sanity and getdate fixes ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sun, 23 Oct 2016 00:34:10 +0200 ++ ++cvs (2:1.12.13+real-17) unstable; urgency=medium ++ ++ * Fix a use-after-free bug ++ * Correctly use autoconf to detect long double ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sat, 22 Oct 2016 05:42:39 +0200 ++ ++cvs (2:1.12.13+real-16) unstable; urgency=medium ++ ++ * Take back the package (Closes: #764397) ++ * Fix typo in changelog entry for cvs (2:1.12.13+real-9) and others ++ * Bump Policy; no changes ++ * Update code with bugfixes from MirBSD 0AB7.2 (Closes: #839669) ++ * Actually use correct getdate implementation ++ * groff now needs an explicit ghostscript dependency for ps2pdf ++ * Remove stuff unnecessary with dh-autoreconf ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sat, 22 Oct 2016 02:58:34 +0200 ++ ++cvs (2:1.12.13+real-15) unstable; urgency=low ++ ++ * QA upload. ++ * Orphan the package. ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Tue, 07 Oct 2014 17:58:58 +0000 ++ ++cvs (2:1.12.13+real-14) unstable; urgency=low ++ ++ * debian/control: Move VCS-* fields to Alioth collab-maint git ++ * Remove now-useless RCS IDs ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Tue, 08 Jul 2014 16:10:54 +0200 ++ ++cvs (2:1.12.13+real-12) unstable; urgency=medium ++ ++ * Add texlive-fonts-recommended B-D (thanks Norbert Preining) ++ to fix FTBFS in sid (thanks Daniel Schepler) (Closes: #739138) ++ * Policy 3.9.5 (no changes AFAICT) ++ * Check distfile with upstream signing key (thanks lintian) ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sun, 16 Feb 2014 14:07:36 +0000 ++ ++cvs (2:1.12.13+real-11) unstable; urgency=medium ++ ++ * Add workaround for eglibc crypt(3) returning NULL ++ * If DEB_BUILD_OPTIONS contains “sanity” run testsuite after build ++ * Drop obsolete texi2html B-D (thanks lintian) that was unused anyway ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Thu, 18 Jul 2013 21:52:12 +0000 ++ ++cvs (2:1.12.13+real-10) unstable; urgency=low ++ ++ [ Daniel Schepler ] ++ * Use dh-autoreconf to regenerate configure script and avoid unnecessary ++ compilation of mktime.c, which doesn't work on x32 as is. ++ * Add texlive-latex-recommended to fix just another FTBFS ++ ++ [ Thorsten Glaser ] ++ * Do not compress *.pdf files (cf. #704093) ++ * Allow root to commit ++ * Policy 3.9.4 ++ * Make cvs.texinfo compatible with newer makeinfo (Closes: #711298) ++ * Actually use a fixed mktime.m4 (Closes: #698908) ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Wed, 26 Jun 2013 19:40:39 +0000 ++ ++cvs (2:1.12.13+real-9) unstable; urgency=low ++ ++ * Fix watch file: mangle Epoch away, too ++ * Remove old conffile /etc/pam.d/cvs (Closes: #669957) ++ * Policy 3.9.3 (no changes) ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sun, 22 Apr 2012 15:10:16 +0000 ++ ++cvs (2:1.12.13+real-8) unstable; urgency=high ++ ++ * Brown paper bag change: sanity.sh (the testsuite) was corrupted ++ during checkout of the packaging VCS in the -7 (all PASS again) ++ * Bonus change: use hardening build flags; fix resulting warnings ++ * Urgency due to riding on the previous upload’s security fix ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Tue, 07 Feb 2012 20:39:42 +0000 ++ ++cvs (2:1.12.13+real-7) unstable; urgency=high ++ ++ * Drop unsafe scripts from contrib, add NEWS entry for that ++ (Closes: #658947) ++ * debian/rules: cleanup (remove install/check, dh_installdirs; ++ switch to dh_prep if extant) ++ * Use -Wl,--as-needed for the link to appease dpkg-shlibdebs ++ * Update maintainer scripts from template jupp (better comments) ++ * Drop csh-using contrib script from package, with NEWS entry ++ * Demote rcs2log(1) to contrib, add NEWS entry ++ * Stop shipping a patch to rcs(1) with the binary package, ffs ++ * Don’t ship cvshelp.man either, it’s antiquated and not useful ++ * Fix meaning of -rHEAD for the diff subcommand (with NEWS entry) ++ * Make the testsuite again usable (full PASS) ++ * Apply suggested patch for CVE-2012-0804 from Petr Pisar ++ * Update lintian overrides ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Tue, 07 Feb 2012 18:01:44 +0000 ++ ++cvs (2:1.12.13+real-6) unstable; urgency=low ++ ++ * d/watch: mangle the +real away until 1.12.14 is out, ++ as this is an artefact from the old (epoch 1) packaging ++ * Demote mksh to Suggests, recommended (hah!) by many ++ (Closes: #631110) (merges back ++ 2:1.12.13+real-5debianderivatethatcannotbenamed1) ++ * Honour Policy §11.4; fix by YOSHINO Yoshihito (Closes: #631936) ++ * Use upstream-source-in-CVS packaging, clean up ++ * d/rules: Add build-{arch,indep} targets as aliases to build ++ * Bring d/copyright more in sync with this distfile’s reality ++ * d/control: Reword package description. (Closes: #631826) ++ * If sleeping at exit, sleep another 20 ms (2 HZ), to avoid ++ possible race conditions. (Should work around LP: #12230) ++ * Update in sync with MirPorts 1.12.13-12 = MirOS BSD 0AAF.1 ++ * Stop installing cvsbug(8), use reportbug instead ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Thu, 28 Jul 2011 16:02:02 +0000 ++ ++cvs (2:1.12.13+real-5) unstable; urgency=low ++ ++ * Drop PAM entirely, it was specific to Debian anyway ++ * Add cvs-switchroot, from src/scripts/mnt-cvsroot (Closes: #41685) ++ * Drop some old and irrelevant changelogs from the binary package ++ * Update from MirPorts 1.12.13-11 = MirOS BSD 0AAE.2 ++ * Revert most of 65_login_cvspass_message and just be silent if the ++ pserver client password file doesn't exist and create it silently ++ if needed (Closes: #524146) ++ * Honour noexec flag in 'cvs -n init' (Closes: #151982) ++ * Sync modules option list with cederqvist (Closes: #226888) ++ * Apply patch for assert on negated version numbers on diff ++ (Closes: #297551) ++ From: Peter Moulder <Peter.Moulder@infotech.monash.edu.au> ++ * Change cvs add dir message (Closes: #294094) ++ * Accept port when using extssh connection method (Closes: #151882) ++ * Write a new command for direct ,v file download (Closes: #421119) ++ * Drop broken libbsd.fd.o headers and shut up gcc 4.6 warnings ++ * Fix piuparts breakage: ignore delgroup non-existence on purge ++ * Deliver a NEWS.Debian (Closes: #626106) ++ * d/README.source: Update, call to automake is now also needed ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sat, 11 Jun 2011 05:32:56 +0000 ++ ++cvs (2:1.12.13+real-4) unstable; urgency=low ++ ++ * Renamed .orig.tar.gz due to archive pathname conflict ++ * d/README.source: Document patch location (VCS-CVS, VCS-Browser alike) ++ * New build from MirPorts 1.12.13-10 = MirOS BSD 0AAE.1 ++ - Contains changes from cvs ++ (1:1.12.13-12debianderivatethatcannotbenamed1): ++ + Apply fix from Kees Cook to avoid %n in writable memory (LP: #296453) ++ - Other BTS relevant changes: ++ + Allow CVSROOT-less “version” (LP: #97683) and “cvs version” ++ + Update loginfo documentation, ‘%{t}’ is indeed gone (Closes: #329151) ++ + Lower syslog level from emergency (Closes: #563856) ++ + Fix awk substr start argument, thanks John Hughes (Closes: #518600) ++ + Rename nodes with colons in them (Closes: #113809) ++ + Fix typo (Closes: #464137) ++ + Document missing rcs2log(1) options (Closes: #306354) and fix dashes ++ * Upload new package to Debian unstable (Closes: #306432) ++ (Closes: #458864) (Closes: #464134) (Closes: #479752) ++ (Closes: #576035) (Closes: #614700) (Closes: #617578) ++ - Drop PAM (Closes: #340984) (Closes: #393436) ++ - No longer installs repositories (Closes: #168300) ++ (Closes: #408117) (Closes: #482301) (Closes: #499790) ++ (Closes: #511643) (Closes: #607297) ++ - Deprecate pserver (Closes: #343169) (Closes: #495938) ++ - Drop Origin and Bugs headers again (upload to Debian proper) ++ and old (pre-Debian upload) private repo changelog entries ++ - Thank you, Steve, for handing over package maintainership! ++ * Clarify package description (LP: #377411) ++ * Build with Kerberos V support (Closes: #60800) (LP: #157760) ++ * Recommends: openssh-client; Suggests: rcs ++ ++ -- Thorsten Glaser <tg@mirbsd.de> Sat, 07 May 2011 01:00:39 +0000 +--- cvs-1.12.13+real.orig/debian/control ++++ cvs-1.12.13+real/debian/control +@@ -0,0 +1,40 @@ ++Source: cvs ++Section: vcs ++Priority: optional ++Maintainer: Thorsten Glaser <tg@mirbsd.de> ++Homepage: http://www.nongnu.org/cvs/ ++Build-Depends: debhelper-compat (= 13), ++ ghostscript, groff, libbsd-dev, libkrb5-dev | heimdal-dev, ++# # optional, for running the sanity suite ++# procps, ++ texinfo, texlive-base, zlib1g-dev ++Standards-Version: 4.5.1 ++Rules-Requires-Root: no ++VCS-git: https://evolvis.org/anonscm/git/alioth/cvs.git -b master ++VCS-Browser: https://evolvis.org/plugins/scmgit/cgi-bin/gitweb.cgi?p=alioth/cvs.git;a=shortlog;h=refs/heads/master ++ ++Package: cvs ++Architecture: any ++Multi-Arch: foreign ++Depends: ${misc:Depends}, ${shlibs:Depends}, adduser ++Recommends: openssh-client ++Suggests: mksh, rcs ++Enhances: rcs, cvs2svn (>= 2.4.0-4~) ++Description: Concurrent Versions System ++ CVS is a version control system, which allows you to keep access ++ to 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 texinfo manual provides further information on ++ more tasks that it can perform. ++ . ++ There are some tasks that are not covered by CVS. They can be done in ++ conjunction with CVS but will tend to require some script-writing and ++ software other than CVS. These tasks are bug-tracking, build management ++ (that is, make and make-like tools), and automated testing. However, ++ CVS makes these tasks easier. ++ . ++ This package contains a CVS binary which can act as both client and ++ server, although there is no CVS dæmon; to access remote repositories, ++ please use :extssh: not :pserver: any more. +--- cvs-1.12.13+real.orig/debian/copyright ++++ cvs-1.12.13+real/debian/copyright +@@ -0,0 +1,117 @@ ++This package was debianised by Thorsten Glaser <tg@mirbsd.de> on ++Wed Sep 15 21:52:29 UTC 2010. ++ ++It was downloaded from: ++http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13/cvs-1.12.13.tar.gz ++ ++ ++GNU CVS itself is Copyright © 1986-2005 ++ The Free Software Foundation, Inc. ++with portions contributed by others. ++ ++It is licenced under the GNU General Public License, version 2 or later, ++with a good part available under either GPLv1 or LGPLv2.x. On Debian sy‐ ++stems the licence can be found at: /usr/share/common-licenses/GPL-2 ++ ++Parts of the code are covered by the following GPL-compatible copyright: ++ ++ * Copyright (c) 1993 Bob Withers ++ * All Rights Reserved ++ * ++ * Permission to use, copy, modify, and distribute this software and ++ * its documentation for any purpose and without fee is hereby granted ++ * provided that the above copyright notice appears in all copies and ++ * that both the copyright notice and this permission notice appear in ++ * supporting documentation. ++ ++One header file, which almost certainly does not fall under copyright ++law, is covered by the four-clause UCB licence, however in 1999 the ++advertising clause was rescinded, so it’s GPL compatible now: ++ ++ * 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. ++ ++Parts and the packaging are covered by the following GPL-compatible licence: ++ ++# Copyright © 2005, 2008, 2011, 2017, 2021 ++# mirabilos <m@mirbsd.org> ++# ++# Provided that these terms and disclaimer and all copyright notices ++# are retained or reproduced in an accompanying document, permission ++# is granted to deal in this work without restriction, including un‐ ++# limited rights to use, publicly perform, distribute, sell, modify, ++# merge, give away, or sublicence. ++# ++# This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to ++# the utmost extent permitted by applicable law, neither express nor ++# implied; without malicious intent or gross negligence. In no event ++# may a licensor, author or contributor be held liable for indirect, ++# direct, other damage, loss, or other issues arising in any way out ++# of dealing in the work, even if advised of the possibility of such ++# damage or existence of a defect, except proven that it results out ++# of said person’s immediate fault when using the work as intended. ++ ++CVS also includes a convenience copy of zlib which is not used; ++it’s covered by these (GPL-compatible) terms: ++ ++ Copyright (C) 1995-2005 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. ++ ++zlib, again, contains contributed material under terms as those: ++ ++ * Copyright (c) 1997 ++ * Christian Michelsen Research AS ++ * Advanced Computing ++ * Fantoftvegen 38, 5036 BERGEN, Norway ++ * http://www.cmr.no ++ * ++ * Permission to use, copy, modify, distribute and sell this software ++ * and its documentation for any purpose is hereby granted without fee, ++ * provided that the above copyright notice appear in all copies and ++ * that both that copyright notice and this permission notice appear ++ * in supporting documentation. Christian Michelsen Research AS makes no ++ * representations about the suitability of this software for any ++ * purpose. It is provided "as is" without express or implied warranty. +--- cvs-1.12.13+real.orig/debian/cvs-switchroot ++++ cvs-1.12.13+real/debian/cvs-switchroot +@@ -0,0 +1,99 @@ ++#!/bin/mksh ++# $MirOS: src/scripts/mnt-cvsroot,v 1.19 2016/10/21 21:09:59 tg Exp $ ++#- ++# Copyright © 2005, 2008, 2011 ++# mirabilos <m@mirbsd.org> ++# ++# Provided that these terms and disclaimer and all copyright notices ++# are retained or reproduced in an accompanying document, permission ++# is granted to deal in this work without restriction, including un‐ ++# limited rights to use, publicly perform, distribute, sell, modify, ++# merge, give away, or sublicence. ++# ++# This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to ++# the utmost extent permitted by applicable law, neither express nor ++# implied; without malicious intent or gross negligence. In no event ++# may a licensor, author or contributor be held liable for indirect, ++# direct, other damage, loss, or other issues arising in any way out ++# of dealing in the work, even if advised of the possibility of such ++# damage or existence of a defect, except proven that it results out ++# of said person’s immediate fault when using the work as intended. ++#- ++# Change CVSROOT of a checked out tree (and save space with it) ++# With option -T: change Tag instead of Root ++ ++me=${0##*/} ++function die { ++ print -ru2 -- "$me: $*" ++ exit 1 ++} ++ ++if [[ $1 = -T ]]; then ++ tagmode=-T ++ fn=Tag ++ shift ++else ++ tagmode= ++ fn=Root ++fi ++newroot=$1 ++useroot=0 ++if [[ $newroot = - ]]; then ++ shift ++ newroot=$(realpath "$1") ++ [[ -d $newroot ]] && if [[ -d $newroot/CVS ]]; then ++ newroot=$newroot/CVS/$fn ++ else ++ newroot=$newroot/$fn ++ fi ++ useroot=1 ++fi ++if [[ -z $newroot || $newroot = -? ]]; then ++ print -u2 "Syntax: $me newroot [dir [...]]" ++ print -u2 "\t$me - .../CVS/Root [dir [...]]" ++ print -u2 "\t$me -T - .../CVS/Tag [dir [...]]" ++ exit 1 ++fi ++shift ++ ++[[ -n $1 ]] || set -- . ++ ++# realpath(2)ise arguments ++set -A arg ++i=0 ++for name in "$@"; do ++ arg[i++]=$(realpath "$name") ++done ++ ++T="$(mktemp ${arg[0]}/$me.XXXXXXXXXX)" || die fatal: cannot mktemp ++ ++if (( useroot )); then ++ rm -f "$T" ++ ln "$newroot" "$T" || cp "$newroot" "$T" || \ ++ die "fatal: cannot copy '$newroot' to temporary '$T'" ++fi ++ ++trap 'rm -f "$T"; exit 0' 0 ++trap 'rm -f "$T"; trap - EXIT; exit 1' 1 2 3 5 13 15 ++ ++if (( !useroot )); then ++ chmod 664 "$T" ++ print -r -- "$newroot" >"$T" ++fi ++ ++let rv=0 ++find "${arg[@]}" -path \*/CVS/$fn -print0 |& ++while IFS= read -d '' -pr name; do ++ rm "$name" || die "error: cannot rm <$name>" ++ ln -f "$T" "$name" || if ! U="$(mktemp ${arg[0]}/$me.XXXXXXXXXX)"; then ++ cp "$T" "$name" ++ elif cat "$T" >"$U" && ln -f "$U" "$name"; then ++ rm -f "$T" ++ T="$U" ++ else ++ rm -f "$U" ++ cp "$T" "$name" ++ fi ++done ++ ++exit 0 +--- cvs-1.12.13+real.orig/debian/cvs-switchroot.1 ++++ cvs-1.12.13+real/debian/cvs-switchroot.1 +@@ -0,0 +1,76 @@ ++.Dd June 10, 2011 ++.Dt CVS\-SWITCHROOT 1 ++.Os ++.Sh NAME ++.Nm cvs\-switchroot ++.Nd change repository or tag in a cvs working copy ++.Sh SYNOPSIS ++.Nm ++.Op Fl T ++.Ar newroot ++.Op Ar ++.Pp ++.Nm ++.Op Fl T ++\-\& ++.Ar srcpath ++.Op Ar ++.Sh DESCRIPTION ++The ++.Nm ++utility manipulates a CVS working copy directly, ++modifying the information stored in the administrative ++subdirectory and saving space by hardlinking if possible. ++.Pp ++If the ++.Fl T ++option is given, the sticky tag is operated on, ++otherwise, the repository path ++.Pq Ev CVSROOT . ++.Pp ++The information (Tag or Root) is set to the same as in ++.Ar srcpath ++if the first non-option argument ++.Ar newroot ++is a sole dash ++.Pq Sq \-\& , ++the literal value ++.Ar newroot ++otherwise. ++.Sh EXAMPLES ++Change all ++.Pa Root ++information in the current sandbox to ++.Pa /cvs : ++.Bd -literal -offset ident ++$ cvs\-switchroot /cvs . ++.Ed ++.Pp ++Set all roots in the current working directory and all ++its subdirectories to the ++.Pa Root ++of the parent directory: ++.Bd -literal -offset ident ++$ cvs\-switchroot \- .. . ++.Ed ++.Pp ++Hardlink the ++.Pa Tag ++information in the current working directory, for example ++.Pa /usr/src , ++and ++.Pa /usr/ports ++with each other: ++.Bd -literal -offset ident ++$ cvs\-switchroot \-T \- . . /usr/ports ++.Ed ++.Sh SEE ALSO ++.Xr cvs 1 ++.Sh HISTORY ++.Nm ++has existed in the MirBSD source tree since 2005. ++It was added to Debian's cvs package in 2011. ++.Sh CAVEATS ++.Nm ++depends on ++.Nm mksh . +--- cvs-1.12.13+real.orig/debian/doc-base ++++ cvs-1.12.13+real/debian/doc-base +@@ -0,0 +1,21 @@ ++Document: cvs-doc ++Title: Cederqvist - The CVS manual ++Author: FSF, Derek R. Price, Ximbiot, Signum Support AB, and others ++Abstract: This manual describes how to use and administer CVS. ++ It is both a manual and a tutorial, as well as a reference guide, ++ also known as The Cederqvist, and *the* book to read before using CVS. ++Section: Programming ++ ++Format: HTML ++Index: /usr/share/doc/cvs/cvs.html ++Files: /usr/share/doc/cvs/cvs.html* ++ ++Format: Text ++Files: /usr/share/doc/cvs/cvs.txt* ++ ++Format: PDF ++Files: /usr/share/doc/cvs/cvs.pdf* ++ ++Format: Info ++Index: /usr/share/info/cvs.info.gz ++Files: /usr/share/info/cvs.info* +--- cvs-1.12.13+real.orig/debian/doc-base.client ++++ cvs-1.12.13+real/debian/doc-base.client +@@ -0,0 +1,18 @@ ++Document: cvs-doc-client ++Title: CVS client/server protocol description ++Abstract: This document describes the client/server protocol used by CVS. ++Section: Programming ++ ++Format: HTML ++Index: /usr/share/doc/cvs/cvsclient.html ++Files: /usr/share/doc/cvs/cvsclient.html* ++ ++Format: Text ++Files: /usr/share/doc/cvs/cvsclient.txt* ++ ++Format: PDF ++Files: /usr/share/doc/cvs/cvsclient.pdf* ++ ++Format: Info ++Index: /usr/share/info/cvsclient.info.gz ++Files: /usr/share/info/cvsclient.info* +--- cvs-1.12.13+real.orig/debian/doc-base.faq ++++ cvs-1.12.13+real/debian/doc-base.faq +@@ -0,0 +1,10 @@ ++Document: cvs-doc-faq ++Title: CVS - Frequently Asked Questions ++Author: David Grubbs, Dr. Pascal Molli, and others ++Abstract: Packaged FAQ-O-MATIC dump containing a number of answers ++ to frequently asked questions about CVS. The document may be out of ++ date; http://ximbiot.com/cvs/wiki/CVS%20FAQ contains an updated version. ++Section: Programming ++ ++Format: Text ++Files: /usr/share/doc/cvs/FAQ* +--- cvs-1.12.13+real.orig/debian/doc-base.intro ++++ cvs-1.12.13+real/debian/doc-base.intro +@@ -0,0 +1,7 @@ ++Document: cvs-doc-intro ++Title: Introduction to using CVS ++Author: Steven Pemberton <Steven.Pemberton@cwi.nl> ++Section: Programming ++ ++Format: Text ++Files: /usr/share/doc/cvs/intro.txt* +--- cvs-1.12.13+real.orig/debian/doc-base.paper ++++ cvs-1.12.13+real/debian/doc-base.paper +@@ -0,0 +1,14 @@ ++Document: cvs-doc-paper ++Title: CVS II: Parallelizing Software Development ++Author: Brian Berliner <berliner@prisma.com> ++Abstract: This paper is the cvs USENIX article, Winter 1990. ++ The program described in this paper fills a need in the UNIX community ++ for a freely available tool to manage software revision and release ++ control in a multi-developer, multi-directory, multi-group environment. ++ This tool also addresses the increasing need for tracking third-party ++ vendor source distributions while trying to maintain local modifications ++ to earlier releases. ++Section: Programming ++ ++Format: PDF ++Files: /usr/share/doc/cvs/cvs-paper.pdf* +--- cvs-1.12.13+real.orig/debian/doc-base.rcsfiles ++++ cvs-1.12.13+real/debian/doc-base.rcsfiles +@@ -0,0 +1,11 @@ ++Document: cvs-doc-rcsfiles ++Title: RCS file format description ++Author: Jim Kingdon ++Abstract: This file attempts to document the RCS file format (which is ++ implemented by a great many tools, both free and non-free, both by ++ calling GNU RCS and by reimplementing access to RCS files) in some ++ standard separate from any one tool. ++Section: Programming ++ ++Format: Text ++Files: /usr/share/doc/cvs/RCSFILES* +--- cvs-1.12.13+real.orig/debian/docs ++++ cvs-1.12.13+real/debian/docs +@@ -0,0 +1,20 @@ ++AUTHORS ++BUGS ++DEVEL-CVS ++FAQ ++HACKING ++MINOR-BUGS ++NEWS ++PROJECTS ++README ++TODO ++debian/builddir/doc/*.html ++debian/builddir/doc/*.txt ++debian/builddir/doc/cvs.pdf ++debian/builddir/doc/cvsclient.pdf ++debian/stagedir/clogs/ChangeLog.* ++doc/HACKING.DOCS ++doc/RCSFILES ++doc/cvs-paper.ms ++doc/cvs-paper.pdf ++doc/writeproxy.rtf +--- cvs-1.12.13+real.orig/debian/info ++++ cvs-1.12.13+real/debian/info +@@ -0,0 +1 @@ ++debian/stagedir/usr/share/info/*.info +--- cvs-1.12.13+real.orig/debian/install ++++ cvs-1.12.13+real/debian/install +@@ -0,0 +1,11 @@ ++#contrib/cvs_acls.html usr/share/cvs/contrib/ ++contrib/descend.man usr/share/cvs/contrib/ ++contrib/descend.sh usr/share/cvs/contrib/ ++contrib/rcs2log.1 usr/share/cvs/contrib/ ++contrib/rcs2sccs.sh usr/share/cvs/contrib/ ++contrib/sandbox_status.man usr/share/cvs/contrib/ ++debian/cvs-switchroot usr/bin/ ++debian/lintian/cvs usr/share/lintian/overrides/ ++debian/stagedir/usr/bin/cvs usr/bin/ ++#debian/stagedir/usr/bin/cvsbug usr/bin/ ++debian/stagedir/usr/share/cvs/contrib/* usr/share/cvs/contrib/ +--- cvs-1.12.13+real.orig/debian/lintian/cvs ++++ cvs-1.12.13+real/debian/lintian/cvs +@@ -0,0 +1,2 @@ ++# not really documentation, more a directory listing / description ++cvs: package-contains-documentation-outside-usr-share-doc usr/share/cvs/contrib/README +--- cvs-1.12.13+real.orig/debian/manpages ++++ cvs-1.12.13+real/debian/manpages +@@ -0,0 +1,4 @@ ++debian/cvs-switchroot.1 ++debian/stagedir/usr/share/man/man1/cvs.1 ++debian/stagedir/usr/share/man/man5/cvs.5 ++#debian/stagedir/usr/share/man/man8/cvsbug.8 +--- cvs-1.12.13+real.orig/debian/postinst ++++ cvs-1.12.13+real/debian/postinst +@@ -0,0 +1,50 @@ ++#!/bin/sh ++ ++set -e ++ ++# This maintainer script can be called the following ways: ++# ++# * new-postinst "configure" [$most_recently_configured_version] ++# The package is unpacked; all dependencies are unpacked and, when there ++# are no circular dependencies, configured. ++# ++# * old-postinst "abort-upgrade" $new_version ++# * old-postinst "abort-remove" ++# * conflictors-postinst "abort-remove" "in-favour" $new_package ++# $new_version ++# * deconfigureds-postinst "abort-deconfigure" "in-favour" ++# $failed_install_package $fip_version # new-package ++# ["removing" $conflicting_package $cp_version] # old-package ++# The package is unpacked; all dependencies are at least Half-Installed, ++# previously been configured, and not removed. In some error situations, ++# dependencies may not be even fully unpacked. ++# ++# * postinst "triggered" "${triggers[*]}" ++# For trigger-only calls, i.e. if "configure" is not called. ++# ++# * new-postinst "reconfigure" [$most_recently_configured_version](?) ++# Treat this as just like "configure" for a future extension by debconf. ++ ++case $1 in ++(configure|reconfigure) ++ addgroup --force-badname --system _cvsadmin ++ ;; ++ ++(abort-upgrade|abort-remove|abort-deconfigure) ++ ;; ++ ++(triggered) ++ ;; ++ ++(*) ++ echo >&2 "E: postinst called with unknown subcommand '$1'" ++ exit 1 ++ ;; ++esac ++ ++# dh_installdeb will replace this with shell code automatically ++# generated by other debhelper scripts. ++ ++#DEBHELPER# ++ ++exit 0 +--- cvs-1.12.13+real.orig/debian/postrm ++++ cvs-1.12.13+real/debian/postrm +@@ -0,0 +1,50 @@ ++#!/bin/sh ++ ++set -e ++ ++# This maintainer script can be called the following ways: ++# ++# * postrm "remove" ++# * postrm "purge" ++# * old-postrm "upgrade" $new_version ++# * disappearers-postrm "disappear" $overwriter_pkg $overwriter_version ++# The package's files have been removed or replaced; only Essential pak- ++# kages may be available; skip gracefully actions requiring Depends. ++# ++# * new-postrm "failed-upgrade" $old_version ++# * new-postrm "failed-upgrade" $old_version $new_version # 1.18.5, stretch ++# Called when 'old-postrm "upgrade"' fails; the new package is unpacked, ++# Essential packages and Pre-Depends are available; the latter have been ++# configured and never removed but may be Unpacked or Half-Configured. ++# ++# * new-postrm "abort-install" [$old_version] ++# * new-postrm "abort-install" [$old_version $new_version] # 1.18.5, stretch ++# * new-postrm "abort-upgrade" $old_version ++# * new-postrm "abort-upgrade" $old_version $new_version # 1.18.5, stretch ++# Called when preinst fails; package is not unpacked. Essential packages ++# and (unpacked or Half-Configured) Pre-Depends are available. ++ ++case $1 in ++(remove) ++ ;; ++ ++(purge) ++ test -x /usr/sbin/update-inetd && update-inetd --remove "^cvspserver" ++ (delgroup --system --only-if-empty _cvsadmin || :) ++ ;; ++ ++(upgrade|disappear|failed-upgrade|abort-install|abort-upgrade) ++ ;; ++ ++(*) ++ echo >&2 "E: postrm called with unknown subcommand '$1'" ++ exit 1 ++ ;; ++esac ++ ++# dh_installdeb will replace this with shell code automatically ++# generated by other debhelper scripts. ++ ++#DEBHELPER# ++ ++exit 0 +--- cvs-1.12.13+real.orig/debian/rules ++++ cvs-1.12.13+real/debian/rules +@@ -0,0 +1,185 @@ ++#!/usr/bin/make -f ++ ++ifeq (,$(filter terse,${DEB_BUILD_OPTIONS})) ++export DH_VERBOSE=1 ++export V=1 ++export VERBOSE=1 ++endif ++ ++LC_ALL:=C ++export LC_ALL ++ ++shellescape='$(subst ','\'',$(1))' ++shellexport=$(1)=$(call shellescape,${$(1)}) ++ ++DEB_BUILD_ARCH?=$(shell dpkg-architecture -qDEB_BUILD_ARCH) ++DEB_HOST_ARCH?=$(shell dpkg-architecture -qDEB_HOST_ARCH) ++DEB_BUILD_GNU_TYPE?=$(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) ++DEB_HOST_GNU_TYPE?=$(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) ++ ++OUR_CPPFLAGS:= ++OUR_CFLAGS:= -Wall -Wformat ++OUR_LDFLAGS:= ++ ++OUR_CPPFLAGS+= -D_GNU_SOURCE ++OUR_CPPFLAGS+= -DUSE_LIBBSD ++OUR_CFLAGS+= -fno-strict-aliasing ++# addresses part of #698908 ++OUR_CFLAGS+= -fwrapv ++# for now. uses are mostly checked. ++OUR_CFLAGS+= -Wno-unused-result ++ ++dpkgbuildflagsmkescape=$(subst \,\\\,$(1)) ++export DEB_BUILD_MAINT_OPTIONS:=hardening=+all ++export DEB_CPPFLAGS_MAINT_APPEND:=$(call dpkgbuildflagsmkescape,${OUR_CPPFLAGS}) ++export DEB_CFLAGS_MAINT_APPEND:=$(call dpkgbuildflagsmkescape,${OUR_CFLAGS}) ++export DEB_CXXFLAGS_MAINT_APPEND:=$(call dpkgbuildflagsmkescape,${OUR_CXXFLAGS}) ++export DEB_LDFLAGS_MAINT_APPEND:=$(call dpkgbuildflagsmkescape,${OUR_LDFLAGS}) ++include /usr/share/dpkg/buildflags.mk ++include /usr/share/dpkg/buildtools.mk ++ ++LIBS+= -lbsd ++ ++CONFIGURE_ENV:= $(foreach i,CC CPPFLAGS CFLAGS LDFLAGS LIBS,$(call shellexport,$i)) ++CONFIGURE_ENV+= CSH=/bin/csh ++CONFIGURE_ENV+= ac_cv_path_MKTEMP=/bin/mktemp ++ ++CONFIGURE_ARGS:= --build=${DEB_BUILD_GNU_TYPE} \ ++ --host=${DEB_HOST_GNU_TYPE} \ ++ --prefix=/usr \ ++ --infodir=/usr/share/info \ ++ --mandir=/usr/share/man \ ++ --sysconfdir=/etc \ ++ --disable-dependency-tracking \ ++ --disable-maintainer-mode \ ++ --disable-pam \ ++ --disable-nls \ ++ --enable-client \ ++ --enable-password-authenticated-client \ ++ --enable-server \ ++ --enable-proxy \ ++ --enable-case-sensitivity \ ++ --enable-encryption \ ++ --disable-lock-compatibility \ ++ --enable-rootcommit \ ++ --enable-config-override=no \ ++ --without-krb4 \ ++ --with-gssapi \ ++ --with-external-zlib \ ++ --with-rsh=ssh \ ++ --with-editor=/usr/bin/editor \ ++ --with-tmpdir=/var/tmp \ ++ --with-umask=002 \ ++ --with-cvs-admin-group=_cvsadmin ++ ++MAKE_ARGS:= MAKEINFO=makeinfo ++MAKE_ARGS+= MAKEINFOFLAGS=--no-split ++# ‘u’ is default in Debian and gives warnings (upstream has ‘cru’) ++MAKE_ARGS+= ARFLAGS=rc ++ ++CLEANFILES:= autom4te.cache build-aux/config.guess \ ++ build-aux/config.sub cvs.spec debian/.*_stamp \ ++ debian/CVSTEMP debian/builddir debian/stagedir \ ++ doc/cvs-paper.pdf doc/cvs.1 doc/cvs.info* \ ++ doc/cvs.pdf doc/cvsclient.info* doc/cvsclient.pdf \ ++ doc/getdate-cvs.texi emx/Makefile os2/Makefile \ ++ vms/config.h windows-NT/config.h ++ ++debian/.configure_stamp: ++ dh_testdir ++ -rm -rf ${CLEANFILES} ++ cp /usr/share/misc/config.guess /usr/share/misc/config.sub build-aux/ ++ dh_autoreconf ++ mkdir debian/builddir debian/stagedir ++ cd debian/builddir && \ ++ env ${CONFIGURE_ENV} sh ../../configure ${CONFIGURE_ARGS} ++ # generate PDF 1.4 by default ++ ln -s ../../../build-aux/texinfo.tex debian/builddir/doc/texinfo-r.tex ++ printf '%s\n' \ ++ '\pdfminorversion4\relax\pdfobjcompresslevel0\relax%' \ ++ '\input texinfo-r.tex' \ ++ >debian/builddir/doc/texinfo.tex ++ @:>$@ ++ ++build-indep: ++build build-arch: debian/.build_stamp ++ ++debian/.build_stamp: debian/.configure_stamp ++ dh_testdir ++ cd debian/builddir && ${MAKE} ${MAKE_ARGS} ++ifeq (,$(filter nodoc,$(DEB_BUILD_OPTIONS))) ++ cd debian/builddir && ${MAKE} -C doc ${MAKE_ARGS} doc html info pdf txt ++endif ++ifneq (,$(filter sanity,$(DEB_BUILD_OPTIONS))) ++ # run the testsuite after build (DEB_BUILD_OPTIONS=sanity) ++ # Depends on procps and, if running locally (not in a buildd chroot), ++ # ssh + rsync (logging in to localhost), for testing remote/proxy op. ++ # warning: this takes a *lot* of time! ++ # idea: run this under Valgrind to take even more time ;) ++ cd debian/builddir && ${MAKE} ${MAKE_ARGS} check ++endif ++ @:>$@ ++ ++clean: ++ dh_testdir ++ dh_autoreconf_clean ++ -rm -rf ${CLEANFILES} ++ dh_clean ++ ++binary-indep: ++ ++binary-arch: debian/.build_stamp ++ dh_testdir ++ dh_testroot ++ if test -x "$$(which dh_prep)"; then dh_prep; else dh_clean -k; fi ++ -rm -rf debian/stagedir ++ mkdir -p debian/stagedir/clogs ++ cd debian/builddir && \ ++ ${MAKE} ${MAKE_ARGS} DESTDIR=${CURDIR}/debian/stagedir install ++ cat ChangeLog ChangeLog.zoo >debian/stagedir/clogs/ChangeLog ++ cat doc/ChangeLog doc/ChangeLog.fsf >debian/stagedir/clogs/ChangeLog.doc ++ #cat lib/ChangeLog lib/ChangeLog.fsf >debian/stagedir/clogs/ChangeLog.lib ++ #cat src/ChangeLog src/ChangeLog-97 src/ChangeLog-96 src/ChangeLog-9395 \ ++ # src/ChangeLog-9194 >debian/stagedir/clogs/ChangeLog.src ++ cp src/ChangeLog debian/stagedir/clogs/ChangeLog.src ++ cp contrib/ChangeLog debian/stagedir/clogs/ChangeLog.contrib ++ cp diff/ChangeLog debian/stagedir/clogs/ChangeLog.diff ++ #cp m4/ChangeLog debian/stagedir/clogs/ChangeLog.m4 ++ #cp man/ChangeLog debian/stagedir/clogs/ChangeLog.man ++ #cp tools/ChangeLog debian/stagedir/clogs/ChangeLog.tools ++ # fat and nonsensical to ship this ++ rm -f debian/stagedir/usr/share/cvs/contrib/rcs-5.7-commitid.patch ++ # uses csh ++ rm -f debian/stagedir/usr/share/cvs/contrib/sccs2rcs ++ # unsafe ++ rm -f debian/stagedir/usr/share/cvs/contrib/commit_prep ++ rm -f debian/stagedir/usr/share/cvs/contrib/cvs_acls ++ rm -f debian/stagedir/usr/share/cvs/contrib/log ++ rm -f debian/stagedir/usr/share/cvs/contrib/log_accum ++ rm -f debian/stagedir/usr/share/cvs/contrib/mfpipe ++ rm -f debian/stagedir/usr/share/cvs/contrib/rcslock ++ # we ship cvs-switchroot(1) instead ++ rm -f debian/stagedir/usr/share/cvs/contrib/newcvsroot ++ dh_installchangelogs debian/stagedir/clogs/ChangeLog ++ifneq (,$(filter nodoc,$(DEB_BUILD_OPTIONS))) ++ # this will cause lintian warnings as it installs the doc-base files ++endif ++ dh_installdocs ++ dh_install ++ mv debian/cvs/usr/share/cvs/contrib/intro.doc \ ++ debian/cvs/usr/share/doc/cvs/intro.txt ++ dh_installinfo ++ dh_installman ++ dh_link ++ dh_strip ++ dh_compress -X.pdf ++ cd debian/cvs/usr/share/cvs/contrib && chmod +x descend.sh rcs2sccs.sh ++ dh_fixperms ++ dh_installdeb ++ dh_shlibdeps ++ dh_gencontrol ++ dh_md5sums ++ dh_builddeb -- -Zgzip -z9 ++ ++binary: binary-indep binary-arch ++.PHONY: binary binary-arch binary-indep build build-arch build-indep clean +--- cvs-1.12.13+real.orig/debian/source/format ++++ cvs-1.12.13+real/debian/source/format +@@ -0,0 +1 @@ ++1.0 +--- cvs-1.12.13+real.orig/debian/source/lintian-overrides ++++ cvs-1.12.13+real/debian/source/lintian-overrides +@@ -0,0 +1,35 @@ ++# reused downstream with request to keep compressing with gzip ++cvs source: custom-compression-in-debian-rules ++ ++# (well at least for now) ++# not my fault ++cvs source: deprecated-configure-filename ++ ++# too near the freeze to change it now ++cvs source: no-dh-sequencer ++ ++# desired method of keeping changes is as VCS working tree ++cvs source: older-source-format 1.0 ++cvs source: direct-changes-in-diff-but-no-patch-system * ++ ++# wtf lintian‽ ++cvs source: cute-field ++ ++# not part of the binary package, and not legally a problem ++cvs source: license-problem-gfdl-non-official-text doc/getdate-cvs.texi * ++ ++# this originates here, but I may just include it in a release later ++cvs source: maintainer-manual-page debian/cvs-switchroot.1 ++ ++# no, thanks ++cvs source: no-dep5-copyright ++ ++# not our examples ++cvs source: package-does-not-install-examples zlib/examples/ ++ ++# this is… complicated; this package’s upstream is MirBSD, ++# not Savannah (nonGNU), which is the de-facto upstream of ++# (the 1.12.x series) GNU CVS as it is the only place with ++# activity for ages but the Savannah people didn’t manage, ++# yet, to officially transfer this, so let’s not, for now… ++cvs source: upstream-metadata-file-is-missing +--- cvs-1.12.13+real.orig/debian/upstream/signing-key.asc ++++ cvs-1.12.13+real/debian/upstream/signing-key.asc +@@ -0,0 +1,25 @@ ++-----BEGIN PGP PUBLIC KEY BLOCK----- ++Version: GnuPG v1 ++ ++mQGiBD4u3XQRBACN7F6Ducb4gaJw7LJPCaNbk4+eW/EWjiC+aoJhnNocWGfeKM2d ++NYRDPuyW6IqAmMPGBq0HAdSmi64BQg5mC8Q7NGujfzVDefACELuwQRUxFadbcAXn ++1eGUHGsst93FFwlhY+SH3Yuo1plvNBnlMhDt9ylT3/s38zKG874+A44L4wCg/7fh ++u0zqxFA0w22lXobhkKO4upED/0zA5BJ+d8brNLe6RpIQXTUzPxZ+UoU5RG9wlzv/ ++zabSS6eAPpmeoIPeKdSwRO/G0/f3Qn/vxDKVTqRzNKpusKJz8TS+gDBZSFjQ1L3U ++TL6qh5kdnTy/yETg8wiUMXVaTqWtXP2eFEoHoto6dVP46BuULqQK980EmR6jg/ul ++EGC/BACD5iO81tygsm6OBEu59hJ+GykU60+9Mzz1/qPYdejJmJkmdoJZWplJULGD ++270nQlDarPJzMCpyrUzAZYdnmO6dwic/4hIxJENQ3GBrhbdr6YuuNgTxIXJJxTH7 ++qTJqRrHLw9Cvk1oPFYlzE2vQuDNlrqxXg/V06l4/ZJfotj3mI7RNRGVyZWsgUi4g ++UHJpY2UgKEdldCBDVlMgU3VwcG9ydCBhdCA8aHR0cDovL3hpbWJpb3QuY29tPiEp ++IDxkZXJla0B4aW1iaW90LmNvbT6IYQQTEQIAGQUCPi7ddAQLBwMCAxUCAwMWAgEC ++HgECF4AAEgkQLD1OTBfyMaQHZUdQRwABAVEoAJ9o9E9Ya1dKUi1xRepkcpWqzjjt ++OgCgqSQSvoBA3NLu8/US2RAb+Xn1vAK5AQ0EPi7dehAEAJgUmO0vNtZJj4qUyyFd ++lw9wH9jQVRwblKxItr/0eO28ta+JOXWH668/wcyJFbVCulanS/o1crbq1bq3662Q ++EiHaZuB4hUJHCmkrfnxSvyw+w3tvk1ByiWw4uhsIiYCLpq6h/w9Yv0bSXOctGWFv ++/dnZw1f/N1PLU955Ze7hofVrAAMGA/9dw6G1LznEO2zjfTYHZtEKSlAtvRGqyOQc ++7htMOXagUpPAF/KGHnBETWVyuEfNNW1c/EQ3LQi+L23q9u0L+cAcWiR4SBCejEII ++3bFE3hPLGxfa0LamJrq0kkSDoYm6OWB4WNPSGBCSZywwdLnLjqXiCU1+rT6qZcvN ++JEKFAJUOA4hOBBgRAgAGBQI+Lt16ABIJECw9TkwX8jGkB2VHUEcAAQE9AACfTWlS ++/WpC3LgkF8rcbbap9M8U/RkAoL2DhkJHX3uYYJzagVUiWJffkLnR ++=hls5 ++-----END PGP PUBLIC KEY BLOCK----- +--- cvs-1.12.13+real.orig/debian/watch ++++ cvs-1.12.13+real/debian/watch +@@ -0,0 +1,3 @@ ++version=4 ++opts="dversionmangle=s/^[0-9]+://;s/\+real$//,pgpsigurlmangle=s/$/.sig/" \ ++https://ftp.gnu.org/non-gnu/cvs/source/feature/([0-9.]*)/ cvs-([0-9.]*)\.tar\.gz +--- cvs-1.12.13+real.orig/diff/analyze.c ++++ cvs-1.12.13+real/diff/analyze.c +@@ -358,7 +358,7 @@ + else + { + int c; +- struct partition part; ++ struct partition part = { 0, 0, 0, 0 }; + + /* Find a point of correspondence in the middle of the files. */ + +--- cvs-1.12.13+real.orig/diff/diff3.c ++++ cvs-1.12.13+real/diff/diff3.c +@@ -1439,14 +1439,13 @@ + int const mapping[3], rev_mapping[3]; + { + int i; +- int oddoneout; ++ int oddoneout = 0; + char *cp; + struct diff3_block *ptr; + int line; + size_t length; +- int dontprint; ++ int dontprint = 0; + static int skew_increment[3] = { 2, 3, 1 }; /* 0==>2==>1==>3 */ +- char const *line_prefix = tab_align_flag ? "\t" : " "; + + for (ptr = diff; ptr; ptr = D_NEXT (ptr)) + { +@@ -1503,7 +1502,7 @@ + line = 0; + do + { +- printf_output (line_prefix); ++ printf_output (tab_align_flag ? "\t" : " "); + cp = D_RELNUM (ptr, realfile, line); + length = D_RELLEN (ptr, realfile, line); + write_output (cp, length); +@@ -1555,11 +1554,12 @@ + int leading_dot, start, num; + { + write_output (".\n", 2); +- if (leading_dot) ++ if (leading_dot) { + if (num == 1) + printf_output ("%ds/^\\.//\n", start); + else + printf_output ("%d,%ds/^\\.//\n", start, start + num - 1); ++ } + } + + /* +@@ -1750,11 +1750,12 @@ + do + { + c = getc (infile); +- if (c == EOF) ++ if (c == EOF) { + if (ferror (infile)) + diff3_perror_with_exit ("input file"); + else if (feof (infile)) + diff3_fatal ("input file shrank"); ++ } + cc = c; + write_output (&cc, 1); + } +@@ -1804,7 +1805,7 @@ + linesread += i; + while (0 <= --i) + while ((c = getc (infile)) != '\n') +- if (c == EOF) ++ if (c == EOF) { + if (ferror (infile)) + diff3_perror_with_exit ("input file"); + else if (feof (infile)) +@@ -1813,6 +1814,7 @@ + diff3_fatal ("input file shrank"); + return conflicts_found; + } ++ } + } + /* Copy rest of common file. */ + while ((c = getc (infile)) != EOF || !(ferror (infile) | feof (infile))) +--- cvs-1.12.13+real.orig/diff/ifdef.c ++++ cvs-1.12.13+real/diff/ifdef.c +@@ -189,7 +189,7 @@ + + default: + { +- int value; ++ int value = 0; + char *speclim; + + f = scan_printf_spec (spec); +@@ -322,7 +322,7 @@ + + default: + { +- int value; ++ int value = 0; + char *speclim; + + f = scan_printf_spec (spec); +--- cvs-1.12.13+real.orig/diff/side.c ++++ cvs-1.12.13+real/diff/side.c +@@ -122,7 +122,7 @@ + break; + + case '\b': +- if (in_position != 0 && --in_position < out_bound) ++ if (in_position != 0 && --in_position < out_bound) { + if (out_position <= in_position) + /* Add spaces to make up for suppressed tab past out_bound. */ + for (; out_position < in_position; out_position++) +@@ -133,6 +133,7 @@ + cc = c; + write_output (&cc, 1); + } ++ } + break; + + case '\f': +--- cvs-1.12.13+real.orig/diff/util.c ++++ cvs-1.12.13+real/diff/util.c +@@ -235,7 +235,7 @@ + close (pipes[0]); + } + +- execl (PR_PROGRAM, PR_PROGRAM, "-f", "-h", name, 0); ++ execl (PR_PROGRAM, PR_PROGRAM, "-f", "-h", name, NULL); + pfatal_with_name (PR_PROGRAM); + } + else +--- cvs-1.12.13+real.orig/doc/HACKING.DOCS ++++ cvs-1.12.13+real/doc/HACKING.DOCS +@@ -16,7 +16,9 @@ + @strong{ ... } Similar to @emph{}, but the effect is to + bracket with asterisks in info files (* ... *) + and in bold in PDF & probably in postscript & +- HTML. ++ HTML. It will cause spurious links in info if ++ used in some circumstances; if in doubt, use ++ @empy{ ... } instead then. + @noindent Suppresses indentation of the following + paragraph. This can ocassionally be useful + after examples and the like. +@@ -44,3 +46,6 @@ + + For more on using texinfo docs, see the `info texinfo' documentation or + http://www.gnu.org/manual/texinfo/texinfo.html . ++ ++ ++$MirOS: src/gnu/usr.bin/cvs/doc/HACKING.DOCS,v 1.3 2010/09/19 19:42:52 tg Exp $ +--- cvs-1.12.13+real.orig/doc/Makefile.am ++++ cvs-1.12.13+real/doc/Makefile.am +@@ -1,4 +1,5 @@ + ## Process this file with automake to produce Makefile.in ++# $MirOS: src/gnu/usr.bin/cvs/doc/Makefile.am,v 1.5 2017/01/09 22:54:22 tg Exp $ + # Makefile for GNU CVS documentation (excluding man pages - see ../man). + # + # Copyright (C) 1986-2005 The Free Software Foundation, Inc. +@@ -84,7 +85,7 @@ + # It is possible that an implicit .ms.ps target could be safely defined. I + # don't recall looking into it. + cvs-paper.ps: cvs-paper.ms +- $(ROFF) -t -p -ms -Tps $(srcdir)/cvs-paper.ms >cvs-paper.ps-t ++ $(ROFF) -t -p -ms -Tps -P-p28c,21c $(srcdir)/cvs-paper.ms >cvs-paper.ps-t + cp cvs-paper.ps-t $@ + -@rm -f cvs-paper.ps-t + +@@ -92,8 +93,8 @@ + # Nothing in $(srcdir) be rebuilt, and this will always be rebuilt when it + # is dependant on cvs-paper.ps and cvs-paper.ps isn't distributed. + $(srcdir)/cvs-paper.pdf: cvs-paper.ms +- $(ROFF) -t -p -ms -Tps $(srcdir)/cvs-paper.ms >cvs-paper.ps-t +- ps2pdf cvs-paper.ps-t cvs-paper.pdf-t ++ $(ROFF) -t -p -ms -Tps -P-p28c,21c $(srcdir)/cvs-paper.ms >cvs-paper.ps-t ++ ps2pdf14 -sPAPERSIZE=pa4 cvs-paper.ps-t cvs-paper.pdf-t + cp cvs-paper.pdf-t $@ + -@rm -f cvs-paper.pdf-t cvs-paper.ps-t + +--- cvs-1.12.13+real.orig/doc/cvs-paper.ms ++++ cvs-1.12.13+real/doc/cvs-paper.ms +@@ -1,4 +1,5 @@ + .\" soelim cvs.ms | pic | tbl | troff -ms ++.\" $MirOS: src/gnu/usr.bin/cvs/doc/cvs-paper.ms,v 1.3 2017/08/12 17:37:55 tg Exp $ + .\" @(#)cvs.ms 1.2 92/01/30 + .\" + .\" troff source to the cvs USENIX article, Winter 1990, Washington, D.C. +@@ -108,7 +109,7 @@ + .SM + SCCS + .LG +-[Bell] serialize file modifications by ++[Bell] serialise file modifications by + allowing only one developer to have a writable copy of a particular file at + any one point in time. + That developer is said to +@@ -312,7 +313,7 @@ + the copy, and then merges the modified copy with the original. + This paradigm allows developers to work in isolation from one another since + changes are made to copies of objects. +-Because locks are not used, development is not serialized and can proceed ++Because locks are not used, development is not serialised and can proceed + in parallel. + Developers, however, must merge objects after the changes have been made. + In particular, a developer must resolve conflicts when the same object has +@@ -853,7 +854,7 @@ + it has been checked out, takes only 1.5 wall clock minutes. + Updating the \fIcomplete\fP 128 MByte source tree under \fBcvs\fP control + (17243 files/1005 directories) takes roughly 28 wall clock minutes and +-utilizes one-third of the machine. ++utilises one-third of the machine. + For now this is entirely acceptable; improvements on these numbers will + possibly be made in the future. + .NH 2 +@@ -923,7 +924,7 @@ + .IP \(bu 3 + Security of the source repository is currently not dealt with directly. + The usual UNIX approach of user-group-other security permissions through +-the file system is utilized, but nothing else. ++the filesystem is utilised, but nothing else. + \fBcvs\fP could likely be a set-group-id executable that checks a + protected database to verify user access permissions for particular objects + before allowing any operations to affect those objects. +--- cvs-1.12.13+real.orig/doc/cvs.man.footer ++++ cvs-1.12.13+real/doc/cvs.man.footer +@@ -1,3 +1,4 @@ ++.\" $MirOS: src/gnu/usr.bin/cvs/doc/cvs.man.footer,v 1.6 2017/01/08 19:42:05 tg Exp $ + .SH "AUTHORS" + .TP + Dick Grune +@@ -26,15 +27,13 @@ + Have helped maintain + .B cvs + for many years. +-.TP ++.PP + And many others too numerous to mention here. + .SH "SEE ALSO" + The most comprehensive manual for CVS is +-Version Management with CVS by Per Cederqvist et al. Depending on +-your system, you may be able to get it with the +-.B info CVS +-command or it may be available as cvs.pdf (Portable Document Format), +-cvs.ps (PostScript), cvs.texinfo (Texinfo source), or cvs.html. ++Version Management with CVS by Per Cederqvist et al. (see ++.I NOTE ++at top). + .SP + For CVS updates, more information on documentation, software related + to CVS, development of CVS, and more, see: +@@ -43,7 +42,6 @@ + .PD 0 + .IP "" 4 + .B http://www.nongnu.org/cvs/ +-.in -1i + .SP + .BR ci ( 1 ), + .BR co ( 1 ), +@@ -54,5 +52,7 @@ + .BR patch ( 1 ), + .BR rcs ( 1 ), + .BR rcsdiff ( 1 ), ++.BR rcsintro ( 1 ), + .BR rcsmerge ( 1 ), +-.BR rlog ( 1 ). ++.BR rlog ( 1 ), ++.BR re_format ( 7 ). +--- cvs-1.12.13+real.orig/doc/cvs.man.header ++++ cvs-1.12.13+real/doc/cvs.man.header +@@ -1,3 +1,5 @@ ++.\" $MirOS: src/gnu/usr.bin/cvs/doc/cvs.man.header,v 1.6 2016/11/08 21:12:15 tg Exp $ ++.\" + .\" This is the man page for CVS. It is auto-generated from the + .\" cvs.man.header, cvs.texinfo, & cvs.man.footer files. Please make changes + .\" there. A full copyright & license notice may also be found in cvs.texinfo. +@@ -5,6 +7,7 @@ + .\" Man page autogeneration, including this header file, is + .\" Copyright 2004-2005 The Free Software Foundation, Inc., + .\" Derek R. Price, & Ximbiot <http://ximbiot.com>. ++.\" Copyright (c) 2004, 2010, 2012, 2016 mirabilos <m@mirbsd.org>. + .\" + .\" This documentation is free software; you can redistribute it and/or modify + .\" it under the terms of the GNU General Public License as published by +@@ -23,7 +26,9 @@ + .ds Rv \\$3 + .ds Dt \\$4 + .. +-.TH CVS 1 "\*(Dt" ++.de IX ++.. ++.TH CVS 1 + .\" Full space in nroff; half space in troff + .de SP + .if n .sp +@@ -51,11 +56,82 @@ + .IX "release control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system" + .IX "source control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system" + .IX revisions "cvs command" "" "\fLcvs\fP \- source control" +-This manpage is a summary of some of the features of +-\fBcvs\fP. It is auto-generated from an appendix of the CVS manual. +-For more in-depth documentation, please consult the +-Cederqvist manual (via the +-.B info CVS +-command or otherwise, +-as described in the SEE ALSO section of this manpage). Cross-references +-in this man page refer to nodes in the same. ++.\" ++This manual page is a summary of parts of the \fBcvs\fP documentation ++and automatically generated from an appendix of the CVS manual ++(the \fICederqvist\fP), which is also the target of all cross-references ++found in this manual page; please refer to the full CVS manual ++for more in-depth documentation of the Concurrent Versions System. ++.PP ++If you're reading this manual page as part of the MirBSD online (HTML) ++manual pages archive, follow the cvs(GNU) link to the Cederqvist ++(and the cvsclient(GNU) link to the client/server protocol description, ++if necessary). ++.PP ++If you installed ++.B cvs ++via the Debian or MirPorts Framework package management systems, ++.br ++.RS ++.B /usr/mpkg/share/doc/cvs/cvs.pdf ++(MirPorts Framework) or ++.br ++.B /usr/share/doc/cvs/cvs.pdf ++(Debian), respectively, ++.RE ++are versions of the Cederqvist rendered as books, for printing ++and reading on screen. ++.PP ++If you have a Texinfo reader such as ++.B info ++installed (part of the base system on MirBSD; part of the ++.I info ++package on Debian), you can read the Cederqvist by entering: ++.br ++.RS ++.B info ++.I cvs ++.RE ++.PP ++Quick introduction to ++.B info ++so you aren't immediately lost: ++.RS 4n ++.TP 3n ++.I arrow\ keys ++to move on the page ++.TP 3n ++.I Tab ++to move to the next hyperlink ++.TP 3n ++.I Return ++to activate the hyperlink under the cursor ++.TP 3n ++.BI l \ (lowercase\ ell) ++to go to the previously visited page ++.TP 3n ++.IB Page\ Up/ b,\ Page\ Down/Space ++to move by screen pages, including advancing to the previous ++(or next, respectively) section at the first (last) screen page ++.TP 3n ++.B p,\ n ++to go to the previous (next) page on the current navigation hierarchy level ++.TP 3n ++.B t ++to go to the "Top" page, i.e. the start of the document ++.TP 3n ++.BI / <search-term>Return ++to start a search from the current cursor position and jump to the first result ++.TP 3n ++.BI / Return ++to jump to the next result in an ongoing search ++.TP 3n ++.B q ++to exit the ++.B info ++viewer ++.RE ++.PP ++Other ways to read further documentation are described in the ++.I SEE\ ALSO ++section of this manual page. +--- cvs-1.12.13+real.orig/doc/cvs.texinfo ++++ cvs-1.12.13+real/doc/cvs.texinfo +@@ -1,6 +1,18 @@ + \input texinfo @c -*-texinfo-*- + @comment Documentation for CVS. + @setfilename cvs.info ++@set MBSDPATCHLEVEL -MirOS-0AB9.1 ++@tex ++ % set PA4 paper size (can print on both DIN ISO A4 and US Letter) ++ \globaldefs = 1% ++ \afourpaper% ++ \internalpagesizes{46\baselineskip}{160mm}% ++ {\voffset}{\hoffset}% ++ {\bindingoffset}{36pt}% ++ {28truecm}{21truecm}% ++ \globaldefs = 0% ++@end tex ++@comment $MirOS: src/gnu/usr.bin/cvs/doc/cvs.texinfo,v 1.38 2021/01/30 02:05:55 tg Exp $ + @macro copyleftnotice + @noindent + Copyright @copyright{} 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +@@ -9,7 +21,11 @@ + + @multitable @columnfractions .12 .88 + @item Portions +-@item @tab Copyright @copyright{} 1999, 2000, 2001, 2002, 2003, 2004, 2005 ++@item @tab Copyright @copyright{} 2003, 2004, 2005, 2007, 2009, 2010, 2011, ++ 2013, 2014, 2015, 2016, 2017, 2021 ++ mirabilos, The MirOS Project ++@item @tab Copyright @copyright{} 1999, 2000, 2001, 2002, 2003, 2004, 2005, ++ 2007 + Derek R. Price, + @item @tab Copyright @copyright{} 2002, 2003, 2004, 2005 + Ximbiot @url{http://ximbiot.com}, +@@ -51,6 +67,15 @@ + @comment MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + @comment GNU General Public License for more details. + ++@comment It should be noted that the Texinfo manual is distributed ++@comment under the above notice in all forms, except for the manpage ++@comment generated from it, and that the manual and the source code ++@comment of CVS often need to stay synchronised; therefore, exchanging ++@comment between these three entities under these two licences seems ++@comment to be granted, and the statement above can be interpreted as ++@comment explicit dual-licence grant. As a major contributor to this ++@comment documentation for MirBSD, I do not oppose. --mirabilos ++ + @c See ../README for A4 vs. US letter size. + @c When we provided A4 postscript, and people tried to + @c print it on US letter, the usual complaint was that the +@@ -103,7 +128,7 @@ + @end direntry + @dircategory Individual utilities + @direntry +-* cvs: (cvs)CVS commands. Concurrent Versions System ++* cvs: (cvs)CVS command list. Concurrent Versions System + @end direntry + + @comment The titlepage section does not appear in the Info file. +@@ -111,12 +136,12 @@ + @sp 4 + @comment The title is printed in a large font. + @center @titlefont{Version Management} +-@sp ++@sp 1 + @center @titlefont{with} +-@sp ++@sp 1 + @center @titlefont{CVS} + @sp 2 +-@center for @sc{cvs} @value{VERSION} ++@center for @sc{cvs} @value{VERSION}@value{MBSDPATCHLEVEL} + @comment -release- + @sp 3 + @center Per Cederqvist et al +@@ -141,13 +166,20 @@ + @node Top + @top + ++@ifnotinfo ++@anchor{Cederqvist} ++@end ifnotinfo + This info manual describes how to use and administer +-@sc{cvs} version @value{VERSION}. ++@sc{cvs} version @value{VERSION}@value{MBSDPATCHLEVEL} and up. + @end ifnottex + + @ifinfo + @copyleftnotice ++@anchor{Cederqvist} + @end ifinfo ++@iftex ++@anchor{Cederqvist} ++@end iftex + + @c This menu is pretty long. Not sure how easily that + @c can be fixed (no brilliant ideas right away)... +@@ -181,6 +213,7 @@ + * Troubleshooting:: Some tips when nothing works + * Credits:: Some of the contributors to this manual + * BUGS:: Dealing with bugs in CVS or this manual ++* CVS command list:: Alphabetical list of all CVS commands + * Index:: Index + @end menu + +@@ -327,7 +360,7 @@ + you wind up requiring the entire repository to be + checked out. + +-If you modularize your work, and construct a build ++If you modularise your work, and construct a build + system that will share files (via links, mounts, + @code{VPATH} in @file{Makefile}s, etc.), you can + arrange your disk usage however you like. +@@ -483,11 +516,11 @@ + As a way of introducing @sc{cvs}, we'll go through a + typical work-session using @sc{cvs}. The first thing + to understand is that @sc{cvs} stores all files in a +-centralized @dfn{repository} (@pxref{Repository}); this ++centralised @dfn{repository} (@pxref{Repository}); this + section assumes that a repository is set up. + @c I'm not sure that the sentence concerning the + @c repository quite tells the user what they need to +-@c know at this point. Might need to expand on "centralized" ++@c know at this point. Might need to expand on "centralised" + @c slightly (maybe not here, maybe further down in the example?) + + Suppose you are working on a simple compiler. The source +@@ -742,7 +775,7 @@ + @c /home/joe/sources. But this node is too long + @c as it is; need a little reorganization... + +-@cindex :local:, setting up ++@cindex local method, setting up + @sc{cvs} can access a repository by a variety of + means. It might be on the local computer, or it might + be on a computer across the room or across the world. +@@ -1037,10 +1070,6 @@ + if you want to allow read-only access to some directories + (@pxref{config}). + +-@c CVS seems to use CVSUMASK in picking permissions for +-@c val-tags, but maybe we should say more about this. +-@c Like val-tags gets created by someone who doesn't +-@c have CVSUMASK set right? + @cindex CVSROOT/val-tags file, and read-only access to projects + @cindex val-tags file, and read-only access to projects + Also note that users must have write access to the +@@ -1072,7 +1101,7 @@ + @c FIXME: Need more discussion of which + @c group should own the file in the repository. + @c Include a somewhat detailed example of the usual +-@c case where CVSUMASK is 007, the developers are all ++@c case where CVSUMASK is 002, the developers are all + @c in a group, and that group owns stuff in the + @c repository. Need to talk about group ownership of + @c newly-created directories/files (on some unices, +@@ -1152,7 +1181,7 @@ + sure). + + If you are using local @sc{cvs} and the repository is on a +-networked file system which is served by the Samba SMB ++networked filesystem which is served by the Samba SMB + server, some people have reported problems with + permissions. Enabling WRITE=YES in the samba + configuration is said to fix/workaround it. +@@ -1551,7 +1580,7 @@ + This file lists the files and directories in the + working directory. + The first character of each line indicates what sort of +-line it is. If the character is unrecognized, programs ++line it is. If the character is unrecognised, programs + reading the file should silently skip that line, to + allow for future expansion. + +@@ -1780,7 +1809,7 @@ + @cindex CVSROOT, module name + @cindex Defining modules (intro) + +-@c FIXME: this node should be reorganized into "general ++@c FIXME: this node should be reorganised into "general + @c information about admin files" and put the "editing + @c admin files" stuff up front rather than jumping into + @c the details of modules right away. Then the +@@ -1931,14 +1960,23 @@ + on what each developer uses). + + The repository should be accessible +-(directly or via a networked file system) from all ++(directly or via a networked filesystem) from all + machines which want to use @sc{cvs} in server or local + mode; the client machines need not have any access to + it other than via the @sc{cvs} protocol. It is not +-possible to use @sc{cvs} to read from a repository ++normally possible to use @sc{cvs} to read from a repository + which one only has read access to; @sc{cvs} needs to be + able to create lock files (@pxref{Concurrency}). + ++If the environment variable @code{$CVSREADONLYFS} is defined, ++however, CVS will allow read-only access without creating any ++history entries or reader lock files. This allows doing most ++usual repository operations except checkin in a fast way, ++although if any other user is accessing the same data at the ++same time, it may lead to corrupt data. This mode is best used ++for publicly accessible anonymous CVS mirrors, not the main ++working repository. ++ + @cindex init (subcommand) + To create a repository, run the @code{cvs init} + command. It will set up an empty repository in the +@@ -1954,9 +1992,18 @@ + you run @code{cvs init} on an already set-up + repository. + +-@code{cvs init} will enable history logging; if you +-don't want that, remove the history file after running +-@code{cvs init}. @xref{history file}. ++The repository is created honouring the @code{$CVSUMASK} ++setting (@pxref{CVSUMASK}), even the @file{history} and ++@file{val-tags} files are not created world-writable any ++more as in previous CVS versions. History logging is, ++accordingly, configured to log write operations only; if ++you don’t want that, edit or remove the @samp{LogHistory} ++entry in the @file{config} file (@pxref{config}) and make ++sure that all users who need to write that file can do so, ++for example by using a @code{$CVSUMASK} of 002 (which is ++also the default) and putting everyone into the same Unix ++group (consider the security implications if you really ++want to enable world-writable logging). + + @node Backing up + @section Backing up a repository +@@ -2103,6 +2150,9 @@ + * Write proxies:: Distributing load across several CVS servers + @end menu + ++For the protocol specification, ++@pxref{Top, the CVS client/server protocol,, cvsclient, The CVS client/server protocol}. ++ + @node Server requirements + @subsection Server requirements + +@@ -2236,19 +2286,19 @@ + through and @var{port} is the port number on the HTTP proxy server to connect + via. @var{port} defaults to 8080. + +-@strong{NOTE: An HTTP proxy server is not the same as a @sc{cvs} write proxy ++@emph{NOTE: An HTTP proxy server is not the same as a @sc{cvs} write proxy + server - please see @ref{Write proxies} for more on @sc{cvs} write proxies.} + + For example, to connect pserver via a web proxy listening on port 8000 of + www.myproxy.net, you would use a method of: + + @example +-:pserver;proxy=www.myproxy.net;proxyport=8000:@var{pserver_connection_string} ++:pserver;proxy=www.myproxy.net;proxyport=8000:@var{connstr} + @end example + +-@strong{NOTE: In the above example, @var{pserver_connection_string} is still +-required to connect and authenticate to the CVS server, as noted in the +-upcoming sections on password authentication, @code{gserver}, and ++@emph{NOTE: In the above example, the pserver connection string @var{connstr} ++is still required to connect and authenticate to the CVS server, as noted in ++the upcoming sections on password authentication, @code{gserver}, and + @code{kserver}. The example above only demonstrates a modification to the + @var{method} portion of the repository name.} + +@@ -2369,7 +2419,7 @@ + machine to the filename of the server you want to use, + for example @file{/usr/local/bin/cvs-1.6}. + For the @code{ext} and @code{fork} methods, you may +-also specify @var{CVS_SERVER} as an otpion in the ++also specify @var{CVS_SERVER} as an option in the + @var{CVSROOT} so that you may use different servers for + differnt roots. See @ref{Remote repositories} for more + details. +@@ -2377,21 +2427,23 @@ + There is no need to edit @file{inetd.conf} or start a + @sc{cvs} server daemon. + +-@cindex :server:, setting up +-@cindex :ext:, setting up ++@cindex server method, setting up ++@cindex ext method, setting up + @cindex Kerberos, using kerberized rsh + @cindex SSH (rsh replacement) + @cindex rsh replacements (Kerberized, SSH, &c) + There are two access methods that you use in @code{CVSROOT} + for rsh. @code{:server:} specifies an internal rsh + client, which is supported only by some @sc{cvs} ports. ++This is not supported on most Unix-style systems. + @code{:ext:} specifies an external rsh program. By + default this is @code{rsh} (unless otherwise specified + by the @file{--with-rsh} flag to configure) but you may set the + @code{CVS_RSH} environment variable to invoke another + program which can access the remote server (for + example, @code{remsh} on HP-UX 9 because @code{rsh} is +-something different). It must be a program which can ++something different, or @code{ssh} to allow the use of secure ++and/or compressed connections). It must be a program which can + transmit data to and from the server without modifying + it; for example the Windows NT @code{rsh} is not + suitable since it by default translates between CRLF +@@ -2405,6 +2457,12 @@ + to be inapplicable; consult the documentation for your rsh + replacement. + ++In the Debian and MirBSD versions of @sc{cvs}, you can ++also specify @code{:extssh:} to force use of the Secure ++Shell, or @code{:ext=prog:} or @code{:ext=/path/to/prog:} ++to specify the remote shell to use without needing to ++touch the @code{CVS_RSH} environment variable. ++ + You may choose to specify the @var{CVS_RSH} option as a method option + in the @var{CVSROOT} string to allow you to use different connection tools + for different roots (@pxref{The connection method}). For example, allowing +@@ -2501,15 +2559,19 @@ + The @samp{--allow-root} option specifies the allowable + @sc{cvsroot} directory. Clients which attempt to use a + different @sc{cvsroot} directory will not be allowed to +-connect. If there is more than one @sc{cvsroot} +-directory which you want to allow, repeat the option. ++connect. To allow a whole class of @sc{cvsroot}, specify ++a POSIX extended regular expression to match allowed ++directories with the @samp{--allow-root-regexp} option. ++These options may be used in conjunction, and both options ++may be repeated to allow access to multiple @sc{cvsroot} ++directories and classes of directories. + (Unfortunately, many versions of @code{inetd} have very small + limits on the number of arguments and/or the total length + of the command. The usual solution to this problem is + to have @code{inetd} run a shell script which then invokes + @sc{cvs} with the necessary arguments.) + +- If your @code{inetd} wants a symbolic service ++If your @code{inetd} wants a symbolic service + name instead of a raw port number, then put this in + @file{/etc/services}: + +@@ -2675,7 +2737,7 @@ + (@code{info-cvs@@nongnu.org} or @code{bug-cvs@@nongnu.org}) if you use the + @sc{cvs} PAM support. + +-@strong{WARNING: Using PAM gives the system administrator much more ++@emph{WARNING: Using PAM gives the system administrator much more + flexibility about how @sc{cvs} users are authenticated but + no more security than other methods. See below for more.} + +@@ -2776,7 +2838,7 @@ + @cindex Login (subcommand) + @cindex Password client, using + @cindex Authenticated client, using +-@cindex :pserver:, setting up ++@cindex pserver method, setting up + To run a @sc{cvs} command on a remote repository via + the password-authenticating server, one specifies the + @code{pserver} protocol, optional username, repository host, an +@@ -2887,7 +2949,7 @@ + @c FIXME: The bit about "access to the repository + @c implies general access to the system is *not* specific + @c to pserver; it applies to kerberos and SSH and +-@c everything else too. Should reorganize the ++@c everything else too. Should reorganise the + @c documentation to make this clear. + The separate @sc{cvs} password file (@pxref{Password + authentication server}) allows people +@@ -2940,8 +3002,8 @@ + + @cindex GSSAPI + @cindex Security, GSSAPI +-@cindex :gserver:, setting up +-@cindex Kerberos, using :gserver: ++@cindex gserver method, setting up ++@cindex Kerberos, using gserver method + GSSAPI is a generic interface to network security + systems such as Kerberos 5. + If you have a working GSSAPI library, you can have +@@ -2992,9 +3054,9 @@ + @node Kerberos authenticated + @subsection Direct connection with Kerberos + +-@cindex Kerberos, using :kserver: ++@cindex Kerberos, using kserver method + @cindex Security, Kerberos +-@cindex :kserver:, setting up ++@cindex kserver method, setting up + The easiest way to use Kerberos is to use the Kerberos + @code{rsh}, as described in @ref{Connecting via rsh}. + The main disadvantage of using rsh is that all the data +@@ -3039,7 +3101,7 @@ + @subsection Connecting with fork + + @cindex fork, access method +-@cindex :fork:, setting up ++@cindex fork method, setting up + This access method allows you to connect to a + repository on your local disk via the remote protocol. + In other words it does pretty much the same thing as +@@ -3065,7 +3127,7 @@ + cvs -d :fork:/usr/local/cvsroot checkout foo + @end example + +-@cindex CVS_SERVER, and :fork: ++@cindex CVS_SERVER, and fork method + As with @code{:ext:}, the server is called @samp{cvs} + by default, or the value of the @code{CVS_SERVER} + environment variable. +@@ -3994,7 +4056,7 @@ + tag. + + @noindent +-@strong{WARNING: the commands in this section are ++@emph{WARNING: the commands in this section are + dangerous; they permanently discard historical + information and it can be difficult or impossible to + recover from errors. If you are a @sc{cvs} +@@ -4024,7 +4086,7 @@ + trigger warnings and will not be deleted. + + @noindent +-@strong{WARNING: Moving branch tags is very dangerous! If you think ++@emph{WARNING: Moving branch tags is very dangerous! If you think + you need the @code{-B} option, think again and ask your @sc{cvs} + administrator about it (if that isn't you). There is almost certainly + another way to accomplish what you want to accomplish.} +@@ -4055,7 +4117,7 @@ + name are ignored with a warning message. + + @noindent +-@strong{WARNING: Moving branch tags is very dangerous! If you think you ++@emph{WARNING: Moving branch tags is very dangerous! If you think you + need the @code{-B} option, think again and ask your @sc{cvs} + administrator about it (if that isn't you). There is almost certainly + another way to accomplish what you want to accomplish.} +@@ -4257,7 +4319,7 @@ + @c until it is ready for the main trunk. The whole + @c thing is generally speaking more akin to the + @c "Revision management" node although it isn't clear to +-@c me whether policy matters should be centralized or ++@c me whether policy matters should be centralised or + @c distributed throughout the relevant sections. + Suppose that release 1.0 of tc has been made. You are continuing to + develop tc, planning to create release 1.1 in a couple of months. After a +@@ -4904,7 +4966,7 @@ + directory need not change anything. Therefore, there + is no conflict. + +-@strong{WARNING: In versions of @sc{cvs} prior to 1.12.2, there was a ++@emph{WARNING: In versions of @sc{cvs} prior to 1.12.2, there was a + major problem with using @samp{-kk} on merges. Namely, @samp{-kk} + overrode any default keyword expansion mode set in the archive file in + the repository. This could, unfortunately for some users, cause data +@@ -5104,7 +5166,7 @@ + @file{backend.c} to the repository: + + @c This example used to specify +-@c -m "Optimizer and code generation passes." ++@c -m "Optimiser and code generation passes." + @c to the cvs add command, but that doesn't work + @c client/server (see log2 in sanity.sh). Should fix CVS, + @c but also seems strange to document things which +@@ -5266,7 +5328,7 @@ + cvs add: oj.c, version 1.1.1.1, resurrected + @end example + +-If you realize your mistake before you run the ++If you realise your mistake before you run the + @code{remove} command you can use @code{update} to + resurrect the file: + +@@ -5712,12 +5774,12 @@ + @node user-defined logging + @section User-defined logging + +-@c FIXME: probably should centralize this information ++@c FIXME: probably should centralise this information + @c here, at least to some extent. Maybe by moving the + @c loginfo, etc., nodes here and replacing + @c the "user-defined logging" node with one node for + @c each method. +-You can customize @sc{cvs} to log various kinds of ++You can customise @sc{cvs} to log various kinds of + actions, in whatever manner you choose. These + mechanisms operate by executing a script at various + times. The script might append a message to a file +@@ -5736,7 +5798,7 @@ + @samp{-o}, @samp{-e}, and @samp{-t} options in the + modules file. For a more flexible way of giving + notifications to various users, which requires less in +-the way of keeping centralized scripts up to date, use ++the way of keeping centralised scripts up to date, use + the @code{cvs watch add} command (@pxref{Getting + Notified}); this command is useful even if you are not + using @code{cvs watch on}. +@@ -5968,7 +6030,7 @@ + locks, have all developers put "edit -c", "commit -c" in their + .cvsrc file, and turn on watches in the repository. This + prevents them from doing a @code{cvs edit} if anyone is +-already editting the file. It also may ++already editing the file. It also may + be possible to use plain watches together with suitable + procedures (not enforced by software), to avoid having + two people edit at the same time. +@@ -6451,7 +6513,7 @@ + You can now go ahead and commit this as revision 1.7. + + @example +-$ cvs commit -m "Initialize scanner. Use symbolic exit values." driver.c ++$ cvs commit -m "Initialise scanner. Use symbolic exit values." driver.c + Checking in driver.c; + /usr/local/cvsroot/yoyodyne/tc/driver.c,v <-- driver.c + new revision: 1.7; previous revision: 1.6 +@@ -6630,7 +6692,7 @@ + put "edit -c" and "commit -c" into all .cvsrc files, + and make files default to read only by turning on watches + or putting "cvs -r" into all .cvsrc files. +-This prevents multiple people from editting a file at ++This prevents multiple people from editing a file at + the same time (unless explicitly overriden with @samp{-f}). + + @c I'm a little dissatisfied with this presentation, +@@ -6875,7 +6937,7 @@ + There are two additional options that @code{cvs edit} understands as of + @sc{cvs} client and server versions 1.12.10 but @code{cvs watch} does not. + The first is @code{-c}, which causes @code{cvs edit} to fail if anyone else +-is editting the file. This is probably only useful when @samp{edit -c} and ++is editing the file. This is probably only useful when @samp{edit -c} and + @samp{commit -c} are specified in all developers' @file{.cvsrc} files. This + behavior may be overriden this via the @code{-f} option, which overrides + @code{-c} and allows multiple edits to succeed. +@@ -6992,7 +7054,7 @@ + cons. Let it be said that a lot of this is a matter of + opinion or what works given different groups' working + styles, but here is a brief description of some of the +-issues. There are many ways to organize a team of ++issues. There are many ways to organise a team of + developers. @sc{cvs} does not try to enforce a certain + organization. It is a tool that can be used in several + ways. +@@ -7014,7 +7076,7 @@ + many groups is that they occur rarely and usually are + relatively straightforward to resolve. + +-The rarity of serious conflicts may be surprising, until one realizes ++The rarity of serious conflicts may be surprising, until one realises + that they occur only when two developers disagree on the proper design + for a given section of code; such a disagreement suggests that the + team has not been communicating properly in the first place. In order +@@ -7182,6 +7244,15 @@ + @item $@splitrcskeyword{Date}$ + The date and time (UTC) the revision was checked in. + ++@cindex Mdocdate keyword ++@item $@splitrcskeyword{Mdocdate}$ ++The date (UTC) the revision was checked in, in a format suitable ++for the Berkeley mdoc macro processing. ++ ++@example ++$Mdocdate: January 30 2021 $ ++@end example ++ + @cindex Header keyword + @item $@splitrcskeyword{Header}$ + A standard header containing the full pathname of the +@@ -7243,7 +7314,8 @@ + but for several reasons it can be problematic. + + If the prefix of the @code{$@splitrcskeyword{Log}$} keyword turns out to be +-longer than @code{MaxCommentLeaderLength}, CVS will skip expansion of this ++longer than the @file{CVSROOT/config} setting @code{MaxCommentLeaderLength}, ++CVS will skip expansion of this + keyword unless @code{UseArchiveCommentLeader} is also set in + @file{CVSROOT/config} and a @samp{comment leader} is set in the RCS archive + file, in which case the comment leader will be used instead. For more on +@@ -7336,7 +7408,7 @@ + the source files so that it gets passed through to + generated files. For example, if you are managing + computer program source code, you might include a +-variable which is initialized to contain that string. ++variable which is initialised to contain that string. + Or some C compilers may provide a @code{#pragma ident} + directive. Or a document management system might + provide a way to pass a string through to generated +@@ -7550,13 +7622,14 @@ + A list may be used. The this example: + + @example +- # Add a "MyBSD" keyword and restrict keyword +- # expansion to the MyBSD, Name and Date keywords. ++ # Add a "MyBSD" keyword and restrict keyword expansion ++ # to the MyBSD, Name, Date and Mdocdate keywords. + LocalKeyword=MyBSD=CVSHeader +- KeywordExpand=iMyBSD,Name,Date ++ KeywordExpand=iMyBSD,Name,Date,Mdocdate + @end example + +-would allow $@splitrcskeyword{MyBSD}$, $@splitrcskeyword{Name}$, and ++would allow $@splitrcskeyword{MyBSD}$, $@splitrcskeyword{Name}$, ++$@splitrcskeyword{Mdocdate} and + $@splitrcskeyword{Date}$ to be expanded. + + It is also possible to configure an exclusion list +@@ -7595,7 +7668,7 @@ + has been around a long time. However, that patch + implemented these features using @code{tag=} and + @code{tagexpand=} keywords and those keywords are NOT +-recognized. ++recognised. + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @node Log keyword +@@ -7742,7 +7815,7 @@ + $ cvs import -m "Import of FSF v. 0.05" fsf/wdiff FSF_DIST WDIFF_0_05 + @end example + +-@strong{WARNING: If you use a release tag that already exists in one of the ++@emph{WARNING: If you use a release tag that already exists in one of the + repository archives, files removed by an import may not be detected.} + + For files that have not been modified locally, the newly created +@@ -7786,7 +7859,12 @@ + + You can also revert local changes completely and return + to the latest vendor release by changing the `head' +-revision back to the vendor branch on all files. For ++revision back to the vendor branch on all files. This ++does, however, produce weird results if you should ever ++edit this file again, for anyone looking at the output ++from the @code{log} command or CVSweb. To fix this, ++first commit a revision of the file which equals the ++vendor branch, then use @code{admin} @samp{-b}. For + example, if you have a checked-out copy of the sources + in @file{~/work.d/wdiff}, and you want to revert to the + vendor's version for all the files in that directory, +@@ -7853,6 +7931,10 @@ + @code{cvs import}. It takes as an argument the vendor + branch to import to. The default is @samp{-b 1.1.1}. + ++Vendor branches can only be in the format 1.1.x where ++@samp{x} is an @emph{uneven} number, because branch ++tags use even numbers. ++ + For example, suppose that there are two teams, the red + team and the blue team, that are sending you sources. + You want to import the red team's efforts to branch +@@ -8030,7 +8112,7 @@ + + When @code{PreservePermissions} is in use, some @sc{cvs} + operations (such as @samp{cvs status}) will not +-recognize a file's hard link structure, and so will ++recognise a file's hard link structure, and so will + emit spurious warnings about mismatching hard links. + The reason is that @sc{cvs}'s internal structure does not + make it easy for these operations to collect all the +@@ -8094,16 +8176,18 @@ + This appendix describes the overall structure of + @sc{cvs} commands, and describes some commands in + detail (others are described elsewhere; for a quick +-reference to @sc{cvs} commands, @pxref{Invoking CVS}). ++reference to @sc{cvs} commands, @pxref{Invoking CVS}, ++and for an alphabetical list of all @sc{cvs} commands, ++@pxref{CVS command list}). + @c The idea is that we want to move the commands which + @c are described here into the main body of the manual, + @c in the process reorganizing the manual to be +-@c organized around what the user wants to do, not +-@c organized around CVS commands. ++@c organised around what the user wants to do, not ++@c organised around CVS commands. + @c + @c Note that many users do expect a manual which is +-@c organized by command. At least some users do. +-@c One good addition to the "organized by command" ++@c organised by command. At least some users do. ++@c One good addition to the "organised by command" + @c section (if any) would be "see also" links. + @c The awk manual might be a good example; it has a + @c reference manual which is more verbose than Invoking +@@ -8117,19 +8201,20 @@ + * Global options:: Options you give to the left of cvs_command + * Common options:: Options you give to the right of cvs_command + * Date input formats:: Acceptable formats for date specifications +-* admin:: Administration ++* admin:: Administration front-end for RCS + * annotate:: What revision modified each line of a file? + * checkout:: Checkout sources for editing + * commit:: Check files into the repository + * diff:: Show differences between revisions + * export:: Export sources from CVS, similar to checkout +-* history:: Show status of files and users ++* history:: Show repository access history + * import:: Import sources into CVS, using vendor branches +-* log:: Show log messages for files ++* log:: Print out history information for files + * ls & rls:: List files in the repository +-* rdiff:: 'patch' format diffs between releases ++* rdiff:: Create 'patch' format diffs between revisions + * release:: Indicate that a directory is no longer in use + * server & pserver:: Act as a server for a client on stdin/stdout ++* suck:: Download RCS ,v file raw + * update:: Bring work tree in sync with repository + @end menu + +@@ -8375,6 +8460,31 @@ + @samp{-N} in the @file{~/.cvsrc} entry for @samp{log}, + you may need to use @samp{-f} to show the tag names. + ++@item -g ++Forges group-writable permissions on files in the working copy. ++This option is typically used when you have multiple users sharing ++a single checked out source tree, allowing them to operate their ++shells with a less dangerous umask at the expense of @sc{cvs} security. ++To use this feature, create a directory to hold the checked-out ++source tree, set it to a private group, and set up the directory ++such that files created under it inherit the gid of the directory. ++On BSD systems, this occurs automatically. On SYSV systems and ++GNU/Linux, the sgid bit must be set on the directory for this. ++The users who are to share the checked out tree must be placed in ++that group which owns the directory. ++ ++Note that the sharing of a single checked-out source tree is very ++different from giving several users access to a common @sc{cvs} repository. ++Access to a common @sc{cvs} repository already maintains shared group-write ++permissions and does not require this option. ++ ++Due to the security implications, setting this option globally in ++your @file{.cvsrc} file is strongly discouraged; if you must, ensure ++all source checkouts are "firewalled" within a private group or a ++private mode 0700 directory. ++ ++This option is a MidnightBSD extension merged into Debian and MirBSD @sc{cvs}. ++ + @item -H + @itemx --help + Display usage information about the specified @samp{cvs_command} +@@ -8498,7 +8608,7 @@ + which are listed with the individual commands, may have + different behavior from one @sc{cvs} command to the other). + +-@strong{Note: the @samp{history} command is an exception; it supports ++@emph{Note: the @samp{history} command is an exception; it supports + many options that conflict even with these standard options.} + + @table @code +@@ -8523,7 +8633,7 @@ + slightly different way; @pxref{history options}). + + For a complete description of the date formats accepted by @sc{cvs}, +-@ref{Date input formats}. ++@pxref{Date input formats}. + @c What other formats should we accept? I don't want + @c to start accepting a whole mess of non-standard + @c new formats (there are a lot which are in wide use in +@@ -8610,7 +8720,7 @@ + @code{annotate}, @code{checkout}, @code{export}, + @code{rdiff}, @code{rtag}, and @code{update}. + +-@strong{WARNING: The @code{commit} and @code{remove} ++@emph{WARNING: The @code{commit} and @code{remove} + commands also have a + @samp{-f} option, but it has a different behavior for + those commands. See @ref{commit options}, and +@@ -8631,7 +8741,7 @@ + @code{checkout}, @code{diff}, @code{export}, @code{import}, + @code{rdiff}, and @code{update} commands. + +-@strong{WARNING: Prior to CVS version 1.12.2, the @samp{-k} flag ++@emph{WARNING: Prior to CVS version 1.12.2, the @samp{-k} flag + overrode the @samp{-kb} indication for a binary file. This could + sometimes corrupt binary files. @xref{Merging and keywords}, for + more.} +@@ -8660,7 +8770,7 @@ + specified to run in the modules + database (@pxref{modules}); this option bypasses it). + +-@strong{Note: this is not the same as the @samp{cvs -n} ++@emph{Note: this is not the same as the @samp{cvs -n} + program option, which you can specify to the left of a cvs command!} + + Available with the @code{checkout}, @code{commit}, @code{export}, +@@ -8688,14 +8798,21 @@ + @item -r @var{tag}[:@var{date}] + @cindex HEAD, special tag + @cindex BASE, special tag ++@cindex BASE, special date + Use the revision specified by the @var{tag} argument (and the @var{date} + argument for the commands which accept it) instead of the + default @dfn{head} revision. As well as arbitrary tags defined + with the @code{tag} or @code{rtag} command, two special tags are + always available: @samp{HEAD} refers to the most recent version +-available in the repository, and @samp{BASE} refers to the ++available in the repository (also known as the tip of the @samp{MAIN} ++branch, also known as trunk; the name of a branch refers to its tip; ++this version of @sc{cvs} introduces @samp{.bhead}, but only for the ++@sc{diff} command, for the same), and @samp{BASE} refers to the + revision you last checked out into the current working directory. + ++@c fixed: HEAD is changed now; .bhead is the name of the branch, ++@c but added for cases where it is unknown. ++@c --mirabilos + @c FIXME: What does HEAD really mean? I believe that + @c the current answer is the head of the default branch + @c for all cvs commands except diff. For diff, it +@@ -8735,12 +8852,19 @@ + the name of a branch is interpreted as the most recent + revision on that branch. + ++As a Debian and MirBSD @sc{cvs} extension, specifying @samp{BASE} as the ++@var{date} portion of the argument yields the @emph{base revision} of the ++branch specified by the @var{tag} portion of the argument, i.e. the revision ++on the parent branch the @var{tag} branch split off, or, where both ++branches were the same. ++This option has not received very much testing, beware! ++ + Specifying the @samp{-q} global option along with the + @samp{-r} command option is often useful, to suppress + the warning messages when the @sc{rcs} file + does not contain the specified tag. + +-@strong{Note: this is not the same as the overall @samp{cvs -r} option, ++@emph{Note: this is not the same as the overall @samp{cvs -r} option, + which you can specify to the left of a @sc{cvs} command!} + + @samp{-r @var{tag}} is available with the @code{commit} and @code{history} +@@ -8764,8 +8888,8 @@ + @include getdate-cvs.texi + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node admin +-@appendixsec admin---Administration ++@node admin, annotate, Date input formats, CVS commands ++@appendixsec admin---Administration front-end for RCS + @cindex Admin (subcommand) + + @itemize @bullet +@@ -8863,7 +8987,7 @@ + a future release of @sc{cvs}. + + @item -i +-Useless with @sc{cvs}. This creates and initializes a ++Useless with @sc{cvs}. This creates and initialises a + new @sc{rcs} file, without depositing a revision. With + @sc{cvs}, add files with the @code{cvs add} command + (@pxref{Adding files}). +@@ -9129,13 +9253,16 @@ + @end table + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node annotate ++@node annotate, checkout, admin, CVS commands + @appendixsec annotate---What revision modified each line of a file? + @cindex annotate (subcommand) + + @itemize @bullet + @item +-Synopsis: annotate [options] files@dots{} ++Synopsis: ++annotate [options] files@dots{} ++ ++rannotate [options] files@dots{} + @item + Requires: repository. + @item +@@ -9144,7 +9271,10 @@ + + For each file in @var{files}, print the head revision + of the trunk, together with information on the last +-modification for each line. ++modification for each line. If backwards annotation ++is requested, show the first modification after the ++specified revision. (Backwards annotation currently ++appears to be broken.) + + @menu + * annotate options:: annotate options +@@ -9160,6 +9290,10 @@ + them): + + @table @code ++@item -b ++Backwards, show when a line was removed. ++Currently appears to be broken. ++ + @item -l + Local directory only, no recursion. + +@@ -9215,7 +9349,7 @@ + @c changed this line *before* 1.4"...). + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node checkout ++@node checkout, commit, annotate, CVS commands + @appendixsec checkout---Check out sources for editing + @cindex checkout (subcommand) + @cindex co (subcommand) +@@ -9449,14 +9583,13 @@ + @end example + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node commit ++@node commit, diff, checkout, CVS commands + @appendixsec commit---Check files into the repository + @cindex commit (subcommand) + + @itemize @bullet + @item +-Synopsis: commit [-lnRf] [-m 'log_message' | +--F file] [-r revision] [files@dots{}] ++Synopsis: commit [-lnRf] [-m 'log_message' | -F file] [-r revision] [files@dots{}] + @item + Requires: working directory, repository. + @item +@@ -9501,8 +9634,11 @@ + + At @code{commit}, a unique commitid is placed in the @sc{rcs} + file inside the repository. All files committed at once +-get the same commitid. The commitid can be retrieved with +-the @code{log} and @code{status} command; see @ref{log}, ++get the same commitid, a string consisting only of hexadecimal ++digits (usually 16 in GNU @sc{cvs}, 19 in Debian and MirBSD @sc{cvs}). ++FSF GNU @sc{cvs} 1.11 and OpenBSD OpenCVS do not support commitids yet. ++The commitid can be retrieved with ++the @code{log} and @code{status} command; see @ref{log} and + @ref{File status}. + + @menu +@@ -9621,7 +9757,7 @@ + group would like to work on this software with you, but + without disturbing main-line development, you could + commit your change to a new branch. Others can then +-checkout your experimental stuff and utilize the full ++checkout your experimental stuff and utilise the full + benefit of @sc{cvs} conflict resolution. The scenario might + look like: + +@@ -9662,7 +9798,7 @@ + @end example + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node diff ++@node diff, export, commit, CVS commands + @appendixsec diff---Show differences between revisions + @cindex diff (subcommand) + +@@ -9685,7 +9821,7 @@ + under them will be compared. + + The exit status for diff is different than for other +-@sc{cvs} commands; for details @ref{Exit status}. ++@sc{cvs} commands; for details @pxref{Exit status}. + + @menu + * diff options:: diff options +@@ -10295,7 +10431,7 @@ + @end example + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node export ++@node export, history, diff, CVS commands + @appendixsec export---Export sources from CVS, similar to checkout + @cindex export (subcommand) + +@@ -10393,8 +10529,8 @@ + @end ignore + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node history +-@appendixsec history---Show status of files and users ++@node history, import, export, CVS commands ++@appendixsec history---Show repository access history + @cindex history (subcommand) + + @itemize @bullet +@@ -10425,7 +10561,7 @@ + (@file{$CVSROOT/CVSROOT/history}) with read and write permissions for all + users (@pxref{Creating a repository}). + +-@strong{Note: @code{history} uses @samp{-f}, @samp{-l}, ++@emph{Note: @code{history} uses @samp{-f}, @samp{-l}, + @samp{-n}, and @samp{-p} in ways that conflict with the + normal use inside @sc{cvs} (@pxref{Common options}).} + +@@ -10587,7 +10723,7 @@ + @end ignore + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node import ++@node import, log, history, CVS commands + @appendixsec import---Import sources into CVS, using vendor branches + @cindex import (subcommand) + +@@ -10721,9 +10857,9 @@ + the new file is @code{dead}, resetting the new file's default branch, + and placing the file in the Attic (@pxref{Attic}) directory. + +-Use of this option can be forced on a repository-wide basis +-by setting the @samp{ImportNewFilesToVendorBranchOnly} option in +-CVSROOT/config (@pxref{config}). ++Setting the @samp{ImportNewFilesToVendorBranchOnly} option in ++CVSROOT/config (@pxref{config}) forces use of this option on ++a repository-wide basis. + @end table + + @c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +@@ -10773,13 +10909,15 @@ + See @ref{Tracking sources}, and @ref{From files}. + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node log +-@appendixsec log---Print out log information for files ++@node log, ls & rls, import, CVS commands ++@appendixsec log---Print out history information for files + @cindex log (subcommand) + + @itemize @bullet + @item + Synopsis: log [options] [files@dots{}] ++ ++rlog [options] [files@dots{}] + @item + Requires: repository, working directory. + @item +@@ -10805,7 +10943,7 @@ + the @code{$TZ} environment variable, which can be set to + govern how @code{log} displays dates. + +-@strong{Note: @code{log} uses @samp{-R} in a way that conflicts ++@emph{Note: @code{log} uses @samp{-R} in a way that conflicts + with the normal use inside @sc{cvs} (@pxref{Common options}).} + + @menu +@@ -10997,13 +11135,15 @@ + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @node ls & rls +-@appendixsec ls & rls ++@appendixsec ls & rls---List files in the repository + @cindex ls (subcommand) + @cindex rls (subcommand) + + @itemize @bullet + @item + ls [-e | -l] [-RP] [-r tag[:date]] [-D date] [path@dots{}] ++ ++rls [-e | -l] [-RP] [-r tag[:date]] [-D date] [path@dots{}] + @item + Requires: repository for @code{rls}, repository & working directory for + @code{ls}. +@@ -11094,8 +11234,8 @@ + @end example + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node rdiff +-@appendixsec rdiff---'patch' format diffs between releases ++@node rdiff, release, ls & rls, CVS commands ++@appendixsec rdiff---Create 'patch' format diffs between revisions + @cindex rdiff (subcommand) + + @itemize @bullet +@@ -11173,6 +11313,9 @@ + @item -c + Use the context diff format. This is the default format. + ++@item -p ++Show which C function each change is in. ++ + @item -s + Create a summary change report instead of a patch. The + summary includes information about files that were +@@ -11230,8 +11373,8 @@ + @end example + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node release +-@appendixsec release---Indicate that a Module is no longer in use ++@node release, server & pserver, rdiff, CVS commands ++@appendixsec release---Indicate that a directory is no longer in use + @cindex release (subcommand) + + @itemize @bullet +@@ -11282,7 +11425,7 @@ + succeeds. If this flag is not given your files will + remain in your working directory. + +-@strong{WARNING: The @code{release} command deletes ++@emph{WARNING: The @code{release} command deletes + all directories and files recursively. This + has the very serious side-effect that any directory + that you have created inside your checked-out sources, +@@ -11379,14 +11522,33 @@ + @cindex configuration file + @table @code + @item -c path +-Load configuration from @var{path} rather than the default location +-@file{$CVSROOT/CVSROOT/config} (@pxref{config}). @var{path} must be +-@file{/etc/cvs.conf} or prefixed by @file{/etc/cvs/}. This option is +-supported beginning with @sc{cvs} release 1.12.13. ++Load configuration from the given @var{path} rather than from the ++default location @file{$CVSROOT/CVSROOT/config} (@pxref{config}). ++@var{path} must be @file{/etc/cvs.conf} or prefixed by @file{/etc/cvs/}. ++This option is supported beginning with @sc{cvs} release 1.12.13. + @end table + + @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-@node update ++@node suck, update, server & pserver, CVS commands ++@appendixsec suck---Download RCS ,v file raw ++@cindex suck (subcommand) ++ ++@itemize @bullet ++@item ++suck module/pa/th ++@item ++Requires: repository ++@end itemize ++ ++Locates the file module/pa/th,v or module/pa/Attic/th,v and downloads ++it raw as RCS comma-v file. ++ ++Output consists of the real pathname of the comma-v file, relative to ++the CVS repository, followed by a newline and the binary file content ++immediately thereafter. ++ ++@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ++@node update, , suck, CVS commands + @appendixsec update---Bring work tree in sync with repository + @cindex update (subcommand) + +@@ -11635,6 +11797,8 @@ + references to where each command or feature is + described in detail. For other references run the + @code{cvs --help} command, or see @ref{Index}. ++For an alphabetical list of all @sc{cvs} commands, ++@pxref{CVS command list}). + + A @sc{cvs} command looks like: + +@@ -11646,10 +11810,15 @@ + + @table @code + @item --allow-root=@var{rootdir} +-Specify legal @sc{cvsroot} directory (server only) (not +-in @sc{cvs} 1.9 and older). See @ref{Password ++Specify acceptable @sc{cvsroot} directory (server only). ++Appeared in @sc{cvs} 1.10. See @ref{Password + authentication server}. + ++@item --allow-root-regexp=@var{rootdir} ++Specify a POSIX extended regular expression which matches acceptable ++@sc{cvsroot} directories (server only). Appeared in @sc{cvs} ++1.12.14. See @ref{Password authentication server}. ++ + @item -a + Authenticate all communication (client only) (not in @sc{cvs} + 1.9 and older). See @ref{Global options}. +@@ -11669,6 +11838,10 @@ + Do not read the @file{~/.cvsrc} file. See @ref{Global + options}. + ++@item -g ++Set the umask to allow group writable permissions in ++the working copy. See @ref{Global options}. ++ + @item -H + @itemx --help + Print a help message. See @ref{Global options}. +@@ -11730,6 +11903,7 @@ + @example + $@splitrcskeyword{Author}: joe $ + $@splitrcskeyword{Date}: 1993/12/09 03:21:13 $ ++$@splitrcskeyword{Mdocdate}: December 9 1993 $ + $@splitrcskeyword{CVSHeader}: files/file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $ + $@splitrcskeyword{Header}: /home/files/file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $ + $@splitrcskeyword{Id}: file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $ +@@ -11756,6 +11930,7 @@ + + @table @code + @c ------------------------------------------------------------ ++@anchor{add} + @item add [@var{options}] [@var{files}@dots{}] + Add a new file/directory. See @ref{Adding files}. + +@@ -11877,7 +12052,8 @@ + @item -j @var{tag}[:@var{date}] + Merge in the change specified by @var{tag}, or when @var{date} is specified + and @var{tag} is a branch tag, the version from the branch @var{tag} as it +-existed on @var{date}. See @ref{checkout options}. ++existed on @var{date}. See @ref{checkout options}. Also, ++see @ref{Common options}. + + @item -k @var{kflag} + Use @var{kflag} keyword expansion. See +@@ -11907,7 +12083,7 @@ + @item -r @var{tag}[:@var{date}] + Checkout the revision already tagged with @var{tag} or, when @var{date} is + specified and @var{tag} is a branch tag, the version from the branch @var{tag} +-as it existed on @var{date}. This . See @ref{Common options}. ++as it existed on @var{date}. See @ref{Common options}. + + @item -s + Like -c, but include module status. See @ref{checkout options}. +@@ -11992,6 +12168,7 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{edit} + @item edit [@var{options}] [@var{files}@dots{}] + Get ready to edit a watched file. See @ref{Editing files}. + +@@ -12003,7 +12180,7 @@ + @ref{Editing files}. + + @item -c +-Check edits: Edit fails if someone else is already editting the file. ++Check edits: Edit fails if someone else is already editing the file. + Requires a @sc{cvs} client and server both of version 1.12.10 or greater. + + @item -f +@@ -12018,6 +12195,7 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{editors} + @item editors [@var{options}] [@var{files}@dots{}] + See who is editing a watched file. See @ref{Watch information}. + +@@ -12163,14 +12341,17 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{init} + @item init + Create a @sc{cvs} repository if it doesn't exist. See + @ref{Creating a repository}. + + @c ------------------------------------------------------------ ++@anchor{kserver} + @item kserver + Kerberos authenticated server. +-See @ref{Kerberos authenticated}. ++@xref{server & pserver}. ++@xref{Kerberos authenticated}. + + @c ------------------------------------------------------------ + @item log [@var{options}] [@var{files}@dots{}] +@@ -12211,21 +12392,55 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{login} + @item login + Prompt for password for authenticating server. See + @ref{Password authentication client}. + + @c ------------------------------------------------------------ ++@anchor{logout} + @item logout + Remove stored password for authenticating server. See + @ref{Password authentication client}. + + @c ------------------------------------------------------------ ++@anchor{ls} ++@item ls [@var{options}] [@var{path}@dots{}] ++List files available from CVS. See @ref{ls & rls}. ++ ++@table @code ++@item -d ++Show dead revisions (with tag when specified). ++See @ref{ls & rls options}. ++ ++@item -e ++Display in CVS/Entries format. ++ ++@item -l ++Display all details. ++ ++@item -P ++Prune empty directories. See @ref{Moving directories}. ++ ++@item -R ++List recursively. @xref{Recursive behavior}. ++ ++@item -D @var{date} ++Show files from date. See @ref{Common options}. ++ ++@item -r @var{rev} ++Show files with revision or tag. ++@end table ++ ++@c ------------------------------------------------------------ ++@anchor{pserver} + @item pserver + Password authenticated server. +-See @ref{Password authentication server}. ++@xref{server & pserver}. ++@xref{Password authentication server}. + + @c ------------------------------------------------------------ ++@anchor{rannotate} + @item rannotate [@var{options}] [@var{modules}@dots{}] + Show last revision where each line was modified. See + @ref{annotate}. +@@ -12298,7 +12513,7 @@ + @end table + + @c ------------------------------------------------------------ +-@item release [@var{options}] @var{directory} ++@item release [@var{options}] @var{directories}@dots{} + Indicate that a directory is no longer in use. See + @ref{release}. + +@@ -12308,6 +12523,7 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{remove} + @item remove [@var{options}] [@var{files}@dots{}] + Remove an entry from the repository. See @ref{Removing files}. + +@@ -12324,6 +12540,7 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{rlog} + @item rlog [@var{options}] [@var{files}@dots{}] + Print out history information for modules. See @ref{log}. + +@@ -12361,9 +12578,40 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{rls} ++@item rls [@var{options}] [@var{path}@dots{}] ++List files in a module. See @ref{ls & rls}. ++ ++@table @code ++@item -d ++Show dead revisions (with tag when specified). ++See @ref{ls & rls options}. ++ ++@item -e ++Display in CVS/Entries format. ++ ++@item -l ++Display all details. ++ ++@item -P ++Prune empty directories. See @ref{Moving directories}. ++ ++@item -R ++List recursively. @xref{Recursive behavior}. ++ ++@item -D @var{date} ++Show files from date. See @ref{Common options}. ++ ++@item -r @var{rev} ++Show files with revision or tag. ++@end table ++ ++@c ------------------------------------------------------------ ++@anchor{rtag} + @item rtag [@var{options}] @var{tag} @var{modules}@dots{} + Add a symbolic tag to a module. +-See @ref{Revisions} and @ref{Branching and merging}. ++@xref{Tagging by date/tag}. ++@xref{Creating a branch}. + + @table @code + @item -a +@@ -12407,10 +12655,18 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{server} + @item server +-Rsh server. See @ref{Connecting via rsh}. ++SSH/rsh server. ++@xref{server & pserver}. ++@xref{Connecting via rsh}. + + @c ------------------------------------------------------------ ++@item suck @var{module/filename} ++Download RCS ,v file raw. See @ref{suck}. ++ ++@c ------------------------------------------------------------ ++@anchor{status} + @item status [@var{options}] @var{files}@dots{} + Display status information in a working directory. See + @ref{File status}. +@@ -12427,9 +12683,11 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{tag} + @item tag [@var{options}] @var{tag} [@var{files}@dots{}] + Add a symbolic tag to checked out version of files. +-See @ref{Revisions} and @ref{Branching and merging}. ++@xref{Tagging the working directory}. ++@xref{Creating a branch}. + + @table @code + @item -b +@@ -12465,6 +12723,7 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{unedit} + @item unedit [@var{options}] [@var{files}@dots{}] + Undo an edit command. See @ref{Editing files}. + +@@ -12541,6 +12800,7 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{version} + @item version + @cindex version (subcommand) + +@@ -12548,6 +12808,7 @@ + is remote, display both the client and server versions. + + @c ------------------------------------------------------------ ++@anchor{watch} + @item watch [on|off|add|remove] [@var{options}] [@var{files}@dots{}] + + on/off: turn on/off read-only checkouts of files. See +@@ -12572,6 +12833,7 @@ + @end table + + @c ------------------------------------------------------------ ++@anchor{watchers} + @item watchers [@var{options}] [@var{files}@dots{}] + See who is watching a file. See @ref{Watch information}. + +@@ -12711,7 +12973,7 @@ + @item @var{mname} [ options ] @var{dir} [ @var{files}@dots{} ] + In the simplest case, this form of module definition + reduces to @samp{@var{mname} @var{dir}}. This defines +-all the files in directory @var{dir} as module mname. ++all the files in directory @var{dir} as module @var{mname}. + @var{dir} is a relative path (from @code{$CVSROOT}) to a + directory of source in the source repository. In this + case, on checkout, a single directory called +@@ -12934,7 +13196,7 @@ + @sc{cvs} will execute this program on the server from a temporary + directory. The path is searched for this program. + +-If using ``local access'' (on a local or remote NFS file system, i.e. ++If using ``local access'' (on a local or remote NFS filesystem, i.e. + repository set just to a path), + the program will be executed from the newly checked-out tree, if + found there, or alternatively searched for in the path if not. +@@ -12975,7 +13237,7 @@ + mechanisms outside @sc{cvs}, to insert any necessary + changes. + +-@strong{WARNING: do not use @code{COPY} with ++@emph{WARNING: do not use @code{COPY} with + @sc{cvs} 1.9 or earlier - such versions of @sc{cvs} will + copy one version of your file over the other, wiping + out the previous contents.} +@@ -13292,7 +13554,7 @@ + @file{module}: + + @example +-^module\(/\|$\) (echo; echo %p; echo %@{sVv@}; cat) >>$CVSROOT/CVSROOT/commitlog ++^module\(/\|$\) (echo; echo %p: %@{sVv@}; cat) >>$CVSROOT/CVSROOT/commitlog + @end example + + Using this same line and assuming a commit of new revisions +@@ -13353,7 +13615,7 @@ + + There are three kinds of programs that can be run on + commit. They are specified in files in the repository, +-as described below. The following table summarizes the ++as described below. The following table summarises the + file names and the purpose of the corresponding + programs. + +@@ -13466,10 +13728,10 @@ + your @file{loginfo} command line templates, you will most likely have to + rewrite any scripts called by the hook to handle the new argument format. + +-Also note that the way @samp{%} followed by unrecognized characters and by ++Also note that the way @samp{%} followed by unrecognised characters and by + @samp{@{@}} was treated in past versions of CVS is not strictly adhered to as + there were bugs in the old versions. Specifically, @samp{%@{@}} would eat the +-next character and unrecognized strings resolved only to the empty string, ++next character and unrecognised strings resolved only to the empty string, + which was counter to what was stated in the documentation. This version will + do what the documentation said it should have (if you were using only some + combination of @samp{%@{sVv@}}, e.g. @samp{%@{sVv@}}, @samp{%@{sV@}}, or +@@ -13749,7 +14011,7 @@ + + The @file{loginfo} file is used to control where log information is sent after + versioned changes are made to repository archive files and after directories +-are added ot the repository. @ref{posttag} for how to log tagging ++are added to the repository. @ref{posttag} for how to log tagging + information and @ref{postadmin} for how to log changes due to the @code{admin} + command. + +@@ -13779,14 +14041,11 @@ + @file{loginfo} supports: + + @table @t +-@item @{stVv@} ++@item @{sVv@} + File attributes, where: + @table @t + @item s + file name +-@item T +-tag name of destination, or the empty string when there is no associated +-tag name (this usually means the trunk) + @item V + old version number (pre-checkin) + @item v +@@ -13795,7 +14054,7 @@ + @end table + + For example, some valid format strings are @samp{%%}, +-@samp{%s}, @samp{%@{s@}}, and @samp{%@{stVv@}}. ++@samp{%s}, @samp{%@{s@}}, and @samp{%@{sVv@}}. + + @cindex loginfo (admin file), updating legacy repositories + @cindex compatibility notes, loginfo admin file +@@ -13843,9 +14102,9 @@ + @c directory, it is kind of awkward if + @c only the first matching line is used. + @example +-ALL /usr/local/bin/cvs-log $CVSROOT/CVSROOT/commitlog $USER +-^CVSROOT\(/\|$\) /usr/local/bin/cvs-log /usr/adm/cvsroot-log $USER +-^prog1\(/\|$\) Mail -s "%p %s" ceder ++ALL /usr/local/bin/cvs-log $CVSROOT/CVSROOT/commitlog $USER ++^CVSROOT\(/\|$\) /usr/local/bin/cvs-log /usr/adm/cvsroot-log $USER ++^prog1\(/\|$\) Mail -s "%p %s" ceder + @end example + + The shell-script @file{/usr/local/bin/cvs-log} looks +@@ -14210,7 +14469,7 @@ + + @itemize @bullet + @item +-The list is initialized to include certain file name ++The list is initialised to include certain file name + patterns: names associated with @sc{cvs} + administration, or with other common source control + systems; common names for patch files, object files, +@@ -14378,7 +14637,7 @@ + the server machine, and don't get any reasonable + expansion if pserver (@pxref{Password authenticated}) + is in use; therefore user variables (see below) may be +-a better choice to customize behavior based on the user ++a better choice to customise behavior based on the user + running @sc{cvs}. + @c Based on these limitations, should we deprecate ~? + @c What is it good for? Are people using it? +@@ -14442,6 +14701,7 @@ + random string of printable characters of at least 16 + characters length. Users should assume that it may + someday grow to at most 256 characters in length. ++Currently, Debian and MirBSD @sc{cvs} uses 19 characters. + @end table + + If you want to pass a value to the administrative files +@@ -14613,7 +14873,7 @@ + @cindex KeywordExpand, in CVSROOT/config + @item KeywordExpand=@var{value} + Specify @samp{i} followed by a list of keywords to be expanded +-(for example, @samp{KeywordExpand=iMYCVS,Name,Date}), ++(for example, @samp{KeywordExpand=iMYCVS,Name,Date,Mdocdate}), + or @samp{e} followed by a list of keywords not to be expanded + (for example, @samp{KeywordExpand=eCVSHeader}). + For more on keyword expansion, see @ref{Configuring keyword expansion}. +@@ -14621,8 +14881,8 @@ + @cindex LocalKeyword, in CVSROOT/config + @item LocalKeyword=@var{value} + Specify a local alias for a standard keyword. +-For example, @samp{LocalKeyword=MYCVS=CVSHeader}. +-For more on local keywords, see @ref{Keyword substitution}. ++See @ref{Keyword substitution} for more information in local keywords. ++Example: @samp{LocalKeyword=MYCVS=CVSHeader} + + @cindex LockDir, in CVSROOT/config + @item LockDir=@var{directory} +@@ -14632,7 +14892,7 @@ + write access only to @var{directory}, not to the + repository. + It can also be used to put the locks on a very fast +-in-memory file system to speed up locking and unlocking ++in-memory filesystem to speed up locking and unlocking + the repository. + You need to create @var{directory}, but + @sc{cvs} will create subdirectories of @var{directory} as it +@@ -14657,7 +14917,9 @@ + Default of @samp{TOEFWUPCGMAR} (or simply @samp{all}) will log + all transactions. Any subset of the default is + legal. (For example, to only log transactions that modify the +-@file{*,v} files, use @samp{LogHistory=TMAR}.) To disable history logging ++@file{*,v} files, use @samp{LogHistory=TMAR} which is nowadays ++set by @code{cvs init} by default.) ++To disable history logging + completely, use @samp{LogHistory=}. + + @cindex MaxCommentLeaderLength, in CVSROOT/config +@@ -14743,11 +15005,11 @@ + the log message should always be reread; @samp{no} + or @samp{never}, indicating that it should never be + reread; or @var{value} may be @samp{stat}, indicating +-that the file should be checked with the file system ++that the file should be checked with the filesystem + @samp{stat()} function to see if it has changed (see warning below) + before rereading. The default value is @samp{always}. + +-@strong{Note: the `stat' mode can cause CVS to pause for up to ++@emph{Note: the `stat' mode can cause CVS to pause for up to + one extra second per directory committed. This can be less IO and + CPU intensive but is not recommended for use with large repositories} + +@@ -14879,11 +15141,12 @@ + check out from a read-only repository, such as within + an anoncvs server, or from a @sc{cd-rom} repository. + +-It has the same effect as if the @samp{-R} command-line ++Setting this has the same effect as if the @samp{-R} command-line + option is used. This can also allow the use of + read-only NFS repositories. + + @item $CVSUMASK ++@anchor{CVSUMASK} + Controls permissions of files in the repository. See + @ref{File permissions}. + +@@ -14977,11 +15240,24 @@ + + @cindex CVS_CLIENT_LOG, environment variable + @item $CVS_CLIENT_LOG +-Used for debugging only in client-server +-mode. If set, everything sent to the server is logged +-into @file{@code{$CVS_CLIENT_LOG}.in} and everything +-sent from the server is logged into +-@file{@code{$CVS_CLIENT_LOG}.out}. ++Used for debugging only in client-server mode. ++If set and not empty, everything sent to the server is logged ++into @file{@code{$CVS_CLIENT_LOG}.in}, and everything received ++from the server is logged into @file{@code{$CVS_CLIENT_LOG}.out}. ++ ++@cindex CVS_SECONDARY_LOG, environment variable ++@item $CVS_SECONDARY_LOG ++Used for debugging only in secondary write proxy mode. ++If set and not empty, everything sent to the primary server is logged ++into @file{@code{$CVS_SECONDARY_LOG}.in}, and everything received ++from the primary server is logged into @file{@code{$CVS_SECONDARY_LOG}.out}. ++ ++@cindex CVS_SERVER_LOG, environment variable ++@item $CVS_SERVER_LOG ++Used for debugging only in client-server mode. ++If set and not empty, everything sent to the client is logged ++into @file{@code{$CVS_SERVER_LOG}.in}, and everything received ++from the client is logged into @file{@code{$CVS_SERVER_LOG}.out}. + + @cindex CVS_SERVER_SLEEP, environment variable + @item $CVS_SERVER_SLEEP +@@ -15047,7 +15323,7 @@ + @c If you "cvs rm" and commit using 1.3, then you'll + @c want to run "rcs -sdead <file,v>" on each of the + @c files in the Attic if you then want 1.5 and +-@c later to recognize those files as dead (I think the ++@c later to recognise those files as dead (I think the + @c symptom if this is not done is that files reappear + @c in joins). (Wait: the above will work but really to + @c be strictly correct we should suggest checking +@@ -15172,6 +15448,7 @@ + specific reason for denying authorization. Check that + the username and password specified are correct and + that the @code{CVSROOT} specified is allowed by @samp{--allow-root} ++or @samp{--allow-root-regexp} + in @file{inetd.conf}. See @ref{Password authenticated}. + + @item cvs @var{command}: conflict: removed @var{file} was modified by second party +@@ -15614,21 +15891,21 @@ + access method you are using. + + @table @code +-@cindex :ext:, troubleshooting ++@cindex ext method, troubleshooting + @item :ext: + Try running the rsh program from the command line. For + example: "rsh servername cvs -v" should print @sc{cvs} + version information. If this doesn't work, you need to + fix it before you can worry about @sc{cvs} problems. + +-@cindex :server:, troubleshooting ++@cindex server method, troubleshooting + @item :server: + You don't need a command line rsh program to use this + access method, but if you have an rsh program around, + it may be useful as a debugging tool. Follow the + directions given for :ext:. + +-@cindex :pserver:, troubleshooting ++@cindex pserver method, troubleshooting + @item :pserver: + Errors along the lines of "connection refused" typically indicate + that inetd isn't even listening for connections on port 2401 +@@ -15806,6 +16083,16 @@ + the file @file{doc/ChangeLog} in the @sc{cvs} source + distribution. + ++MirBSD is the de-facto (if not de-iure yet) new upstream of ++@sc{gnu} @sc{cvs} since 2012 or so; this version is provided ++in Debian as well. Responsible is: ++ ++@display ++mirabilos <@t{m@@mirbsd.org}> ++@end display ++ ++CVS Homepage: @url{http://www.nongnu.org/cvs/} ++ + @c --------------------------------------------------------------------- + @node BUGS + @appendix Dealing with bugs in CVS or this manual +@@ -15887,7 +16174,7 @@ + relevant information. The way to report bugs is to + send email to @email{bug-cvs@@nongnu.org}. Note + that submissions to @email{bug-cvs@@nongnu.org} may be distributed +-under the terms of the @sc{gnu} Public License, so if ++under the terms of the @sc{gnu} General Public License, so if + you don't like this, don't submit them. There is + usually no justification for sending mail directly to + one of the @sc{cvs} maintainers rather than to +@@ -15910,6 +16197,49 @@ + comprehensive, detailed list of known bugs. + + @c --------------------------------------------------------------------- ++@node CVS command list ++@appendix Alphabetical list of all CVS commands ++ ++@xref{Cederqvist, the introduction into the manual, CVS manual Table of Contents}. ++ ++@menu ++* add:: Add a new file/directory to the repository ++* admin:: Administration front-end for RCS ++* annotate:: Show last revision where each line was modified ++* checkout:: Checkout sources for editing ++* commit:: Check files into the repository ++* diff:: Show differences between revisions ++* edit:: Get ready to edit a watched file ++* editors:: See who is editing a watched file ++* export:: Export sources from CVS, similar to checkout ++* history:: Show repository access history ++* import:: Import sources into CVS, using vendor branches ++* init:: Create a CVS repository ++* kserver:: Act in Kerberos server mode ++* log:: Print out history information for files ++* login:: Prompt for password for authenticating server ++* logout:: Removes entry in .cvspass for remote repository ++* ls:: List files available from CVS ++* pserver:: Act in password server mode ++* rannotate:: Show last revision where each line of module was modified ++* rdiff:: Create 'patch' format diffs between revisions ++* release:: Indicate that a work subdirectory is no longer in use ++* remove:: Remove an entry from the repository ++* rlog:: Print out history information for a module ++* rls:: List files in a module ++* rtag:: Add a symbolic tag to a module ++* server:: Act in server mode ++* suck:: Download RCS ,v file raw ++* status:: Display status information on checked out files ++* tag:: Add a symbolic tag to checked out version of files ++* unedit:: Undo an edit command ++* update:: Bring work tree in sync with repository ++* version:: Show current CVS version(s) ++* watch:: Set watches ++* watchers:: See who is watching a file ++@end menu ++ ++@c --------------------------------------------------------------------- + @node Index + @unnumbered Index + @cindex Index +--- cvs-1.12.13+real.orig/doc/cvsclient.texi ++++ cvs-1.12.13+real/doc/cvsclient.texi +@@ -1,6 +1,18 @@ + \input texinfo @c -*- texinfo -*- + + @setfilename cvsclient.info ++@set MBSDPATCHLEVEL -MirOS-0AB9.1 ++@tex ++ % set PA4 paper size (can print on both DIN ISO A4 and US Letter) ++ \globaldefs = 1% ++ \afourpaper% ++ \internalpagesizes{46\baselineskip}{160mm}% ++ {\voffset}{\hoffset}% ++ {\bindingoffset}{36pt}% ++ {28truecm}{21truecm}% ++ \globaldefs = 0% ++@end tex ++@comment $MirOS: src/gnu/usr.bin/cvs/doc/cvsclient.texi,v 1.14 2021/01/30 05:14:20 tg Exp $ + @include version-client.texi + + @dircategory Programming +@@ -8,14 +20,26 @@ + * cvsclient: (cvsclient). The CVS client/server protocol. + @end direntry + ++@iftex ++@titlepage ++@sp 2 ++@center @titlefont{CVS} ++@sp 1 ++@center @titlefont{Client/Server} ++@sp 1 ++@center @titlefont{protocol} ++@sp 3 ++@end iftex ++@ifnottex + @node Top + @top CVS Client/Server ++@end ifnottex + + This document describes the client/server protocol used by CVS. It does +-not describe how to use or administer client/server CVS; see the regular +-CVS manual for that. This is version @value{VERSION} of the protocol +-specification---@xref{Introduction}, for more on what this version number +-means. ++not describe how to use or administer client/server CVS; for that, ++@pxref{Top, the regular CVS manual,, cvs, the regular CVS manual}. ++This specification applies to ++@sc{cvs} version @value{VERSION}@value{MBSDPATCHLEVEL} and up. + + @menu + * Introduction:: What is CVS and what is the client/server protocol for? +@@ -25,6 +49,9 @@ + * Protocol:: Complete description of the protocol + * Protocol Notes:: Possible enhancements, limitations, etc. of the protocol + @end menu ++@iftex ++@end titlepage ++@end iftex + + @node Introduction + @chapter Introduction +@@ -53,7 +80,7 @@ + user documentation, @file{cvs.texinfo}, for that information. The + protocol is non-proprietary (anyone who wants to is encouraged to + implement it) and an implementation, known as CVS, is available under +-the GNU Public License. The CVS distribution, containing this ++the GNU General Public License. The CVS distribution, containing this + implementation, @file{cvs.texinfo}, and a copy (possibly more or less up + to date than what you are reading now) of this document, + @file{cvsclient.texi}, can be found at the usual GNU FTP sites, with a +@@ -149,7 +176,7 @@ + the client proceeds to start the cvs protocol. + + @item kserver +-The kerberized server listens on a port (in the current implementation, ++The kerberised server listens on a port (in the current implementation, + by having inetd call "cvs kserver") which defaults to 1999. The client + connects, sends the usual kerberos authentication information, and then + starts the cvs protocol. Note: port 1999 is officially registered for +@@ -217,7 +244,7 @@ + close the connection. The @var{code} is a code describing why it + failed, intended for computer consumption. The only code currently + defined is @samp{0} which is nonspecific, but clients must silently +-treat any unrecognized codes as nonspecific. ++treat any unrecognised codes as nonspecific. + The @var{text} should be supplied to the + user. Compatibility note: @sc{cvs} 1.9.10 and older clients will print + @code{unrecognized auth response} and @var{text}, and then exit, upon +@@ -393,13 +420,13 @@ + @var{mode-type} is an identifier composed of alphanumeric characters. + Currently specified: @samp{u} for user, @samp{g} for group, @samp{o} + for other (see below for discussion of whether these have their POSIX +-meaning or are more loose). Unrecognized values of @var{mode-type} ++meaning or are more loose). Unrecognised values of @var{mode-type} + are silently ignored. + + @var{data} consists of any data not containing @samp{,}, @samp{\0} or + @samp{\n}. For @samp{u}, @samp{g}, and @samp{o} mode types, data + consists of alphanumeric characters, where @samp{r} means read, @samp{w} +-means write, @samp{x} means execute, and unrecognized letters are ++means write, @samp{x} means execute, and unrecognised letters are + silently ignored. + + The two most obvious ways in which the mode matters are: (1) is it +@@ -471,12 +498,13 @@ + In various contexts, for example the @code{Argument} request and the + @code{M} response, one transmits what is essentially an arbitrary + string. Often this will have been supplied by the user (for example, +-the @samp{-m} option to the @code{ci} request). The protocol has no +-mechanism to specify the character set of such strings; it would be +-fairly safe to stick to the invariant ISO 646 character set but the +-existing practice is probably to just transmit whatever the user +-specifies, and hope that everyone involved agrees which character set is +-in use, or sticks to a common subset. ++the @samp{-m} option to the @code{ci} request will show up in the ++@code{LOGM} response). The protocol has no mechanism to specify the ++character set of such strings; it would have been, initially, fairly ++safe to stick to the invariant ISO 646 character set but the existing ++practice is probably to just transmit whatever the user specifies, ++and hope that everyone involved agrees which character set is in use, ++or sticks to a common subset. In modern times, UTF-8 should be used. + + @node Dates + @section Dates +@@ -513,7 +541,7 @@ + + 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 ++exception is @samp{gzip-file-contents}. Unrecognised requests will + always elicit a response from the server, even if that request begins + with a capital letter. + +@@ -568,7 +596,7 @@ + Response expected: no. + Notify a primary server of a server which referred us. Intended to allow + a primary (write) server to update the read-only mirror a client is using +-for reads to minimize races on any subsequent updates from the client. ++for reads to minimise races on any subsequent updates from the client. + + @item Directory @var{local-directory} \n + @itemx Relative-directory @var{local-directory} \n +@@ -828,7 +856,7 @@ + @end example + + There is no requirement that the client and server clocks be +-synchronized. The client just sends its recommendation for a timestamp ++synchronised. The client just sends its recommendation for a timestamp + (based on file timestamps or whatever), and the server should just believe + it (this means that the time might be in the future, for example). + +@@ -1227,6 +1255,13 @@ + directory and @emph{not} a fully qualified @code{CVSROOT} variable. + The @code{Root} request need not have been previously sent. + ++@item suck \n ++Response expected: yes. ++Actually do a @code{cvs suck} command. ++This uses a previous @code{Argument} request (only one, because the ++@code{cvs suck} CLI command takes only one). ++This is an extension specific to MirBSD, MirPorts and Debian. ++ + @item update \n + Response expected: yes. Actually do a @code{cvs update} command. This + uses any previous @code{Argument}, @code{Directory}, @code{Entry}, +@@ -1268,7 +1303,7 @@ + C: Directory . + C: 1dir + C: add +-S: M Directory /u/cvsroot/1dir/nsdir added to the repository ++S: M Directory /u/cvsroot/1dir/nsdir put under version control + S: ok + @end example + +@@ -1414,7 +1449,7 @@ + + @item @var{other-request} @var{text} \n + Response expected: yes. +-Any unrecognized request expects a response, and does not ++Any unrecognised request expects a response, and does not + contain any additional data. The response will normally be something like + @samp{error unrecognized request}, but it could be a different error if + a previous request which doesn't expect a response produced an error. +@@ -1640,7 +1675,7 @@ + @end example + + There is no requirement that the client and server clocks be +-synchronized. The server just sends its recommendation for a timestamp ++synchronised. The server just sends its recommendation for a timestamp + (based on its own clock, presumably), and the client should just believe + it (this means that the time might be in the future, for example). + +@@ -1757,15 +1792,22 @@ + exact text which is output is subject to vary at the discretion of the + server and the example output given in this document is just that, + example output. Servers are encouraged to use the @samp{MT} response, +-and future versions of this document will hopefully standardize more of ++and future versions of this document will hopefully standardise more of + the @samp{MT} tags; see @ref{Text tags}. + ++@item LOGM @var{text} \n ++Exactly the same as @code{M} but only sent if the client indicates ++supporting it via @code{Valid-responses}, used exclusively for log ++message payload (that is, in @code{cvs log} and @code{cvs rlog}, ++the text body the user originally has entered with the @samp{-m} ++option to the @code{ci} request). ++ + @item Mbinary \n + Additional data: file transmission (note: compressed file transmissions +-are not supported). This is like @samp{M}, except the contents of the ++are not supported). This is like @code{M}, except the contents of the + file transmission are binary and should be copied to standard output + without translation to local text file conventions. To transmit a text +-file to standard output, servers should use a series of @samp{M} requests. ++file to standard output, servers should use a series of @code{M} requests. + + @item E @var{text} \n + Same as @code{M} but send to stderr not stdout. +@@ -1789,12 +1831,12 @@ + + The @var{tagname} can have several forms. If it starts with @samp{a} + to @samp{z} or @samp{A} to @samp{Z}, then it represents tagged text. +-If the implementation recognizes @var{tagname}, then it may interpret ++If the implementation recognises @var{tagname}, then it may interpret + @var{data} in some particular fashion. If the implementation does not +-recognize @var{tagname}, then it should simply treat @var{data} as +-text to be sent to the user (similar to an @samp{M} response). There ++recognise @var{tagname}, then it should simply treat @var{data} as ++text to be sent to the user (similar to an @code{M} response). There + are two tags which are general purpose. The @samp{text} tag is +-similar to an unrecognized tag in that it provides text which will ++similar to an unrecognised tag in that it provides text which will + ordinarily be sent to the user. The @samp{newline} tag is used + without @var{data} and indicates that a newline will ordinarily be + sent to the user (there is no provision for embedding newlines in the +@@ -2133,13 +2175,13 @@ + The protocol uses an extra network turnaround for protocol negotiation + (@code{valid-requests}). It might be nice to avoid this by having the + client be able to send requests and tell the server to ignore them if +-they are unrecognized (different requests could produce a fatal error if +-unrecognized). To do this there should be a standard syntax for ++they are unrecognised (different requests could produce a fatal error if ++unrecognised). To do this there should be a standard syntax for + requests. For example, perhaps all future requests should be a single + line, with mechanisms analogous to @code{Argumentx}, or several requests + working together, to provide greater amounts of information. Or there + might be a standard mechanism for counted data (analogous to that used +-by @code{Modified}) or continuation lines (like a generalized ++by @code{Modified}) or continuation lines (like a generalised + @code{Argumentx}). It would be useful to compare what HTTP is planning + in this area; last I looked they were contemplating something called + Protocol Extension Protocol but I haven't looked at the relevant IETF +--- cvs-1.12.13+real.orig/doc/getdate.texi ++++ cvs-1.12.13+real/doc/getdate.texi +@@ -1,14 +1,22 @@ + @c GNU date syntax documentation ++@c $MirOS: src/gnu/usr.bin/cvs/doc/getdate.texi,v 1.9 2021/01/30 02:06:00 tg Exp $ + + @c Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + @c 2003, 2004, 2005 Free Software Foundation, Inc. + +-@c Permission is granted to copy, distribute and/or modify this document +-@c under the terms of the GNU Free Documentation License, Version 1.1 or +-@c any later version published by the Free Software Foundation; with no +-@c Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +-@c Texts. A copy of the license is included in the ``GNU Free +-@c Documentation License'' file as part of this distribution. ++@c Copyright (c) 2007, 2010 mirabilos <m@mirbsd.org> ++ ++@comment This file is part of the CVS distribution. ++ ++@comment CVS is free software; you can redistribute it and/or modify ++@comment it under the terms of the GNU General Public License as published by ++@comment the Free Software Foundation; either version 2, or (at your option) ++@comment any later version. ++ ++@comment CVS is distributed in the hope that it will be useful, ++@comment but WITHOUT ANY WARRANTY; without even the implied warranty of ++@comment MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++@comment GNU General Public License for more details. + + @node Date input formats + @chapter Date input formats +@@ -55,8 +63,7 @@ + * Day of week items:: Monday and others. + * Relative items in date strings:: next tuesday, 2 years ago. + * Pure numbers in date strings:: 19931219, 1440. +-* Seconds since the Epoch:: @@1078100502. +-* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0". ++* Seconds since the Epoch:: @@1101064456 + * Authors of get_date:: Bellovin, Eggert, Salz, Berets, et al. + @end menu + +@@ -113,8 +120,7 @@ + + @cindex language, in dates + @cindex time zone item +-The output of the @command{date} command +-is not always acceptable as a date string, ++The output of @command{date} is not always acceptable as a date string, + not only because of the language problem, but also because there is no + standard meaning for time zone items like @samp{IST}. When using + @command{date} to generate a date string intended to be parsed later, +@@ -124,15 +130,21 @@ + + @example + $ LC_ALL=C TZ=UTC0 date +-Mon Mar 1 00:21:42 UTC 2004 +-$ TZ=UTC0 date +'%Y-%m-%d %H:%M:%SZ' +-2004-03-01 00:21:42Z ++Fri Dec 15 19:48:05 UTC 2000 ++$ TZ=UTC0 date +"%Y-%m-%d %H:%M:%SZ" ++2000-12-15 19:48:05Z ++$ date --iso-8601=seconds # a GNU extension ++2000-12-15T11:48:05-0800 ++$ date --iso-8601=ns # a GNU extension ++2004-02-29T16:21:42,692722128-0800 + $ date --iso-8601=ns | tr T ' ' # --iso-8601 is a GNU extension. + 2004-02-29 16:21:42,692722128-0800 + $ date --rfc-2822 # a GNU extension +-Sun, 29 Feb 2004 16:21:42 -0800 +-$ date +'%Y-%m-%d %H:%M:%S %z' # %z is a GNU extension. +-2004-02-29 16:21:42 -0800 ++Fri, 15 Dec 2000 11:48:05 -0800 ++$ date +"%Y-%m-%d %H:%M:%S %z" # %z is a GNU extension. ++2000-12-15 11:48:05 -0800 ++$ date +'@@%s' # %s is a MirBSD extension. ++@@1101064210 + $ date +'@@%s.%N' # %s and %N are GNU extensions. + @@1078100502.692722128 + @end example +@@ -234,11 +246,10 @@ + More generally, the time of day may be given as + @samp{@var{hour}:@var{minute}:@var{second}}, where @var{hour} is + a number between 0 and 23, @var{minute} is a number between 0 and +-59, and @var{second} is a number between 0 and 59 possibly followed by +-@samp{.} or @samp{,} and a fraction containing one or more digits. +-Alternatively, +-@samp{:@var{second}} can be omitted, in which case it is taken to +-be zero. ++59, and @var{second} is a number between 0 and 59, with an optional ++fraction separated by @samp{.} or @samp{,} consisting of digits. ++Alternatively, @samp{:@var{second}} can be omitted, in which case ++it is taken to be zero. + + @findex am @r{in date strings} + @findex pm @r{in date strings} +@@ -299,8 +310,7 @@ + described in the previous section. + + If neither a time zone item nor a time zone correction is supplied, +-time stamps are interpreted using the rules of the default time zone +-(@pxref{Specifying time zone rules}). ++time stamps are interpreted using the rules of the default time zone. + + + @node Day of week items +@@ -389,7 +399,7 @@ + date strings like @samp{this thursday}. + + When a relative item causes the resulting date to cross a boundary +-where the clocks were adjusted, typically for daylight saving time, ++where the clocks were adjusted, typically for daylight-saving time, + the resulting date and time are adjusted accordingly. + + The fuzz in units can cause problems with relative items. For +@@ -401,7 +411,7 @@ + @example + $ date -R + Thu, 31 Jul 2003 13:02:39 -0700 +-$ date --date='-1 month' +'Last month was %B?' ++$ date --date="-1 month" +'Last month was %B?' + Last month was July? + $ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!' + Last month was June! +@@ -440,86 +450,49 @@ + @node Seconds since the Epoch + @section Seconds since the Epoch + +-If you precede a number with @samp{@@}, it represents an internal time +-stamp as a count of seconds. The number can contain an internal +-decimal point (either @samp{.} or @samp{,}); any excess precision not +-supported by the internal representation is truncated toward minus +-infinity. Such a number cannot be combined with any other date +-item, as it specifies a complete time stamp. ++If you give a string consisting of @samp{@@} followed by a decimal ++number, it is parsed as an internal time stamp, @sc{utc} for ++@acronym{POSIX} compliant systems, @sc{tai} for systems which keep ++time correctly, and directly mapped to a kernel time. The implementation ++handles an optional fraction separated by @samp{.} or @samp{,} and ++truncates to a supported internal precision, rounding towards the ++negative infinity. Since the kernel time stamp represents complete ++date and time information, it cannot be combined with any other ++format given. + + @cindex beginning of time, for @acronym{POSIX} + @cindex epoch, for @acronym{POSIX} +-Internally, computer times are represented as a count of seconds since +-an epoch---a well-defined point of time. On @acronym{GNU} and +-@acronym{POSIX} systems, the epoch is 1970-01-01 00:00:00 @sc{utc}, so +-@samp{@@0} represents this time, @samp{@@1} represents 1970-01-01 +-00:00:01 @sc{utc}, and so forth. @acronym{GNU} and most other +-@acronym{POSIX}-compliant systems support such times as an extension +-to @acronym{POSIX}, using negative counts, so that @samp{@@-1} +-represents 1969-12-31 23:59:59 @sc{utc}. +- +-Traditional Unix systems count seconds with 32-bit two's-complement +-integers and can represent times from 1901-12-13 20:45:52 through +-2038-01-19 03:14:07 @sc{utc}. More modern systems use 64-bit counts +-of seconds with nanosecond subcounts, and can represent all the times +-in the known lifetime of the universe to a resolution of 1 nanosecond. +- +-On most systems, these counts ignore the presence of leap seconds. +-For example, on most systems @samp{@@915148799} represents 1998-12-31 +-23:59:59 @sc{utc}, @samp{@@915148800} represents 1999-01-01 00:00:00 +-@sc{utc}, and there is no way to represent the intervening leap second +-1998-12-31 23:59:60 @sc{utc}. +- +-@node Specifying time zone rules +-@section Specifying time zone rules +- +-@vindex TZ +-Normally, dates are interpreted using the rules of the current time +-zone, which in turn are specified by the @env{TZ} environment +-variable, or by a system default if @env{TZ} is not set. To specify a +-different set of default time zone rules that apply just to one date, +-start the date with a string of the form @samp{TZ="@var{rule}"}. The +-two quote characters (@samp{"}) must be present in the date, and any +-quotes or backslashes within @var{rule} must be escaped by a +-backslash. +- +-For example, with the @acronym{GNU} @command{date} command you can +-answer the question ``What time is it in New York when a Paris clock +-shows 6:30am on October 31, 2004?'' by using a date beginning with +-@samp{TZ="Europe/Paris"} as shown in the following shell transcript: +- +-@example +-$ export TZ="America/New_York" +-$ date --date='TZ="Europe/Paris" 2004-10-31 06:30' +-Sun Oct 31 01:30:00 EDT 2004 +-@end example ++Although the date syntax here can represent any possible time since the ++year zero, computer integers often cannot represent such a wide range of ++time. On @acronym{POSIX} systems, the clock starts at 1970-01-01 00:00:00 ++@sc{utc}: @acronym{POSIX} does not require support for times before the ++@acronym{POSIX} Epoch and times far in the future. @acronym{GNU} and ++traditional Unix systems have 32-bit signed @code{time_t} and can represent ++times from 1901-12-13 20:45:52 through 2038-01-19 03:14:07 @sc{utc}, such ++that @samp{@@0} represents the epoch, @samp{@@1} represents 1970-01-01 ++00:00:01 @sc{utc}, and so forth, whereas @samp{@@-1}, not mandated by ++@acronym{POSIX}, represents 1969-12-31 23:59:59 @sc{utc}. Systems with ++64-bit signed @code{time_t} can represent all the times in the known ++lifetime of the universe. Modern @acronym{UNIX} systems also can give ++precise timecounters in the nanosecond or even attosecond range with ++a resolution often only a small multiply, like 10000, of the CPU ++frequency (on fast machines). ++ ++@acronym{POSIX} conformant systems do not count leap seconds, and their ++kernel time is a seconds-since-epoch representation of @sc{utc} (which ++is a calendar time); the MirOS family of operating systems keeps time ++as seconds since the epoch, @sc{tai}, correctly counting leap seconds ++and providing conversion functions. Most MirBSD ports have already ++switched to a 64-bit signed @code{time_t}, some are using a ++@sc{djb}-compatible @code{tai_t} internally. The rest of this ++document has not been throughoutly checked for @sc{utc} vs @sc{tai} ++correctness. For @acronym{POSIX}ly broken systems, @samp{@@915148799} ++represents 1998-12-31 23:59:59 @sc{utc}, @samp{@@915148800} represents ++1999-01-01 00:00:00 @sc{utc}, and there is no way to represent the ++intervening leap second 1998-12-31 23:59:60 @sc{utc}. Also, calculation ++of time deltas is wrong, such as the age of the MirBSD founder is already ++off by more than 10 seconds in 2000. + +-In this example, the @option{--date} operand begins with its own +-@env{TZ} setting, so the rest of that operand is processed according +-to @samp{Europe/Paris} rules, treating the string @samp{2004-10-31 +-06:30} as if it were in Paris. However, since the output of the +-@command{date} command is processed according to the overall time zone +-rules, it uses New York time. (Paris was normally six hours ahead of +-New York in 2004, but this example refers to a brief Halloween period +-when the gap was five hours.) +- +-A @env{TZ} value is a rule that typically names a location in the +-@uref{http://www.twinsun.com/tz/tz-link.htm, @samp{tz} database}. +-A recent catalog of location names appears in the +-@uref{http://twiki.org/cgi-bin/xtra/tzdate, TWiki Date and Time +-Gateway}. A few non-@acronym{GNU} hosts require a colon before a +-location name in a @env{TZ} setting, e.g., +-@samp{TZ=":America/New_York"}. +- +-The @samp{tz} database includes a wide variety of locations ranging +-from @samp{Arctic/Longyearbyen} to @samp{Antarctica/South_Pole}, but +-if you are at sea and have your own private time zone, or if you are +-using a non-@acronym{GNU} host that does not support the @samp{tz} +-database, you may need to use a @acronym{POSIX} rule instead. Simple +-@acronym{POSIX} rules like @samp{UTC0} specify a time zone without +-daylight saving time; other rules can specify simple daylight saving +-regimes. @xref{TZ Variable,, Specifying the Time Zone with @code{TZ}, +-libc, The GNU C Library}. + + @node Authors of get_date + @section Authors of @code{get_date} +@@ -545,3 +518,10 @@ + This chapter was originally produced by Fran@,{c}ois Pinard + (@email{pinard@@iro.umontreal.ca}) from the @file{getdate.y} source code, + and then edited by K.@: Berry (@email{kb@@cs.umb.edu}). ++ ++The version of this chapter you are reading comes with MirBSD @sc{gnu} ++@sc{cvs} 1.12 (also in Debian); it is based upon an older version of ++the @sc{gnu} coreutils manual which is @emph{not} yet GFDL-licenced. ++Appropriate changes for the in-tree @code{get_date} version of CVS ++have been applied. ++The MirBSD version is maintained by mirabilos @email{m@@mirbsd.org}. +--- cvs-1.12.13+real.orig/doc/mkman.pl ++++ cvs-1.12.13+real/doc/mkman.pl +@@ -1,10 +1,12 @@ + #! @PERL@ ++# $MirOS: src/gnu/usr.bin/cvs/doc/mkman.pl,v 1.7 2021/01/30 02:06:01 tg Exp $ + # + # Generate a man page from sections of a Texinfo manual. + # + # Copyright 2004 The Free Software Foundation, + # Derek R. Price, + # & Ximbiot <http://ximbiot.com> ++# Copyright (c) 2004, 2010, 2021 mirabilos <m@mirbsd.org> + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -62,7 +64,7 @@ + if $keyword =~ /^(strong|sc|code|file|samp)$/; + return "\\fI" + if $keyword =~ /^(emph|var|dfn)$/; +- die "no handler for keyword \`$keyword', found at line $. of file \`$file'\n"; ++ die "no handler for keyword '$keyword', found at line $. of file '$file'\n"; + } + + +@@ -72,8 +74,12 @@ + { + my ($file, $parent, $keyword, $content) = @_; + +- return "see node \`$content\\(aq in the CVS manual" +- if $keyword =~ /^(p?x)?ref$/; ++ return "node \\(aq$content\\(aq in the CVS manual" ++ if $keyword =~ /^ref$/; ++ return "See node \\(aq$content\\(aq in the CVS manual" ++ if $keyword =~ /^xref$/; ++ return "see node \\(aq$content\\(aq in the CVS manual" ++ if $keyword =~ /^pxref$/; + return "\\fP\\fP$content" + if $keyword =~ /^splitrcskeyword$/; + +@@ -91,11 +97,11 @@ + for my $file (@ARGV) + { + my $fh = new IO::File "< $file" +- or die "Failed to open file \`$file': $!"; ++ or die "Failed to open file '$file': $!"; + + if ($file !~ /\.(texinfo|texi|txi)$/) + { +- print stderr "Passing \`$file' through unprocessed.\n"; ++ print stderr "Passing '$file' through unprocessed.\n"; + # Just cat any file that doesn't look like a Texinfo source. + while (my $line = $fh->getline) + { +@@ -104,7 +110,7 @@ + next; + } + +- print stderr "Processing \`$file'.\n"; ++ print stderr "Processing '$file'.\n"; + $texi_num++; + my $gotone = 0; + my $inblank = 0; +@@ -140,8 +146,11 @@ + s/'/\\(aq/g; + s/`/\\`/g; + s/(?<!-)---(?!-)/\\(em/g; +- s/\@bullet({}|\b)/\\(bu/g; +- s/\@dots({}|\b)/\\&.../g; ++ s/\@bullet(\{}|\b)/\\(bu/g; ++ s/\@dots(\{}|\b)/\\&.../g; ++ ++ # Hack for GNU groff with nroff -Tutf8 ++ s/-/\\-/g; + + # Examples should be indented and otherwise untouched + if (/^\@example$/) +@@ -356,7 +365,7 @@ + s/\@([{}])/$1/g; + + # Verify we haven't left commands unprocessed. +- die "Unprocessed command at line $. of file \`$file': " ++ die "Unprocessed command at line $. of file '$file': " + . ($1 ? "$1\n" : "<EOL>\n") + if /^(?>(?:[^\@]|\@\@)*)\@(\w+|.|$)/; + +--- cvs-1.12.13+real.orig/lib/Makefile.am ++++ cvs-1.12.13+real/lib/Makefile.am +@@ -131,16 +131,11 @@ + ## CVS test scripts for getdate. + TESTS += test-getdate.sh + MOSTLYCLEANFILES += getdate-expected getdate-got getdate.diff +-DISTCLEANFILES += getdate.log ++DISTCLEANFILES += getdate.log getdate.log~ + # Program required by test-getdate.sh for testing getdate.y. + check_PROGRAMS += getdate + getdate_SOURCES = \ +- error.c \ +- getdate.y +-## This source file was added only for the getdate test program when compiled +-## with GNULIB's error.c. +-getdate_SOURCES += \ +- progname.c ++ getdate.c + getdate_CPPFLAGS = -DTEST + getdate_LDADD = \ + $(noinst_LIBRARIES) \ +--- cvs-1.12.13+real.orig/lib/__fpending.h ++++ cvs-1.12.13+real/lib/__fpending.h +@@ -1,7 +1,7 @@ + #include <stddef.h> + #include <stdio.h> + +-#if HAVE_STDIO_EXT_H ++#if defined(HAVE_STDIO_EXT_H) && (HAVE_STDIO_EXT_H) + # include <stdio_ext.h> + #endif + +--- cvs-1.12.13+real.orig/lib/allocsa.h ++++ cvs-1.12.13+real/lib/allocsa.h +@@ -19,7 +19,9 @@ + #ifndef _ALLOCSA_H + #define _ALLOCSA_H + ++#ifdef HAVE_ALLOCA_H + #include <alloca.h> ++#endif + #include <stddef.h> + #include <stdlib.h> + +--- cvs-1.12.13+real.orig/lib/chdir-long.c ++++ cvs-1.12.13+real/lib/chdir-long.c +@@ -39,9 +39,7 @@ + # define O_DIRECTORY 0 + #endif + +-#ifndef PATH_MAX +-# error "compile this file only if your system defines PATH_MAX" +-#endif ++#ifdef PATH_MAX + + struct cd_buf + { +@@ -269,6 +267,8 @@ + } + #endif + ++#endif /* PATH_MAX */ ++ + /* + Local Variables: + compile-command: "gcc -DTEST_CHDIR=1 -DHAVE_CONFIG_H -I.. -g -O -W -Wall chdir-long.c libcoreutils.a" +--- cvs-1.12.13+real.orig/lib/closeout.c ++++ cvs-1.12.13+real/lib/closeout.c +@@ -59,7 +59,7 @@ + when it tries to write out that buffered data. Thus, you would be + left with an incomplete output file and the offending program would + exit successfully. Even calling fflush is not always sufficient, +- since some file systems (NFS and CODA) buffer written/flushed data ++ since some filesystems (NFS and CODA) buffer written/flushed data + until an actual close call. + + Besides, it's wasteful to check the return value from every call +--- cvs-1.12.13+real.orig/lib/error.c ++++ cvs-1.12.13+real/lib/error.c +@@ -1,6 +1,7 @@ + /* Error handler for noninteractive utilities + Copyright (C) 1990-1998, 2000-2003, 2004 Free Software Foundation, Inc. +- This file is part of the GNU C Library. ++ Copyright (c) 2021 mirabilos <m@mirbsd.org> ++ This file is part of GNU CVS. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -133,7 +134,7 @@ + } + + static void +-error_tail (int status, int errnum, const char *message, va_list args) ++warning_tail (int errnum, const char *message, va_list args) + { + #if _LIBC + if (_IO_fwide (stderr, 0) > 0) +@@ -176,17 +177,15 @@ + #endif + putc ('\n', stderr); + fflush (stderr); +- if (status) +- exit (status); + } + +- ++#if 0 /* disabled in CVS */ + /* Print the program name and error message MESSAGE, which is a printf-style + format string with optional args. + If ERRNUM is nonzero, print its corresponding system error message. +- Exit with status STATUS if it is nonzero. */ ++*/ + void +-error (int status, int errnum, const char *message, ...) ++warning (int errnum, const char *message, ...) + { + va_list args; + +@@ -215,7 +214,7 @@ + } + + va_start (args, message); +- error_tail (status, errnum, message, args); ++ warning_tail (errnum, message, args); + + #ifdef _LIBC + _IO_funlockfile (stderr); +@@ -224,13 +223,14 @@ + # endif + #endif + } ++#endif + + /* Sometimes we want to have at most one error per line. This + variable controls whether this mode is selected or not. */ + int error_one_per_line; + + void +-error_at_line (int status, int errnum, const char *file_name, ++warning_at_line (int errnum, const char *file_name, + unsigned int line_number, const char *message, ...) + { + va_list args; +@@ -285,7 +285,7 @@ + } + + va_start (args, message); +- error_tail (status, errnum, message, args); ++ warning_tail (errnum, message, args); + + #ifdef _LIBC + _IO_funlockfile (stderr); +--- cvs-1.12.13+real.orig/lib/error.h ++++ cvs-1.12.13+real/lib/error.h +@@ -1,6 +1,8 @@ ++/* $MirOS: src/gnu/usr.bin/cvs/lib/error.h,v 1.2 2021/01/30 02:06:03 tg Exp $ */ + /* Declaration for error-reporting function + Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. ++ Copyright (c) 2021 mirabilos <m@mirbsd.org> ++ This file is part of GNU CVS. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -19,6 +21,9 @@ + #ifndef _ERROR_H + #define _ERROR_H 1 + ++/* for exit(3) */ ++#include <stdlib.h> ++ + #ifndef __attribute__ + /* This feature is available in gcc versions 2.5 and later. */ + # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +@@ -40,12 +45,46 @@ + if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). + If STATUS is nonzero, terminate the program with `exit (STATUS)'. */ + +-extern void error (int __status, int __errnum, const char *__format, ...) +- __attribute__ ((__format__ (__printf__, 3, 4))); ++/* changed for CVS: if STATUS is nonzero, use EXIT_FAILURE */ ++ ++#if 0 ++#define error(status,...) do { \ ++ int CVS_error_st = (status); \ ++ \ ++ warning(__VA_ARGS__); \ ++ if (CVS_error_st) \ ++ exit(CVS_error_st); \ ++} while (/* CONSTCOND */ 0) ++ ++extern void warning (int __errnum, const char *__format, ...) ++ __attribute__ ((__format__ (__printf__, 2, 3))); ++ ++#else /* ↑ lib │ ↓ CVS */ ++ ++#define error(...) do { \ ++ if (warning(__VA_ARGS__)) \ ++ exit(EXIT_FAILURE); \ ++} while (/* CONSTCOND */ 0) ++ ++extern int warning(int status, int errnum, const char *message, ...) ++ __attribute__((__format__(__printf__, 3, 4))); ++#endif ++ ++#define error_at_line(status,...) do { \ ++ int CVS_error_st = (status); \ ++ \ ++ warning_at_line(__VA_ARGS__); \ ++ if (CVS_error_st) \ ++ exit(CVS_error_st); \ ++} while (/* CONSTCOND */ 0) + +-extern void error_at_line (int __status, int __errnum, const char *__fname, ++extern void warning_at_line (int __errnum, const char *__fname, + unsigned int __lineno, const char *__format, ...) +- __attribute__ ((__format__ (__printf__, 5, 6))); ++ __attribute__ ((__format__ (__printf__, 4, 5))); ++ ++/*XXX this calls for some trickery with __builtin_constant_p ++ to eliminate the if, if not the exit, but let’s just ++ rely on the optimiser for constant arguments; this API sucks */ + + /* If NULL, error will flush stdout, then print on stderr the program + name, a colon and a space. Otherwise, error will call this +--- cvs-1.12.13+real.orig/lib/filenamecat.c ++++ cvs-1.12.13+real/lib/filenamecat.c +@@ -50,7 +50,7 @@ + newly-allocated storage and return the result. + The resulting file name F is such that the commands "ls F" and "(cd + DIR; ls BASE)" refer to the same file, where BASE is ABASE with any +- file system prefixes and leading separators removed. ++ filesystem prefixes and leading separators removed. + Arrange for a directory separator if necessary between DIR and BASE + in the result, removing any redundant separators. + In any case, if BASE_IN_RESULT is non-NULL, set +--- cvs-1.12.13+real.orig/lib/fncase.c ++++ cvs-1.12.13+real/lib/fncase.c +@@ -1,4 +1,4 @@ +-/* fncase.c -- CVS support for case insensitive file systems. ++/* fncase.c -- CVS support for case insensitive filesystems. + Jim Blandy <jimb@cyclic.com> + + This file is part of GNU CVS. +--- cvs-1.12.13+real.orig/lib/getcwd.c ++++ cvs-1.12.13+real/lib/getcwd.c +@@ -151,7 +151,7 @@ + size_t allocated = size; + size_t used; + +-#if HAVE_PARTLY_WORKING_GETCWD && !defined AT_FDCWD ++#if HAVE_PARTLY_WORKING_GETCWD + /* The system getcwd works, except it sometimes fails when it + shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT. If + AT_FDCWD is not defined, the algorithm below is O(N**2) and this +@@ -204,6 +204,9 @@ + ino_t dotino; + bool mount_point; + int parent_status; ++ size_t dirroom; ++ size_t namlen; ++ bool use_d_ino = true; + + /* Look at the parent directory. */ + #ifdef AT_FDCWD +@@ -244,110 +247,131 @@ + goto lose; + dotlist[dotlen++] = '/'; + #endif +- /* Clear errno to distinguish EOF from error if readdir returns +- NULL. */ +- __set_errno (0); +- while ((d = __readdir (dirstream)) != NULL) ++ for (;;) + { ++ /* Clear errno to distinguish EOF from error if readdir returns ++ NULL. */ ++ __set_errno (0); ++ d = __readdir (dirstream); ++ ++ /* When we've iterated through all directory entries without finding ++ one with a matching d_ino, rewind the stream and consider each ++ name again, but this time, using lstat. This is necessary in a ++ chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where ++ .., ../.., ../../.., etc. all had the same device number, yet the ++ d_ino values for entries in / did not match those obtained ++ via lstat. */ ++ if (d == NULL && errno == 0 && use_d_ino) ++ { ++ use_d_ino = false; ++ rewinddir (dirstream); ++ d = __readdir (dirstream); ++ } ++ ++ if (d == NULL) ++ { ++ if (errno == 0) ++ /* EOF on dirstream, which can mean e.g., that the current ++ directory has been removed. */ ++ __set_errno (ENOENT); ++ goto lose; ++ } + if (d->d_name[0] == '.' && + (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0'))) + continue; +- if (MATCHING_INO (d, thisino) || mount_point) ++ ++ if (use_d_ino) + { +- int entry_status; ++ bool match = (MATCHING_INO (d, thisino) || mount_point); ++ if (! match) ++ continue; ++ } ++ ++ { ++ int entry_status; + #ifdef AT_FDCWD +- entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); ++ entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); + #else +- /* Compute size needed for this file name, or for the file +- name ".." in the same directory, whichever is larger. +- Room for ".." might be needed the next time through +- the outer loop. */ +- size_t name_alloc = _D_ALLOC_NAMLEN (d); +- size_t filesize = dotlen + MAX (sizeof "..", name_alloc); +- +- if (filesize < dotlen) +- goto memory_exhausted; ++ /* Compute size needed for this file name, or for the file ++ name ".." in the same directory, whichever is larger. ++ Room for ".." might be needed the next time through ++ the outer loop. */ ++ size_t name_alloc = _D_ALLOC_NAMLEN (d); ++ size_t filesize = dotlen + MAX (sizeof "..", name_alloc); ++ ++ if (filesize < dotlen) ++ goto memory_exhausted; ++ ++ if (dotsize < filesize) ++ { ++ /* My, what a deep directory tree you have, Grandma. */ ++ size_t newsize = MAX (filesize, dotsize * 2); ++ size_t i; ++ if (newsize < dotsize) ++ goto memory_exhausted; ++ if (dotlist != dots) ++ free (dotlist); ++ dotlist = malloc (newsize); ++ if (dotlist == NULL) ++ goto lose; ++ dotsize = newsize; + +- if (dotsize < filesize) +- { +- /* My, what a deep directory tree you have, Grandma. */ +- size_t newsize = MAX (filesize, dotsize * 2); +- size_t i; +- if (newsize < dotsize) +- goto memory_exhausted; +- if (dotlist != dots) +- free (dotlist); +- dotlist = malloc (newsize); +- if (dotlist == NULL) +- goto lose; +- dotsize = newsize; +- +- i = 0; +- do +- { +- dotlist[i++] = '.'; +- dotlist[i++] = '.'; +- dotlist[i++] = '/'; +- } +- while (i < dotlen); +- } ++ i = 0; ++ do ++ { ++ dotlist[i++] = '.'; ++ dotlist[i++] = '.'; ++ dotlist[i++] = '/'; ++ } ++ while (i < dotlen); ++ } + +- strcpy (dotlist + dotlen, d->d_name); +- entry_status = __lstat (dotlist, &st); ++ memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d)); ++ entry_status = __lstat (dotlist, &st); + #endif +- /* We don't fail here if we cannot stat() a directory entry. +- This can happen when (network) file systems fail. If this +- entry is in fact the one we are looking for we will find +- out soon as we reach the end of the directory without +- having found anything. */ +- if (entry_status == 0 && S_ISDIR (st.st_mode) +- && st.st_dev == thisdev && st.st_ino == thisino) +- break; +- } ++ /* We don't fail here if we cannot stat() a directory entry. ++ This can happen when (network) filesystems fail. If this ++ entry is in fact the one we are looking for we will find ++ out soon as we reach the end of the directory without ++ having found anything. */ ++ if (entry_status == 0 && S_ISDIR (st.st_mode) ++ && st.st_dev == thisdev && st.st_ino == thisino) ++ break; ++ } + } +- if (d == NULL) +- { +- if (errno == 0) +- /* EOF on dirstream, which means that the current directory +- has been removed. */ +- __set_errno (ENOENT); +- goto lose; +- } +- else +- { +- size_t dirroom = dirp - dir; +- size_t namlen = _D_EXACT_NAMLEN (d); + +- if (dirroom <= namlen) ++ dirroom = dirp - dir; ++ namlen = _D_EXACT_NAMLEN (d); ++ ++ if (dirroom <= namlen) ++ { ++ if (size != 0) + { +- if (size != 0) +- { +- __set_errno (ERANGE); +- goto lose; +- } +- else +- { +- char *tmp; +- size_t oldsize = allocated; +- +- allocated += MAX (allocated, namlen); +- if (allocated < oldsize +- || ! (tmp = realloc (dir, allocated))) +- goto memory_exhausted; +- +- /* Move current contents up to the end of the buffer. +- This is guaranteed to be non-overlapping. */ +- dirp = memcpy (tmp + allocated - (oldsize - dirroom), +- tmp + dirroom, +- oldsize - dirroom); +- dir = tmp; +- } ++ __set_errno (ERANGE); ++ goto lose; ++ } ++ else ++ { ++ char *tmp; ++ size_t oldsize = allocated; ++ ++ allocated += MAX (allocated, namlen); ++ if (allocated < oldsize ++ || ! (tmp = realloc (dir, allocated))) ++ goto memory_exhausted; ++ ++ /* Move current contents up to the end of the buffer. ++ This is guaranteed to be non-overlapping. */ ++ dirp = memcpy (tmp + allocated - (oldsize - dirroom), ++ tmp + dirroom, ++ oldsize - dirroom); ++ dir = tmp; + } +- dirp -= namlen; +- memcpy (dirp, d->d_name, namlen); +- *--dirp = '/'; + } ++ dirp -= namlen; ++ memcpy (dirp, d->d_name, namlen); ++ *--dirp = '/'; + + thisdev = dotdev; + thisino = dotino; +--- cvs-1.12.13+real.orig/lib/getdate.c ++++ cvs-1.12.13+real/lib/getdate.c +@@ -1,7 +1,9 @@ +-/* A Bison parser, made by GNU Bison 1.875c. */ ++/* A Bison parser, made by GNU Bison 2.3. */ + +-/* Skeleton parser for Yacc-like parsing with Bison, +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++/* Skeleton implementation for Bison's Yacc-like parsers in C ++ ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ++ Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -15,16 +17,24 @@ + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software +- Foundation, Inc., 59 Temple Place - Suite 330, +- Boston, MA 02111-1307, USA. */ ++ Foundation, Inc., 51 Franklin Street, Fifth Floor, ++ Boston, MA 02110-1301, USA. */ ++ ++/* As a special exception, you may create a larger work that contains ++ part or all of the Bison parser skeleton and distribute that work ++ under terms of your choice, so long as that work isn't itself a ++ parser generator using the skeleton or a modified version thereof ++ as a parser skeleton. Alternatively, if you modify or redistribute ++ the parser skeleton itself, you may (at your option) remove this ++ special exception, which will cause the skeleton and the resulting ++ Bison output files to be licensed under the GNU General Public ++ License without this special exception. + +-/* As a special exception, when this file is copied by Bison into a +- Bison output file, you may use that output file without restriction. +- This special exception was added by the Free Software Foundation +- in version 1.24 of Bison. */ ++ This special exception was added by the Free Software Foundation in ++ version 2.2 of Bison. */ + +-/* Written by Richard Stallman by simplifying the original so called +- ``semantic'' parser. */ ++/* C LALR(1) parser skeleton written by Richard Stallman, by ++ simplifying the original so-called "semantic" parser. */ + + /* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local +@@ -36,6 +46,9 @@ + /* Identify Bison output. */ + #define YYBISON 1 + ++/* Bison version. */ ++#define YYBISON_VERSION "2.3" ++ + /* Skeleton name. */ + #define YYSKELETON_NAME "yacc.c" + +@@ -74,6 +87,7 @@ + tUDECIMAL_NUMBER = 276 + }; + #endif ++/* Tokens. */ + #define tAGO 258 + #define tDST 259 + #define tDAY 260 +@@ -102,8 +116,11 @@ + + /* Parse a string into an internal time stamp. + +- Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Free Software +- Foundation, Inc. ++ Copyright (C) 1995, 1997, 1998, 2003, 2004, 2005 ++ Free Software Foundation, Inc. ++ ++ Copyright (c) 2005, 2006, 2007, 2010, 2016, 2017, 2021 ++ mirabilos <m@mirbsd.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -139,6 +156,10 @@ + + #include "getdate.h" + ++#ifdef USE_LIBBSD ++size_t strlcat(char *, const char *, size_t); ++#endif ++ + /* There's no need to extend the stack, so there's no need to involve + alloca. */ + #define YYSTACK_USE_ALLOCA 0 +@@ -166,10 +187,44 @@ + #include <stdlib.h> + #include <string.h> + ++#ifndef _STDLIB_H ++#define _STDLIB_H 1 /* GNU bison needs this */ ++#endif ++ ++#ifndef IN_RCS + #include "setenv.h" + #include "xalloc.h" ++#else /* IN_RCS */ ++#include <unistd.h> ++ ++#define HAVE_STRUCT_TM_TM_ZONE 1 ++#define HAVE_TM_GMTOFF 1 ++ ++#define gettime(ts) clock_gettime(CLOCK_REALTIME,(ts)) + +-#if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII) ++static void * ++xmalloc(size_t s) ++{ ++ static const char xmalloc_enomem[] = "memory exhausted\n"; ++ void *x; ++ ++ if ((x = malloc(s)) == NULL) { ++ write(2, xmalloc_enomem, sizeof(xmalloc_enomem) - 1); ++ exit(1); ++ } ++ ++ return (x); ++} ++ ++static void * ++xmemdup(void const *p, size_t s) ++{ ++ return (memcpy(xmalloc(s), p, s)); ++} ++#endif /* IN_RCS */ ++ ++#if (defined(STDC_HEADERS) && STDC_HEADERS) || \ ++ (!defined(isascii) && !HAVE_ISASCII) + # define IN_CTYPE_DOMAIN(c) 1 + #else + # define IN_CTYPE_DOMAIN(c) isascii (c) +@@ -188,7 +243,8 @@ + of `digit' even when the host does not conform to POSIX. */ + #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) + +-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ ++#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || \ ++ (defined(__STRICT_ANSI__) && __STRICT_ANSI__) + # define __attribute__(x) + #endif + +@@ -196,6 +252,15 @@ + # define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) + #endif + ++#ifndef __IDSTRING ++#define __IDSTRING(varname, string) \ ++ static const char varname[] __attribute__((__used__)) = \ ++ "@(""#)" #varname ": " string ++#endif ++ ++__IDSTRING(rcsid_code, "$MirOS: src/gnu/usr.bin/cvs/lib/getdate.c,v 1.19 2021/01/30 02:30:17 tg Exp $"); ++__IDSTRING(rcsid_bron, "$miros: src/gnu/usr.bin/cvs/lib/getdate.y,v 1.14 2021/01/30 02:28:27 tg Exp $"); ++ + /* Shift A right by B bits portably, by dividing A by 2**B and + truncating towards minus infinity. A and B should be free of side + effects, and B should be in the range 0 <= B <= INT_BITS - 2, where +@@ -292,7 +357,7 @@ + + union YYSTYPE; + static int yylex (union YYSTYPE *, parser_control *); +-static int yyerror (parser_control *, char *); ++static int yyerror (parser_control *, const char *); + static long int time_zone_hhmm (textint, long int); + + +@@ -310,15 +375,22 @@ + # define YYERROR_VERBOSE 0 + #endif + +-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +-#line 209 "getdate.y" +-typedef union YYSTYPE { ++/* Enabling the token table. */ ++#ifndef YYTOKEN_TABLE ++# define YYTOKEN_TABLE 0 ++#endif ++ ++#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED ++typedef union YYSTYPE ++#line 260 "getdate.y" ++{ + long int intval; + textint textintval; + struct timespec timespec; +-} YYSTYPE; +-/* Line 191 of yacc.c. */ +-#line 322 "getdate.c" ++} ++/* Line 193 of yacc.c. */ ++#line 393 "getdate.c" ++ YYSTYPE; + # define yystype YYSTYPE /* obsolescent; will be withdrawn */ + # define YYSTYPE_IS_DECLARED 1 + # define YYSTYPE_IS_TRIVIAL 1 +@@ -329,56 +401,171 @@ + /* Copy the second part of user declarations. */ + + +-/* Line 214 of yacc.c. */ +-#line 334 "getdate.c" ++/* Line 216 of yacc.c. */ ++#line 406 "getdate.c" ++ ++#ifdef short ++# undef short ++#endif ++ ++#ifdef YYTYPE_UINT8 ++typedef YYTYPE_UINT8 yytype_uint8; ++#else ++typedef unsigned char yytype_uint8; ++#endif ++ ++#ifdef YYTYPE_INT8 ++typedef YYTYPE_INT8 yytype_int8; ++#elif (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++typedef signed char yytype_int8; ++#else ++typedef short int yytype_int8; ++#endif ++ ++#ifdef YYTYPE_UINT16 ++typedef YYTYPE_UINT16 yytype_uint16; ++#else ++typedef unsigned short int yytype_uint16; ++#endif ++ ++#ifdef YYTYPE_INT16 ++typedef YYTYPE_INT16 yytype_int16; ++#else ++typedef short int yytype_int16; ++#endif ++ ++#ifndef YYSIZE_T ++# ifdef __SIZE_TYPE__ ++# define YYSIZE_T __SIZE_TYPE__ ++# elif defined size_t ++# define YYSIZE_T size_t ++# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ ++# define YYSIZE_T size_t ++# else ++# define YYSIZE_T unsigned int ++# endif ++#endif + +-#if ! defined (yyoverflow) || YYERROR_VERBOSE ++#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +-# ifndef YYFREE +-# define YYFREE free ++#ifndef YY_ ++# if defined(YYENABLE_NLS) && YYENABLE_NLS ++# if ENABLE_NLS ++# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ ++# define YY_(msgid) dgettext ("bison-runtime", msgid) ++# endif + # endif +-# ifndef YYMALLOC +-# define YYMALLOC malloc ++# ifndef YY_ ++# define YY_(msgid) msgid + # endif ++#endif ++ ++/* Suppress unused-variable warnings by "using" E. */ ++#if ! defined lint || defined __GNUC__ ++# define YYUSE(e) ((void) (e)) ++#else ++# define YYUSE(e) /* empty */ ++#endif ++ ++/* Identity function, used to suppress warnings about constant conditions. */ ++#ifndef lint ++# define YYID(n) (n) ++#else ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++static int ++YYID (int i) ++#else ++static int ++YYID (i) ++ int i; ++#endif ++{ ++ return i; ++} ++#endif ++ ++#if ! defined yyoverflow || YYERROR_VERBOSE + + /* The parser invokes alloca or malloc; define the necessary symbols. */ + + # ifdef YYSTACK_USE_ALLOCA + # if YYSTACK_USE_ALLOCA +-# define YYSTACK_ALLOC alloca +-# endif +-# else +-# if defined (alloca) || defined (_ALLOCA_H) +-# define YYSTACK_ALLOC alloca +-# else + # ifdef __GNUC__ + # define YYSTACK_ALLOC __builtin_alloca ++# elif defined __BUILTIN_VA_ARG_INCR ++# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ ++# elif defined _AIX ++# define YYSTACK_ALLOC __alloca ++# elif defined _MSC_VER ++# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ ++# define alloca _alloca ++# else ++# define YYSTACK_ALLOC alloca ++# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ ++# ifndef _STDLIB_H ++# define _STDLIB_H 1 ++# endif ++# endif + # endif + # endif + # endif + + # ifdef YYSTACK_ALLOC +- /* Pacify GCC's `empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +-# else +-# if defined (__STDC__) || defined (__cplusplus) +-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t ++ /* Pacify GCC's `empty if-body' warning. */ ++# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) ++# ifndef YYSTACK_ALLOC_MAXIMUM ++ /* The OS might guarantee only one guard page at the bottom of the stack, ++ and a page size can be as small as 4096 bytes. So we cannot safely ++ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number ++ to allow for a few compiler-allocated temporary stack slots. */ ++# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ + # endif ++# else + # define YYSTACK_ALLOC YYMALLOC + # define YYSTACK_FREE YYFREE ++# ifndef YYSTACK_ALLOC_MAXIMUM ++# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM ++# endif ++# if (defined __cplusplus && ! defined _STDLIB_H \ ++ && ! ((defined YYMALLOC || defined malloc) \ ++ && (defined YYFREE || defined free))) ++# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ ++# ifndef _STDLIB_H ++# define _STDLIB_H 1 ++# endif ++# endif ++# ifndef YYMALLOC ++# define YYMALLOC malloc ++# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ ++# endif ++# endif ++# ifndef YYFREE ++# define YYFREE free ++# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++void free (void *); /* INFRINGES ON USER NAME SPACE */ ++# endif ++# endif + # endif +-#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ ++#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +-#if (! defined (yyoverflow) \ +- && (! defined (__cplusplus) \ +- || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) ++#if (! defined yyoverflow \ ++ && (! defined __cplusplus \ ++ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + + /* A type that is properly aligned for any stack member. */ + union yyalloc + { +- short yyss; ++ yytype_int16 yyss; + YYSTYPE yyvs; + }; + +@@ -388,24 +575,24 @@ + /* The size of an array large to enough to hold all stacks, each with + N elements. */ + # define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ ++ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + + /* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ + # ifndef YYCOPY +-# if defined (__GNUC__) && 1 < __GNUC__ ++# if defined __GNUC__ && 1 < __GNUC__ + # define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) + # else + # define YYCOPY(To, From, Count) \ + do \ + { \ +- register YYSIZE_T yyi; \ ++ YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ +- while (0) ++ while (YYID (0)) + # endif + # endif + +@@ -423,39 +610,33 @@ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ +- while (0) ++ while (YYID (0)) + + #endif + +-#if defined (__STDC__) || defined (__cplusplus) +- typedef signed char yysigned_char; +-#else +- typedef short yysigned_char; +-#endif +- +-/* YYFINAL -- State number of the termination state. */ ++/* YYFINAL -- State number of the termination state. */ + #define YYFINAL 12 + /* YYLAST -- Last index in YYTABLE. */ + #define YYLAST 88 + +-/* YYNTOKENS -- Number of terminals. */ ++/* YYNTOKENS -- Number of terminals. */ + #define YYNTOKENS 26 +-/* YYNNTS -- Number of nonterminals. */ ++/* YYNNTS -- Number of nonterminals. */ + #define YYNNTS 19 +-/* YYNRULES -- Number of rules. */ ++/* YYNRULES -- Number of rules. */ + #define YYNRULES 78 +-/* YYNRULES -- Number of states. */ ++/* YYNRULES -- Number of states. */ + #define YYNSTATES 96 + + /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ + #define YYUNDEFTOK 2 + #define YYMAXUTOK 276 + +-#define YYTRANSLATE(YYX) \ ++#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + + /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +-static const unsigned char yytranslate[] = ++static const yytype_uint8 yytranslate[] = + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +@@ -490,7 +671,7 @@ + #if YYDEBUG + /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +-static const unsigned char yyprhs[] = ++static const yytype_uint8 yyprhs[] = + { + 0, 0, 3, 5, 7, 10, 11, 14, 16, 18, + 20, 22, 24, 26, 28, 31, 36, 42, 49, 57, +@@ -502,8 +683,8 @@ + 207, 209, 211, 213, 215, 217, 218, 221, 222 + }; + +-/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +-static const yysigned_char yyrhs[] = ++/* YYRHS -- A `-1'-separated list of the rules' RHS. */ ++static const yytype_int8 yyrhs[] = + { + 27, 0, -1, 28, -1, 29, -1, 22, 39, -1, + -1, 29, 30, -1, 31, -1, 32, -1, 33, -1, +@@ -531,22 +712,22 @@ + }; + + /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +-static const unsigned short yyrline[] = ++static const yytype_uint16 yyrline[] = + { +- 0, 230, 230, 231, 235, 242, 244, 248, 250, 252, +- 254, 256, 258, 260, 264, 272, 280, 290, 297, 309, +- 314, 322, 324, 326, 328, 330, 335, 340, 345, 350, +- 358, 363, 383, 390, 398, 406, 411, 417, 422, 431, +- 441, 445, 447, 449, 451, 453, 455, 457, 459, 461, +- 463, 465, 467, 469, 471, 473, 475, 477, 479, 481, +- 483, 485, 489, 491, 493, 495, 497, 499, 503, 503, +- 506, 507, 512, 513, 518, 556, 557, 563, 564 ++ 0, 281, 281, 282, 286, 293, 295, 299, 301, 303, ++ 305, 307, 309, 311, 315, 323, 331, 341, 348, 360, ++ 365, 373, 375, 377, 379, 381, 386, 391, 396, 401, ++ 409, 414, 434, 441, 449, 457, 462, 468, 473, 482, ++ 492, 496, 498, 500, 502, 504, 506, 508, 510, 512, ++ 514, 516, 518, 520, 522, 524, 526, 528, 530, 532, ++ 534, 536, 540, 542, 544, 546, 548, 550, 554, 554, ++ 557, 558, 563, 564, 569, 607, 608, 614, 615 + }; + #endif + +-#if YYDEBUG || YYERROR_VERBOSE +-/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +- First, the terminals, then, starting at YYNTOKENS, nonterminals. */ ++#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE ++/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. ++ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ + static const char *const yytname[] = + { + "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT", +@@ -563,7 +744,7 @@ + # ifdef YYPRINT + /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +-static const unsigned short yytoknum[] = ++static const yytype_uint16 yytoknum[] = + { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +@@ -572,7 +753,7 @@ + # endif + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const unsigned char yyr1[] = ++static const yytype_uint8 yyr1[] = + { + 0, 26, 27, 27, 28, 29, 29, 30, 30, 30, + 30, 30, 30, 30, 31, 31, 31, 31, 31, 32, +@@ -585,7 +766,7 @@ + }; + + /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +-static const unsigned char yyr2[] = ++static const yytype_uint8 yyr2[] = + { + 0, 2, 1, 1, 2, 0, 2, 1, 1, 1, + 1, 1, 1, 1, 2, 4, 5, 6, 7, 1, +@@ -600,7 +781,7 @@ + /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +-static const unsigned char yydefact[] = ++static const yytype_uint8 yydefact[] = + { + 5, 0, 0, 2, 3, 71, 73, 70, 72, 4, + 68, 69, 1, 26, 49, 24, 52, 19, 55, 0, +@@ -614,8 +795,8 @@ + 16, 77, 31, 75, 17, 18 + }; + +-/* YYDEFGOTO[NTERM-NUM]. */ +-static const yysigned_char yydefgoto[] = ++/* YYDEFGOTO[NTERM-NUM]. */ ++static const yytype_int8 yydefgoto[] = + { + -1, 2, 3, 4, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 9, 10, 11, 38, 77, 88 +@@ -624,7 +805,7 @@ + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ + #define YYPACT_NINF -43 +-static const yysigned_char yypact[] = ++static const yytype_int8 yypact[] = + { + -18, 48, 9, -43, 19, -43, -43, -43, -43, -43, + -43, -43, -43, 32, -43, -43, -43, 54, -43, 28, +@@ -639,7 +820,7 @@ + }; + + /* YYPGOTO[NTERM-NUM]. */ +-static const yysigned_char yypgoto[] = ++static const yytype_int8 yypgoto[] = + { + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, 55, -43, -43, -11, -43, -42, -7 +@@ -650,7 +831,7 @@ + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ + #define YYTABLE_NINF -1 +-static const unsigned char yytable[] = ++static const yytype_uint8 yytable[] = + { + 59, 60, 50, 61, 1, 62, 63, 64, 65, 12, + 66, 67, 53, 68, 54, 85, 51, 55, 69, 56, +@@ -663,7 +844,7 @@ + 81, 82, 83, 84, 94, 92, 0, 0, 76 + }; + +-static const yysigned_char yycheck[] = ++static const yytype_int8 yycheck[] = + { + 5, 6, 4, 8, 22, 10, 11, 12, 13, 0, + 15, 16, 6, 18, 8, 10, 18, 11, 23, 13, +@@ -678,7 +859,7 @@ + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +-static const unsigned char yystos[] = ++static const yytype_uint8 yystos[] = + { + 0, 22, 27, 28, 29, 18, 19, 20, 21, 39, + 40, 41, 0, 5, 6, 7, 8, 9, 11, 12, +@@ -692,22 +873,6 @@ + 43, 41, 19, 18, 44, 43 + }; + +-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +-# define YYSIZE_T __SIZE_TYPE__ +-#endif +-#if ! defined (YYSIZE_T) && defined (size_t) +-# define YYSIZE_T size_t +-#endif +-#if ! defined (YYSIZE_T) +-# if defined (__STDC__) || defined (__cplusplus) +-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t +-# endif +-#endif +-#if ! defined (YYSIZE_T) +-# define YYSIZE_T unsigned int +-#endif +- + #define yyerrok (yyerrstatus = 0) + #define yyclearin (yychar = YYEMPTY) + #define YYEMPTY (-2) +@@ -733,30 +898,63 @@ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ +- YYPOPSTACK; \ ++ YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ +- { \ +- yyerror (pc, "syntax error: cannot back up");\ ++ { \ ++ yyerror (pc, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +-while (0) ++while (YYID (0)) ++ + + #define YYTERROR 1 + #define YYERRCODE 256 + +-/* YYLLOC_DEFAULT -- Compute the default location (before the actions +- are run). */ + ++/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. ++ If N is 0, then set CURRENT to the empty location which ends ++ the previous symbol: RHS[0] (always defined). */ ++ ++#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + #ifndef YYLLOC_DEFAULT +-# define YYLLOC_DEFAULT(Current, Rhs, N) \ +- ((Current).first_line = (Rhs)[1].first_line, \ +- (Current).first_column = (Rhs)[1].first_column, \ +- (Current).last_line = (Rhs)[N].last_line, \ +- (Current).last_column = (Rhs)[N].last_column) ++# define YYLLOC_DEFAULT(Current, Rhs, N) \ ++ do \ ++ if (YYID (N)) \ ++ { \ ++ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ ++ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ ++ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ ++ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ ++ } \ ++ else \ ++ { \ ++ (Current).first_line = (Current).last_line = \ ++ YYRHSLOC (Rhs, 0).last_line; \ ++ (Current).first_column = (Current).last_column = \ ++ YYRHSLOC (Rhs, 0).last_column; \ ++ } \ ++ while (YYID (0)) ++#endif ++ ++ ++/* YY_LOCATION_PRINT -- Print the location on the stream. ++ This macro was not mandated originally: define only if we know ++ we won't break user code: when these are the locations we know. */ ++ ++#ifndef YY_LOCATION_PRINT ++# if defined(YYLTYPE_IS_TRIVIAL) && YYLTYPE_IS_TRIVIAL ++# define YY_LOCATION_PRINT(File, Loc) \ ++ fprintf (File, "%d.%d-%d.%d", \ ++ (Loc).first_line, (Loc).first_column, \ ++ (Loc).last_line, (Loc).last_column) ++# else ++# define YY_LOCATION_PRINT(File, Loc) ((void) 0) ++# endif + #endif + ++ + /* YYLEX -- calling `yylex' with the right arguments. */ + + #ifdef YYLEX_PARAM +@@ -777,42 +975,99 @@ + do { \ + if (yydebug) \ + YYFPRINTF Args; \ +-} while (0) ++} while (YYID (0)) + +-# define YYDSYMPRINT(Args) \ +-do { \ +- if (yydebug) \ +- yysymprint Args; \ +-} while (0) ++# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ ++do { \ ++ if (yydebug) \ ++ { \ ++ YYFPRINTF (stderr, "%s ", Title); \ ++ yy_symbol_print (stderr, \ ++ Type, Value, pc); \ ++ YYFPRINTF (stderr, "\n"); \ ++ } \ ++} while (YYID (0)) ++ ++ ++/*--------------------------------. ++| Print this symbol on YYOUTPUT. | ++`--------------------------------*/ ++ ++/*ARGSUSED*/ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++static void ++yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_control *pc) ++#else ++static void ++yy_symbol_value_print (yyoutput, yytype, yyvaluep, pc) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE const * const yyvaluep; ++ parser_control *pc; ++#endif ++{ ++ if (!yyvaluep) ++ return; ++ YYUSE (pc); ++# ifdef YYPRINT ++ if (yytype < YYNTOKENS) ++ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); ++# else ++ YYUSE (yyoutput); ++# endif ++ switch (yytype) ++ { ++ default: ++ break; ++ } ++} + +-# define YYDSYMPRINTF(Title, Token, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yysymprint (stderr, \ +- Token, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (0) ++ ++/*--------------------------------. ++| Print this symbol on YYOUTPUT. | ++`--------------------------------*/ ++ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++static void ++yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_control *pc) ++#else ++static void ++yy_symbol_print (yyoutput, yytype, yyvaluep, pc) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE const * const yyvaluep; ++ parser_control *pc; ++#endif ++{ ++ if (yytype < YYNTOKENS) ++ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); ++ else ++ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); ++ ++ yy_symbol_value_print (yyoutput, yytype, yyvaluep, pc); ++ YYFPRINTF (yyoutput, ")"); ++} + + /*------------------------------------------------------------------. + | yy_stack_print -- Print the state stack from its BOTTOM up to its | + | TOP (included). | + `------------------------------------------------------------------*/ + +-#if defined (__STDC__) || defined (__cplusplus) ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void +-yy_stack_print (short *bottom, short *top) ++yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) + #else + static void + yy_stack_print (bottom, top) +- short *bottom; +- short *top; ++ yytype_int16 *bottom; ++ yytype_int16 *top; + #endif + { + YYFPRINTF (stderr, "Stack now"); +- for (/* Nothing. */; bottom <= top; ++bottom) ++ for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); + } +@@ -821,45 +1076,53 @@ + do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +-} while (0) ++} while (YYID (0)) + + + /*------------------------------------------------. + | Report that the YYRULE is going to be reduced. | + `------------------------------------------------*/ + +-#if defined (__STDC__) || defined (__cplusplus) ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void +-yy_reduce_print (int yyrule) ++yy_reduce_print (YYSTYPE *yyvsp, int yyrule, parser_control *pc) + #else + static void +-yy_reduce_print (yyrule) ++yy_reduce_print (yyvsp, yyrule, pc) ++ YYSTYPE *yyvsp; + int yyrule; ++ parser_control *pc; + #endif + { ++ int yynrhs = yyr2[yyrule]; + int yyi; +- unsigned int yylno = yyrline[yyrule]; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", +- yyrule - 1, yylno); +- /* Print the symbols being reduced, and their result. */ +- for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) +- YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); +- YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); ++ unsigned long int yylno = yyrline[yyrule]; ++ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", ++ yyrule - 1, yylno); ++ /* The symbols being reduced. */ ++ for (yyi = 0; yyi < yynrhs; yyi++) ++ { ++ fprintf (stderr, " $%d = ", yyi + 1); ++ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], ++ &(yyvsp[(yyi + 1) - (yynrhs)]) ++ , pc); ++ fprintf (stderr, "\n"); ++ } + } + + # define YY_REDUCE_PRINT(Rule) \ + do { \ + if (yydebug) \ +- yy_reduce_print (Rule); \ +-} while (0) ++ yy_reduce_print (yyvsp, Rule, pc); \ ++} while (YYID (0)) + + /* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ + int yydebug; + #else /* !YYDEBUG */ + # define YYDPRINTF(Args) +-# define YYDSYMPRINT(Args) +-# define YYDSYMPRINTF(Title, Token, Value, Location) ++# define YY_SYMBOL_PRINT(Title, Type, Value, Location) + # define YY_STACK_PRINT(Bottom, Top) + # define YY_REDUCE_PRINT(Rule) + #endif /* !YYDEBUG */ +@@ -874,13 +1137,9 @@ + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if +- SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) ++ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +-#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 +-# undef YYMAXDEPTH +-#endif +- + #ifndef YYMAXDEPTH + # define YYMAXDEPTH 10000 + #endif +@@ -890,45 +1149,47 @@ + #if YYERROR_VERBOSE + + # ifndef yystrlen +-# if defined (__GLIBC__) && defined (_STRING_H) ++# if defined __GLIBC__ && defined _STRING_H + # define yystrlen strlen + # else + /* Return the length of YYSTR. */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static YYSIZE_T +-# if defined (__STDC__) || defined (__cplusplus) + yystrlen (const char *yystr) +-# else ++#else ++static YYSIZE_T + yystrlen (yystr) +- const char *yystr; +-# endif ++ const char *yystr; ++#endif + { +- register const char *yys = yystr; +- +- while (*yys++ != '\0') ++ YYSIZE_T yylen; ++ for (yylen = 0; yystr[yylen]; yylen++) + continue; +- +- return yys - yystr - 1; ++ return yylen; + } + # endif + # endif + + # ifndef yystpcpy +-# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) ++# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE + # define yystpcpy stpcpy + # else + /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static char * +-# if defined (__STDC__) || defined (__cplusplus) + yystpcpy (char *yydest, const char *yysrc) +-# else ++#else ++static char * + yystpcpy (yydest, yysrc) +- char *yydest; +- const char *yysrc; +-# endif ++ char *yydest; ++ const char *yysrc; ++#endif + { +- register char *yyd = yydest; +- register const char *yys = yysrc; ++ char *yyd = yydest; ++ const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; +@@ -938,70 +1199,194 @@ + # endif + # endif + +-#endif /* !YYERROR_VERBOSE */ ++# ifndef yytnamerr ++/* Copy to YYRES the contents of YYSTR after stripping away unnecessary ++ quotes and backslashes, so that it's suitable for yyerror. The ++ heuristic is that double-quoting is unnecessary unless the string ++ contains an apostrophe, a comma, or backslash (other than ++ backslash-backslash). YYSTR is taken from yytname. If YYRES is ++ null, do not copy; instead, return the length of what the result ++ would have been. */ ++static YYSIZE_T ++yytnamerr (char *yyres, const char *yystr) ++{ ++ if (*yystr == '"') ++ { ++ YYSIZE_T yyn = 0; ++ char const *yyp = yystr; ++ ++ for (;;) ++ switch (*++yyp) ++ { ++ case '\'': ++ case ',': ++ goto do_not_strip_quotes; ++ ++ case '\\': ++ if (*++yyp != '\\') ++ goto do_not_strip_quotes; ++ /* Fall through. */ ++ default: ++ if (yyres) ++ yyres[yyn] = *yyp; ++ yyn++; ++ break; + +- ++ case '"': ++ if (yyres) ++ yyres[yyn] = '\0'; ++ return yyn; ++ } ++ do_not_strip_quotes: ; ++ } + +-#if YYDEBUG +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ ++ if (! yyres) ++ return yystrlen (yystr); + +-#if defined (__STDC__) || defined (__cplusplus) +-static void +-yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +-#else +-static void +-yysymprint (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE *yyvaluep; +-#endif ++ return yystpcpy (yyres, yystr) - yyres; ++} ++# endif ++ ++/* Copy into YYRESULT an error message about the unexpected token ++ YYCHAR while in state YYSTATE. Return the number of bytes copied, ++ including the terminating null byte. If YYRESULT is null, do not ++ copy anything; just return the number of bytes that would be ++ copied. As a special case, return 0 if an ordinary "syntax error" ++ message will do. Return YYSIZE_MAXIMUM if overflow occurs during ++ size calculation. */ ++static YYSIZE_T ++yysyntax_error (char *yyresult, int yystate, int yychar) + { +- /* Pacify ``unused variable'' warnings. */ +- (void) yyvaluep; ++ int yyn = yypact[yystate]; + +- if (yytype < YYNTOKENS) ++ if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) ++ return 0; ++ else + { +- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +-# ifdef YYPRINT +- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); ++ int yytype = YYTRANSLATE (yychar); ++ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); ++ YYSIZE_T yysize = yysize0; ++ YYSIZE_T yysize1; ++ int yysize_overflow = 0; ++ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; ++ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; ++ int yyx; ++ ++# if 0 ++ /* This is so xgettext sees the translatable formats that are ++ constructed on the fly. */ ++ YY_("syntax error, unexpected %s"); ++ YY_("syntax error, unexpected %s, expecting %s"); ++ YY_("syntax error, unexpected %s, expecting %s or %s"); ++ YY_("syntax error, unexpected %s, expecting %s or %s or %s"); ++ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); + # endif +- } +- else +- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); ++ char *yyfmt; ++ char const *yyf; ++ static char const yyunexpected[] = "syntax error, unexpected %s"; ++ static char const yyexpecting[] = ", expecting %s"; ++ static char const yyor[] = " or %s"; ++ char yyformat[sizeof yyunexpected ++ + sizeof yyexpecting - 1 ++ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) ++ * (sizeof yyor - 1))]; ++ char const *yyprefix = yyexpecting; ++ ++ /* Start YYX at -YYN if negative to avoid negative indexes in ++ YYCHECK. */ ++ int yyxbegin = yyn < 0 ? -yyn : 0; ++ ++ /* Stay within bounds of both yycheck and yytname. */ ++ int yychecklim = YYLAST - yyn + 1; ++ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; ++ int yycount = 1; + +- switch (yytype) +- { +- default: +- break; ++ yyarg[0] = yytname[yytype]; ++ yyfmt = yystpcpy (yyformat, yyunexpected); ++ ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) ++ { ++ yycount = 1; ++ yysize = yysize0; ++ yyformat[sizeof yyunexpected - 1] = '\0'; ++ break; ++ } ++ yyarg[yycount++] = yytname[yyx]; ++ yysize1 = yysize + yytnamerr (0, yytname[yyx]); ++ yysize_overflow |= (yysize1 < yysize); ++ yysize = yysize1; ++ yyfmt = yystpcpy (yyfmt, yyprefix); ++ yyprefix = yyor; ++ } ++ ++ yyf = YY_(yyformat); ++ yysize1 = yysize + yystrlen (yyf); ++ yysize_overflow |= (yysize1 < yysize); ++ yysize = yysize1; ++ ++ if (yysize_overflow) ++ return YYSIZE_MAXIMUM; ++ ++ if (yyresult) ++ { ++ /* Avoid sprintf, as that infringes on the user's name space. ++ Don't have undefined behavior even if the translation ++ produced a string with the wrong number of "%s"s. */ ++ char *yyp = yyresult; ++ int yyi = 0; ++ while ((*yyp = *yyf) != '\0') ++ { ++ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) ++ { ++ yyp += yytnamerr (yyp, yyarg[yyi++]); ++ yyf += 2; ++ } ++ else ++ { ++ yyp++; ++ yyf++; ++ } ++ } ++ } ++ return yysize; + } +- YYFPRINTF (yyoutput, ")"); + } ++#endif /* YYERROR_VERBOSE */ ++ + +-#endif /* ! YYDEBUG */ + /*-----------------------------------------------. + | Release the memory associated to this symbol. | + `-----------------------------------------------*/ + +-#if defined (__STDC__) || defined (__cplusplus) ++/*ARGSUSED*/ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void +-yydestruct (int yytype, YYSTYPE *yyvaluep) ++yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, parser_control *pc) + #else + static void +-yydestruct (yytype, yyvaluep) ++yydestruct (yymsg, yytype, yyvaluep, pc) ++ const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; ++ parser_control *pc; + #endif + { +- /* Pacify ``unused variable'' warnings. */ +- (void) yyvaluep; ++ YYUSE (yyvaluep); ++ YYUSE (pc); ++ ++ if (!yymsg) ++ yymsg = "Deleting"; ++ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: +- break; ++ break; + } + } + +@@ -1009,14 +1394,14 @@ + /* Prevent warnings from -Wmissing-prototypes. */ + + #ifdef YYPARSE_PARAM +-# if defined (__STDC__) || defined (__cplusplus) ++#if defined __STDC__ || defined __cplusplus + int yyparse (void *YYPARSE_PARAM); +-# else ++#else + int yyparse (); +-# endif ++#endif + #else /* ! YYPARSE_PARAM */ +-#if defined (__STDC__) || defined (__cplusplus) +-int yyparse ( parser_control *pc ); ++#if defined __STDC__ || defined __cplusplus ++int yyparse (parser_control *pc); + #else + int yyparse (); + #endif +@@ -1032,39 +1417,49 @@ + `----------*/ + + #ifdef YYPARSE_PARAM +-# if defined (__STDC__) || defined (__cplusplus) +-int yyparse (void *YYPARSE_PARAM) +-# else +-int yyparse (YYPARSE_PARAM) +- void *YYPARSE_PARAM; +-# endif ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++int ++yyparse (void *YYPARSE_PARAM) ++#else ++int ++yyparse (YYPARSE_PARAM) ++ void *YYPARSE_PARAM; ++#endif + #else /* ! YYPARSE_PARAM */ +-#if defined (__STDC__) || defined (__cplusplus) ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + int +-yyparse ( parser_control *pc ) ++yyparse (parser_control *pc) + #else + int + yyparse (pc) +- parser_control *pc ; ++ parser_control *pc; + #endif + #endif + { +- /* The lookahead symbol. */ ++ /* The look-ahead symbol. */ + int yychar; + +-/* The semantic value of the lookahead symbol. */ ++/* The semantic value of the look-ahead symbol. */ + YYSTYPE yylval; + + /* Number of syntax errors so far. */ + int yynerrs; + +- register int yystate; +- register int yyn; ++ int yystate; ++ int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; +- /* Lookahead token as an internal (translated) token number. */ ++ /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; ++#if YYERROR_VERBOSE ++ /* Buffer for error messages, and its allocated size. */ ++ char yymsgbuf[128]; ++ char *yymsg = yymsgbuf; ++ YYSIZE_T yymsg_alloc = sizeof yymsgbuf; ++#endif + + /* Three stacks and their tools: + `yyss': related to states, +@@ -1075,18 +1470,18 @@ + to reallocate them elsewhere. */ + + /* The state stack. */ +- short yyssa[YYINITDEPTH]; +- short *yyss = yyssa; +- register short *yyssp; ++ yytype_int16 yyssa[YYINITDEPTH]; ++ yytype_int16 *yyss = yyssa; ++ yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; +- register YYSTYPE *yyvsp; ++ YYSTYPE *yyvsp; + + + +-#define YYPOPSTACK (yyvsp--, yyssp--) ++#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + YYSIZE_T yystacksize = YYINITDEPTH; + +@@ -1095,9 +1490,9 @@ + YYSTYPE yyval; + + +- /* When reducing, the number of symbols on the RHS of the reduced +- rule. */ +- int yylen; ++ /* The number of symbols on the RHS of the reduced rule. ++ Keep to zero when no symbol should be popped. */ ++ int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + +@@ -1121,8 +1516,7 @@ + `------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks +- have just been pushed. so pushing a state here evens the stacks. +- */ ++ have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: +@@ -1135,18 +1529,18 @@ + + #ifdef yyoverflow + { +- /* Give user a chance to reallocate the stack. Use copies of ++ /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; +- short *yyss1 = yyss; ++ yytype_int16 *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ +- yyoverflow ("parser stack overflow", ++ yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + +@@ -1157,21 +1551,21 @@ + } + #else /* no yyoverflow */ + # ifndef YYSTACK_RELOCATE +- goto yyoverflowlab; ++ goto yyexhaustedlab; + # else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) +- goto yyoverflowlab; ++ goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { +- short *yyss1 = yyss; ++ yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) +- goto yyoverflowlab; ++ goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +@@ -1202,19 +1596,17 @@ + `-----------*/ + yybackup: + +-/* Do appropriate processing given the current state. */ +-/* Read a lookahead token if we need one and don't already have one. */ +-/* yyresume: */ +- +- /* First try to decide what to do without reference to lookahead token. */ ++ /* Do appropriate processing given the current state. Read a ++ look-ahead token if we need one and don't already have one. */ + ++ /* First try to decide what to do without reference to look-ahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + +- /* Not known => get a lookahead token if don't already have one. */ ++ /* Not known => get a look-ahead token if don't already have one. */ + +- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ ++ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); +@@ -1229,7 +1621,7 @@ + else + { + yytoken = YYTRANSLATE (yychar); +- YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); ++ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to +@@ -1249,22 +1641,21 @@ + if (yyn == YYFINAL) + YYACCEPT; + +- /* Shift the lookahead token. */ +- YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); +- +- /* Discard the token being shifted unless it is eof. */ +- if (yychar != YYEOF) +- yychar = YYEMPTY; +- +- *++yyvsp = yylval; +- +- + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + ++ /* Shift the look-ahead token. */ ++ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); ++ ++ /* Discard the shifted token unless it is eof. */ ++ if (yychar != YYEOF) ++ yychar = YYEMPTY; ++ + yystate = yyn; ++ *++yyvsp = yylval; ++ + goto yynewstate; + + +@@ -1300,272 +1691,272 @@ + switch (yyn) + { + case 4: +-#line 236 "getdate.y" ++#line 287 "getdate.y" + { +- pc->seconds = yyvsp[0].timespec; ++ pc->seconds = (yyvsp[(2) - (2)].timespec); + pc->timespec_seen = true; +- } ++ ;} + break; + + case 7: +-#line 249 "getdate.y" +- { pc->times_seen++; } ++#line 300 "getdate.y" ++ { pc->times_seen++; ;} + break; + + case 8: +-#line 251 "getdate.y" +- { pc->local_zones_seen++; } ++#line 302 "getdate.y" ++ { pc->local_zones_seen++; ;} + break; + + case 9: +-#line 253 "getdate.y" +- { pc->zones_seen++; } ++#line 304 "getdate.y" ++ { pc->zones_seen++; ;} + break; + + case 10: +-#line 255 "getdate.y" +- { pc->dates_seen++; } ++#line 306 "getdate.y" ++ { pc->dates_seen++; ;} + break; + + case 11: +-#line 257 "getdate.y" +- { pc->days_seen++; } ++#line 308 "getdate.y" ++ { pc->days_seen++; ;} + break; + + case 12: +-#line 259 "getdate.y" +- { pc->rels_seen = true; } ++#line 310 "getdate.y" ++ { pc->rels_seen = true; ;} + break; + + case 14: +-#line 265 "getdate.y" ++#line 316 "getdate.y" + { +- pc->hour = yyvsp[-1].textintval.value; ++ pc->hour = (yyvsp[(1) - (2)].textintval).value; + pc->minutes = 0; + pc->seconds.tv_sec = 0; + pc->seconds.tv_nsec = 0; +- pc->meridian = yyvsp[0].intval; +- } ++ pc->meridian = (yyvsp[(2) - (2)].intval); ++ ;} + break; + + case 15: +-#line 273 "getdate.y" ++#line 324 "getdate.y" + { +- pc->hour = yyvsp[-3].textintval.value; +- pc->minutes = yyvsp[-1].textintval.value; ++ pc->hour = (yyvsp[(1) - (4)].textintval).value; ++ pc->minutes = (yyvsp[(3) - (4)].textintval).value; + pc->seconds.tv_sec = 0; + pc->seconds.tv_nsec = 0; +- pc->meridian = yyvsp[0].intval; +- } ++ pc->meridian = (yyvsp[(4) - (4)].intval); ++ ;} + break; + + case 16: +-#line 281 "getdate.y" ++#line 332 "getdate.y" + { +- pc->hour = yyvsp[-4].textintval.value; +- pc->minutes = yyvsp[-2].textintval.value; ++ pc->hour = (yyvsp[(1) - (5)].textintval).value; ++ pc->minutes = (yyvsp[(3) - (5)].textintval).value; + pc->seconds.tv_sec = 0; + pc->seconds.tv_nsec = 0; + pc->meridian = MER24; + pc->zones_seen++; +- pc->time_zone = time_zone_hhmm (yyvsp[-1].textintval, yyvsp[0].intval); +- } ++ pc->time_zone = time_zone_hhmm ((yyvsp[(4) - (5)].textintval), (yyvsp[(5) - (5)].intval)); ++ ;} + break; + + case 17: +-#line 291 "getdate.y" ++#line 342 "getdate.y" + { +- pc->hour = yyvsp[-5].textintval.value; +- pc->minutes = yyvsp[-3].textintval.value; +- pc->seconds = yyvsp[-1].timespec; +- pc->meridian = yyvsp[0].intval; +- } ++ pc->hour = (yyvsp[(1) - (6)].textintval).value; ++ pc->minutes = (yyvsp[(3) - (6)].textintval).value; ++ pc->seconds = (yyvsp[(5) - (6)].timespec); ++ pc->meridian = (yyvsp[(6) - (6)].intval); ++ ;} + break; + + case 18: +-#line 298 "getdate.y" ++#line 349 "getdate.y" + { +- pc->hour = yyvsp[-6].textintval.value; +- pc->minutes = yyvsp[-4].textintval.value; +- pc->seconds = yyvsp[-2].timespec; ++ pc->hour = (yyvsp[(1) - (7)].textintval).value; ++ pc->minutes = (yyvsp[(3) - (7)].textintval).value; ++ pc->seconds = (yyvsp[(5) - (7)].timespec); + pc->meridian = MER24; + pc->zones_seen++; +- pc->time_zone = time_zone_hhmm (yyvsp[-1].textintval, yyvsp[0].intval); +- } ++ pc->time_zone = time_zone_hhmm ((yyvsp[(6) - (7)].textintval), (yyvsp[(7) - (7)].intval)); ++ ;} + break; + + case 19: +-#line 310 "getdate.y" ++#line 361 "getdate.y" + { +- pc->local_isdst = yyvsp[0].intval; +- pc->dsts_seen += (0 < yyvsp[0].intval); +- } ++ pc->local_isdst = (yyvsp[(1) - (1)].intval); ++ pc->dsts_seen += (0 < (yyvsp[(1) - (1)].intval)); ++ ;} + break; + + case 20: +-#line 315 "getdate.y" ++#line 366 "getdate.y" + { + pc->local_isdst = 1; +- pc->dsts_seen += (0 < yyvsp[-1].intval) + 1; +- } ++ pc->dsts_seen += (0 < (yyvsp[(1) - (2)].intval)) + 1; ++ ;} + break; + + case 21: +-#line 323 "getdate.y" +- { pc->time_zone = yyvsp[0].intval; } ++#line 374 "getdate.y" ++ { pc->time_zone = (yyvsp[(1) - (1)].intval); ;} + break; + + case 22: +-#line 325 "getdate.y" +- { pc->time_zone = yyvsp[-1].intval; pc->rels_seen = true; } ++#line 376 "getdate.y" ++ { pc->time_zone = (yyvsp[(1) - (2)].intval); pc->rels_seen = true; ;} + break; + + case 23: +-#line 327 "getdate.y" +- { pc->time_zone = yyvsp[-2].intval + time_zone_hhmm (yyvsp[-1].textintval, yyvsp[0].intval); } ++#line 378 "getdate.y" ++ { pc->time_zone = (yyvsp[(1) - (3)].intval) + time_zone_hhmm ((yyvsp[(2) - (3)].textintval), (yyvsp[(3) - (3)].intval)); ;} + break; + + case 24: +-#line 329 "getdate.y" +- { pc->time_zone = yyvsp[0].intval + 60; } ++#line 380 "getdate.y" ++ { pc->time_zone = (yyvsp[(1) - (1)].intval) + 60; ;} + break; + + case 25: +-#line 331 "getdate.y" +- { pc->time_zone = yyvsp[-1].intval + 60; } ++#line 382 "getdate.y" ++ { pc->time_zone = (yyvsp[(1) - (2)].intval) + 60; ;} + break; + + case 26: +-#line 336 "getdate.y" ++#line 387 "getdate.y" + { + pc->day_ordinal = 1; +- pc->day_number = yyvsp[0].intval; +- } ++ pc->day_number = (yyvsp[(1) - (1)].intval); ++ ;} + break; + + case 27: +-#line 341 "getdate.y" ++#line 392 "getdate.y" + { + pc->day_ordinal = 1; +- pc->day_number = yyvsp[-1].intval; +- } ++ pc->day_number = (yyvsp[(1) - (2)].intval); ++ ;} + break; + + case 28: +-#line 346 "getdate.y" ++#line 397 "getdate.y" + { +- pc->day_ordinal = yyvsp[-1].intval; +- pc->day_number = yyvsp[0].intval; +- } ++ pc->day_ordinal = (yyvsp[(1) - (2)].intval); ++ pc->day_number = (yyvsp[(2) - (2)].intval); ++ ;} + break; + + case 29: +-#line 351 "getdate.y" ++#line 402 "getdate.y" + { +- pc->day_ordinal = yyvsp[-1].textintval.value; +- pc->day_number = yyvsp[0].intval; +- } ++ pc->day_ordinal = (yyvsp[(1) - (2)].textintval).value; ++ pc->day_number = (yyvsp[(2) - (2)].intval); ++ ;} + break; + + case 30: +-#line 359 "getdate.y" ++#line 410 "getdate.y" + { +- pc->month = yyvsp[-2].textintval.value; +- pc->day = yyvsp[0].textintval.value; +- } ++ pc->month = (yyvsp[(1) - (3)].textintval).value; ++ pc->day = (yyvsp[(3) - (3)].textintval).value; ++ ;} + break; + + case 31: +-#line 364 "getdate.y" ++#line 415 "getdate.y" + { + /* Interpret as YYYY/MM/DD if the first value has 4 or more digits, + otherwise as MM/DD/YY. + The goal in recognizing YYYY/MM/DD is solely to support legacy + machine-generated dates like those in an RCS log listing. If + you want portability, use the ISO 8601 format. */ +- if (4 <= yyvsp[-4].textintval.digits) ++ if (4 <= (yyvsp[(1) - (5)].textintval).digits) + { +- pc->year = yyvsp[-4].textintval; +- pc->month = yyvsp[-2].textintval.value; +- pc->day = yyvsp[0].textintval.value; ++ pc->year = (yyvsp[(1) - (5)].textintval); ++ pc->month = (yyvsp[(3) - (5)].textintval).value; ++ pc->day = (yyvsp[(5) - (5)].textintval).value; + } + else + { +- pc->month = yyvsp[-4].textintval.value; +- pc->day = yyvsp[-2].textintval.value; +- pc->year = yyvsp[0].textintval; ++ pc->month = (yyvsp[(1) - (5)].textintval).value; ++ pc->day = (yyvsp[(3) - (5)].textintval).value; ++ pc->year = (yyvsp[(5) - (5)].textintval); + } +- } ++ ;} + break; + + case 32: +-#line 384 "getdate.y" ++#line 435 "getdate.y" + { + /* ISO 8601 format. YYYY-MM-DD. */ +- pc->year = yyvsp[-2].textintval; +- pc->month = -yyvsp[-1].textintval.value; +- pc->day = -yyvsp[0].textintval.value; +- } ++ pc->year = (yyvsp[(1) - (3)].textintval); ++ pc->month = -(yyvsp[(2) - (3)].textintval).value; ++ pc->day = -(yyvsp[(3) - (3)].textintval).value; ++ ;} + break; + + case 33: +-#line 391 "getdate.y" ++#line 442 "getdate.y" + { + /* e.g. 17-JUN-1992. */ +- pc->day = yyvsp[-2].textintval.value; +- pc->month = yyvsp[-1].intval; +- pc->year.value = -yyvsp[0].textintval.value; +- pc->year.digits = yyvsp[0].textintval.digits; +- } ++ pc->day = (yyvsp[(1) - (3)].textintval).value; ++ pc->month = (yyvsp[(2) - (3)].intval); ++ pc->year.value = -(yyvsp[(3) - (3)].textintval).value; ++ pc->year.digits = (yyvsp[(3) - (3)].textintval).digits; ++ ;} + break; + + case 34: +-#line 399 "getdate.y" ++#line 450 "getdate.y" + { + /* e.g. JUN-17-1992. */ +- pc->month = yyvsp[-2].intval; +- pc->day = -yyvsp[-1].textintval.value; +- pc->year.value = -yyvsp[0].textintval.value; +- pc->year.digits = yyvsp[0].textintval.digits; +- } ++ pc->month = (yyvsp[(1) - (3)].intval); ++ pc->day = -(yyvsp[(2) - (3)].textintval).value; ++ pc->year.value = -(yyvsp[(3) - (3)].textintval).value; ++ pc->year.digits = (yyvsp[(3) - (3)].textintval).digits; ++ ;} + break; + + case 35: +-#line 407 "getdate.y" ++#line 458 "getdate.y" + { +- pc->month = yyvsp[-1].intval; +- pc->day = yyvsp[0].textintval.value; +- } ++ pc->month = (yyvsp[(1) - (2)].intval); ++ pc->day = (yyvsp[(2) - (2)].textintval).value; ++ ;} + break; + + case 36: +-#line 412 "getdate.y" ++#line 463 "getdate.y" + { +- pc->month = yyvsp[-3].intval; +- pc->day = yyvsp[-2].textintval.value; +- pc->year = yyvsp[0].textintval; +- } ++ pc->month = (yyvsp[(1) - (4)].intval); ++ pc->day = (yyvsp[(2) - (4)].textintval).value; ++ pc->year = (yyvsp[(4) - (4)].textintval); ++ ;} + break; + + case 37: +-#line 418 "getdate.y" ++#line 469 "getdate.y" + { +- pc->day = yyvsp[-1].textintval.value; +- pc->month = yyvsp[0].intval; +- } ++ pc->day = (yyvsp[(1) - (2)].textintval).value; ++ pc->month = (yyvsp[(2) - (2)].intval); ++ ;} + break; + + case 38: +-#line 423 "getdate.y" ++#line 474 "getdate.y" + { +- pc->day = yyvsp[-2].textintval.value; +- pc->month = yyvsp[-1].intval; +- pc->year = yyvsp[0].textintval; +- } ++ pc->day = (yyvsp[(1) - (3)].textintval).value; ++ pc->month = (yyvsp[(2) - (3)].intval); ++ pc->year = (yyvsp[(3) - (3)].textintval); ++ ;} + break; + + case 39: +-#line 432 "getdate.y" ++#line 483 "getdate.y" + { + pc->rel_ns = -pc->rel_ns; + pc->rel_seconds = -pc->rel_seconds; +@@ -1574,216 +1965,215 @@ + pc->rel_day = -pc->rel_day; + pc->rel_month = -pc->rel_month; + pc->rel_year = -pc->rel_year; +- } ++ ;} + break; + + case 41: +-#line 446 "getdate.y" +- { pc->rel_year += yyvsp[-1].intval * yyvsp[0].intval; } ++#line 497 "getdate.y" ++ { pc->rel_year += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;} + break; + + case 42: +-#line 448 "getdate.y" +- { pc->rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 499 "getdate.y" ++ { pc->rel_year += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 43: +-#line 450 "getdate.y" +- { pc->rel_year += yyvsp[0].intval; } ++#line 501 "getdate.y" ++ { pc->rel_year += (yyvsp[(1) - (1)].intval); ;} + break; + + case 44: +-#line 452 "getdate.y" +- { pc->rel_month += yyvsp[-1].intval * yyvsp[0].intval; } ++#line 503 "getdate.y" ++ { pc->rel_month += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;} + break; + + case 45: +-#line 454 "getdate.y" +- { pc->rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 505 "getdate.y" ++ { pc->rel_month += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 46: +-#line 456 "getdate.y" +- { pc->rel_month += yyvsp[0].intval; } ++#line 507 "getdate.y" ++ { pc->rel_month += (yyvsp[(1) - (1)].intval); ;} + break; + + case 47: +-#line 458 "getdate.y" +- { pc->rel_day += yyvsp[-1].intval * yyvsp[0].intval; } ++#line 509 "getdate.y" ++ { pc->rel_day += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;} + break; + + case 48: +-#line 460 "getdate.y" +- { pc->rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 511 "getdate.y" ++ { pc->rel_day += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 49: +-#line 462 "getdate.y" +- { pc->rel_day += yyvsp[0].intval; } ++#line 513 "getdate.y" ++ { pc->rel_day += (yyvsp[(1) - (1)].intval); ;} + break; + + case 50: +-#line 464 "getdate.y" +- { pc->rel_hour += yyvsp[-1].intval * yyvsp[0].intval; } ++#line 515 "getdate.y" ++ { pc->rel_hour += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;} + break; + + case 51: +-#line 466 "getdate.y" +- { pc->rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 517 "getdate.y" ++ { pc->rel_hour += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 52: +-#line 468 "getdate.y" +- { pc->rel_hour += yyvsp[0].intval; } ++#line 519 "getdate.y" ++ { pc->rel_hour += (yyvsp[(1) - (1)].intval); ;} + break; + + case 53: +-#line 470 "getdate.y" +- { pc->rel_minutes += yyvsp[-1].intval * yyvsp[0].intval; } ++#line 521 "getdate.y" ++ { pc->rel_minutes += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;} + break; + + case 54: +-#line 472 "getdate.y" +- { pc->rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 523 "getdate.y" ++ { pc->rel_minutes += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 55: +-#line 474 "getdate.y" +- { pc->rel_minutes += yyvsp[0].intval; } ++#line 525 "getdate.y" ++ { pc->rel_minutes += (yyvsp[(1) - (1)].intval); ;} + break; + + case 56: +-#line 476 "getdate.y" +- { pc->rel_seconds += yyvsp[-1].intval * yyvsp[0].intval; } ++#line 527 "getdate.y" ++ { pc->rel_seconds += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;} + break; + + case 57: +-#line 478 "getdate.y" +- { pc->rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 529 "getdate.y" ++ { pc->rel_seconds += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 58: +-#line 480 "getdate.y" +- { pc->rel_seconds += yyvsp[-1].timespec.tv_sec * yyvsp[0].intval; pc->rel_ns += yyvsp[-1].timespec.tv_nsec * yyvsp[0].intval; } ++#line 531 "getdate.y" ++ { pc->rel_seconds += (yyvsp[(1) - (2)].timespec).tv_sec * (yyvsp[(2) - (2)].intval); pc->rel_ns += (yyvsp[(1) - (2)].timespec).tv_nsec * (yyvsp[(2) - (2)].intval); ;} + break; + + case 59: +-#line 482 "getdate.y" +- { pc->rel_seconds += yyvsp[-1].timespec.tv_sec * yyvsp[0].intval; pc->rel_ns += yyvsp[-1].timespec.tv_nsec * yyvsp[0].intval; } ++#line 533 "getdate.y" ++ { pc->rel_seconds += (yyvsp[(1) - (2)].timespec).tv_sec * (yyvsp[(2) - (2)].intval); pc->rel_ns += (yyvsp[(1) - (2)].timespec).tv_nsec * (yyvsp[(2) - (2)].intval); ;} + break; + + case 60: +-#line 484 "getdate.y" +- { pc->rel_seconds += yyvsp[0].intval; } ++#line 535 "getdate.y" ++ { pc->rel_seconds += (yyvsp[(1) - (1)].intval); ;} + break; + + case 62: +-#line 490 "getdate.y" +- { pc->rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 541 "getdate.y" ++ { pc->rel_year += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 63: +-#line 492 "getdate.y" +- { pc->rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 543 "getdate.y" ++ { pc->rel_month += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 64: +-#line 494 "getdate.y" +- { pc->rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 545 "getdate.y" ++ { pc->rel_day += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 65: +-#line 496 "getdate.y" +- { pc->rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 547 "getdate.y" ++ { pc->rel_hour += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 66: +-#line 498 "getdate.y" +- { pc->rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 549 "getdate.y" ++ { pc->rel_minutes += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 67: +-#line 500 "getdate.y" +- { pc->rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; } ++#line 551 "getdate.y" ++ { pc->rel_seconds += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;} + break; + + case 71: +-#line 508 "getdate.y" +- { yyval.timespec.tv_sec = yyvsp[0].textintval.value; yyval.timespec.tv_nsec = 0; } ++#line 559 "getdate.y" ++ { (yyval.timespec).tv_sec = (yyvsp[(1) - (1)].textintval).value; (yyval.timespec).tv_nsec = 0; ;} + break; + + case 73: +-#line 514 "getdate.y" +- { yyval.timespec.tv_sec = yyvsp[0].textintval.value; yyval.timespec.tv_nsec = 0; } ++#line 565 "getdate.y" ++ { (yyval.timespec).tv_sec = (yyvsp[(1) - (1)].textintval).value; (yyval.timespec).tv_nsec = 0; ;} + break; + + case 74: +-#line 519 "getdate.y" ++#line 570 "getdate.y" + { + if (pc->dates_seen && ! pc->year.digits +- && ! pc->rels_seen && (pc->times_seen || 2 < yyvsp[0].textintval.digits)) +- pc->year = yyvsp[0].textintval; ++ && ! pc->rels_seen && (pc->times_seen || 2 < (yyvsp[(1) - (1)].textintval).digits)) ++ pc->year = (yyvsp[(1) - (1)].textintval); + else + { +- if (4 < yyvsp[0].textintval.digits) ++ if (4 < (yyvsp[(1) - (1)].textintval).digits) + { + pc->dates_seen++; +- pc->day = yyvsp[0].textintval.value % 100; +- pc->month = (yyvsp[0].textintval.value / 100) % 100; +- pc->year.value = yyvsp[0].textintval.value / 10000; +- pc->year.digits = yyvsp[0].textintval.digits - 4; ++ pc->day = (yyvsp[(1) - (1)].textintval).value % 100; ++ pc->month = ((yyvsp[(1) - (1)].textintval).value / 100) % 100; ++ pc->year.value = (yyvsp[(1) - (1)].textintval).value / 10000; ++ pc->year.digits = (yyvsp[(1) - (1)].textintval).digits - 4; + } + else + { + pc->times_seen++; +- if (yyvsp[0].textintval.digits <= 2) ++ if ((yyvsp[(1) - (1)].textintval).digits <= 2) + { +- pc->hour = yyvsp[0].textintval.value; ++ pc->hour = (yyvsp[(1) - (1)].textintval).value; + pc->minutes = 0; + } + else + { +- pc->hour = yyvsp[0].textintval.value / 100; +- pc->minutes = yyvsp[0].textintval.value % 100; ++ pc->hour = (yyvsp[(1) - (1)].textintval).value / 100; ++ pc->minutes = (yyvsp[(1) - (1)].textintval).value % 100; + } + pc->seconds.tv_sec = 0; + pc->seconds.tv_nsec = 0; + pc->meridian = MER24; + } + } +- } ++ ;} + break; + + case 75: +-#line 556 "getdate.y" +- { yyval.intval = -1; } ++#line 607 "getdate.y" ++ { (yyval.intval) = -1; ;} + break; + + case 76: +-#line 558 "getdate.y" +- { yyval.intval = yyvsp[0].textintval.value; } ++#line 609 "getdate.y" ++ { (yyval.intval) = (yyvsp[(2) - (2)].textintval).value; ;} + break; + + case 77: +-#line 563 "getdate.y" +- { yyval.intval = MER24; } ++#line 614 "getdate.y" ++ { (yyval.intval) = MER24; ;} + break; + + case 78: +-#line 565 "getdate.y" +- { yyval.intval = yyvsp[0].intval; } ++#line 616 "getdate.y" ++ { (yyval.intval) = (yyvsp[(1) - (1)].intval); ;} + break; + + ++/* Line 1267 of yacc.c. */ ++#line 2171 "getdate.c" ++ default: break; + } ++ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + +-/* Line 1000 of yacc.c. */ +-#line 1782 "getdate.c" +- +- yyvsp -= yylen; +- yyssp -= yylen; +- +- ++ YYPOPSTACK (yylen); ++ yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; +@@ -1812,99 +2202,65 @@ + if (!yyerrstatus) + { + ++yynerrs; +-#if YYERROR_VERBOSE +- yyn = yypact[yystate]; +- +- if (YYPACT_NINF < yyn && yyn < YYLAST) +- { +- YYSIZE_T yysize = 0; +- int yytype = YYTRANSLATE (yychar); +- const char* yyprefix; +- char *yymsg; +- int yyx; +- +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yycount = 0; +- +- yyprefix = ", expecting "; +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++#if ! YYERROR_VERBOSE ++ yyerror (pc, YY_("syntax error")); ++#else ++ { ++ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); ++ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) ++ { ++ YYSIZE_T yyalloc = 2 * yysize; ++ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) ++ yyalloc = YYSTACK_ALLOC_MAXIMUM; ++ if (yymsg != yymsgbuf) ++ YYSTACK_FREE (yymsg); ++ yymsg = (char *) YYSTACK_ALLOC (yyalloc); ++ if (yymsg) ++ yymsg_alloc = yyalloc; ++ else + { +- yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); +- yycount += 1; +- if (yycount == 5) +- { +- yysize = 0; +- break; +- } ++ yymsg = yymsgbuf; ++ yymsg_alloc = sizeof yymsgbuf; + } +- yysize += (sizeof ("syntax error, unexpected ") +- + yystrlen (yytname[yytype])); +- yymsg = (char *) YYSTACK_ALLOC (yysize); +- if (yymsg != 0) +- { +- char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); +- yyp = yystpcpy (yyp, yytname[yytype]); ++ } + +- if (yycount < 5) +- { +- yyprefix = ", expecting "; +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) +- { +- yyp = yystpcpy (yyp, yyprefix); +- yyp = yystpcpy (yyp, yytname[yyx]); +- yyprefix = " or "; +- } +- } +- yyerror (pc, yymsg); +- YYSTACK_FREE (yymsg); +- } +- else +- yyerror (pc, "syntax error; also virtual memory exhausted"); +- } +- else +-#endif /* YYERROR_VERBOSE */ +- yyerror (pc, "syntax error"); ++ if (0 < yysize && yysize <= yymsg_alloc) ++ { ++ (void) yysyntax_error (yymsg, yystate, yychar); ++ yyerror (pc, yymsg); ++ } ++ else ++ { ++ yyerror (pc, YY_("syntax error")); ++ if (yysize != 0) ++ goto yyexhaustedlab; ++ } ++ } ++#endif + } + + + + if (yyerrstatus == 3) + { +- /* If just tried and failed to reuse lookahead token after an ++ /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= YYEOF) +- { +- /* If at end of input, pop the error token, +- then the rest of the stack, then return failure. */ ++ { ++ /* Return failure if at end of input. */ + if (yychar == YYEOF) +- for (;;) +- { +- YYPOPSTACK; +- if (yyssp == yyss) +- YYABORT; +- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); +- yydestruct (yystos[*yyssp], yyvsp); +- } +- } ++ YYABORT; ++ } + else + { +- YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); +- yydestruct (yytoken, &yylval); ++ yydestruct ("Error: discarding", ++ yytoken, &yylval, pc); + yychar = YYEMPTY; +- + } + } + +- /* Else will try to reuse lookahead token after shifting the error ++ /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + +@@ -1914,15 +2270,17 @@ + `---------------------------------------------------*/ + yyerrorlab: + +-#ifdef __GNUC__ +- /* Pacify GCC when the user code never invokes YYERROR and the label +- yyerrorlab therefore never appears in user code. */ +- if (0) ++ /* Pacify compilers like GCC when the user code never invokes ++ YYERROR and the label yyerrorlab therefore never appears in user ++ code. */ ++ if (/*CONSTCOND*/ 0) + goto yyerrorlab; +-#endif + +- yyvsp -= yylen; +- yyssp -= yylen; ++ /* Do not reclaim the symbols of the rule which action triggered ++ this YYERROR. */ ++ YYPOPSTACK (yylen); ++ yylen = 0; ++ YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + +@@ -1951,9 +2309,10 @@ + if (yyssp == yyss) + YYABORT; + +- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); +- yydestruct (yystos[yystate], yyvsp); +- YYPOPSTACK; ++ ++ yydestruct ("Error: popping", ++ yystos[yystate], yyvsp, pc); ++ YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } +@@ -1961,11 +2320,12 @@ + if (yyn == YYFINAL) + YYACCEPT; + +- YYDPRINTF ((stderr, "Shifting error token, ")); +- + *++yyvsp = yylval; + + ++ /* Shift the error token. */ ++ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); ++ + yystate = yyn; + goto yynewstate; + +@@ -1985,25 +2345,43 @@ + goto yyreturn; + + #ifndef yyoverflow +-/*----------------------------------------------. +-| yyoverflowlab -- parser overflow comes here. | +-`----------------------------------------------*/ +-yyoverflowlab: +- yyerror (pc, "parser stack overflow"); ++/*-------------------------------------------------. ++| yyexhaustedlab -- memory exhaustion comes here. | ++`-------------------------------------------------*/ ++yyexhaustedlab: ++ yyerror (pc, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ + #endif + + yyreturn: ++ if (yychar != YYEOF && yychar != YYEMPTY) ++ yydestruct ("Cleanup: discarding lookahead", ++ yytoken, &yylval, pc); ++ /* Do not reclaim the symbols of the rule which action triggered ++ this YYABORT or YYACCEPT. */ ++ YYPOPSTACK (yylen); ++ YY_STACK_PRINT (yyss, yyssp); ++ while (yyssp != yyss) ++ { ++ yydestruct ("Cleanup: popping", ++ yystos[*yyssp], yyvsp, pc); ++ YYPOPSTACK (1); ++ } + #ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); + #endif +- return yyresult; ++#if YYERROR_VERBOSE ++ if (yymsg != yymsgbuf) ++ YYSTACK_FREE (yymsg); ++#endif ++ /* Make sure YYID is used. */ ++ return YYID (yyresult); + } + + +-#line 568 "getdate.y" ++#line 619 "getdate.y" + + + static table const meridian_table[] = +@@ -2520,7 +2898,7 @@ + + /* Do nothing if the parser reports an error. */ + static int +-yyerror (parser_control *pc ATTRIBUTE_UNUSED, char *s ATTRIBUTE_UNUSED) ++yyerror (parser_control *pc ATTRIBUTE_UNUSED, const char *s ATTRIBUTE_UNUSED) + { + return 0; + } +@@ -2563,9 +2941,9 @@ + if (tz) + { + size_t tzsize = strlen (tz) + 1; +- tz = (tzsize <= TZBUFSIZE ++ tz = (tzsize == 1 ? NULL : (tzsize <= TZBUFSIZE + ? memcpy (tzbuf, tz, tzsize) +- : xmemdup (tz, tzsize)); ++ : xmemdup (tz, tzsize))); + } + return tz; + } +@@ -2793,7 +3171,8 @@ + + sizeof pc.time_zone * CHAR_BIT / 3]; + if (!tz_was_altered) + tz0 = get_tz (tz0buf); +- sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0), ++ snprintf(tz1buf, sizeof(tz1buf), ++ "XXX%s%ld:%02d", "-" + (time_zone < 0), + abs_time_zone_hour, abs_time_zone_min); + if (setenv ("TZ", tz1buf, 1) != 0) + goto fail; +@@ -2891,46 +3270,67 @@ + ok = false; + done: + if (tz_was_altered) +- ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0; ++ ok &= (tz0 ? setenv("TZ", tz0, 1) : (unsetenv("TZ"), 0)) == 0; + if (tz0 != tz0buf) + free (tz0); + return ok; + } + + #if TEST ++ATTRIBUTE_NORETURN void ++xalloc_die(void) ++{ ++ fprintf(stderr, "memory exhausted\n"); ++ exit(EXIT_FAILURE); ++} + + int +-main (int ac, char **av) ++main(int argc, char **argv) + { + char buff[BUFSIZ]; ++ int cmd = 0; + +- printf ("Enter date, or blank line to exit.\n\t> "); ++ if (argc > 1) { ++ int i = 1; ++ buff[0] = '\0'; ++ while (i < argc) { ++ if (i > 1) ++ strlcat(buff, " ", BUFSIZ); ++ strlcat(buff, argv[i++], BUFSIZ); ++ } ++ cmd++; ++ goto once; ++ } ++ ++ printf("Enter date, or blank line to exit.\n> "); + fflush (stdout); + + buff[BUFSIZ - 1] = '\0'; +- while (fgets (buff, BUFSIZ - 1, stdin) && buff[0]) ++ while (fgets(buff, BUFSIZ - 1, stdin) && buff[0] && ++ buff[0] != '\r' && buff[0] != '\n') + { + struct timespec d; + struct tm const *tm; ++ once: + if (! get_date (&d, buff, NULL)) + printf ("Bad format - couldn't convert.\n"); + else if (! (tm = localtime (&d.tv_sec))) + { +- long int sec = d.tv_sec; +- printf ("localtime (%ld) failed\n", sec); ++ printf ("localtime (%lld) failed\n", (long long)d.tv_sec); + } + else + { + int ns = d.tv_nsec; +- printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n", +- tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday, ++ printf ("%13lld =\t%04ld-%02d-%02d %02d:%02d:%02d.%09d\n", ++ (long long)d.tv_sec, (long)tm->tm_year + 1900, ++ tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, ns); + } +- printf ("\t> "); ++ if (cmd) ++ return 0; ++ printf ("> "); + fflush (stdout); + } + return 0; + } + #endif /* TEST */ +- +- +--- cvs-1.12.13+real.orig/lib/getdate.h ++++ cvs-1.12.13+real/lib/getdate.h +@@ -1,6 +1,9 @@ ++/* $MirOS: src/gnu/usr.bin/cvs/lib/getdate.h,v 1.7 2016/10/22 20:15:03 tg Exp $ */ ++ + /* Parse a string into an internal time stamp. + +- Copyright (C) 1995, 1997, 1998, 2003, 2004 Free Software Foundation, Inc. ++ Copyright (C) 1995, 1997, 1998, 2003, 2004, 2005 ++ Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -16,7 +19,17 @@ + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + ++#ifndef GETDATE_H ++#define GETDATE_H ++ + #include <stdbool.h> ++#ifndef IN_RCS + #include "timespec.h" ++#else ++#include <sys/time.h> ++#include <time.h> ++#endif + + bool get_date (struct timespec *, char const *, struct timespec const *); ++ ++#endif /* GETDATE_H */ +--- cvs-1.12.13+real.orig/lib/getdate.y ++++ cvs-1.12.13+real/lib/getdate.y +@@ -1,8 +1,11 @@ + %{ + /* Parse a string into an internal time stamp. + +- Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Free Software +- Foundation, Inc. ++ Copyright (C) 1995, 1997, 1998, 2003, 2004, 2005 ++ Free Software Foundation, Inc. ++ ++ Copyright (c) 2005, 2006, 2007, 2010, 2016, 2017, 2021 ++ mirabilos <m@mirbsd.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -38,6 +41,10 @@ + + #include "getdate.h" + ++#ifdef USE_LIBBSD ++size_t strlcat(char *, const char *, size_t); ++#endif ++ + /* There's no need to extend the stack, so there's no need to involve + alloca. */ + #define YYSTACK_USE_ALLOCA 0 +@@ -65,10 +72,44 @@ + #include <stdlib.h> + #include <string.h> + ++#ifndef _STDLIB_H ++#define _STDLIB_H 1 /* GNU bison needs this */ ++#endif ++ ++#ifndef IN_RCS + #include "setenv.h" + #include "xalloc.h" ++#else /* IN_RCS */ ++#include <unistd.h> ++ ++#define HAVE_STRUCT_TM_TM_ZONE 1 ++#define HAVE_TM_GMTOFF 1 ++ ++#define gettime(ts) clock_gettime(CLOCK_REALTIME,(ts)) ++ ++static void * ++xmalloc(size_t s) ++{ ++ static const char xmalloc_enomem[] = "memory exhausted\n"; ++ void *x; ++ ++ if ((x = malloc(s)) == NULL) { ++ write(2, xmalloc_enomem, sizeof(xmalloc_enomem) - 1); ++ exit(1); ++ } ++ ++ return (x); ++} ++ ++static void * ++xmemdup(void const *p, size_t s) ++{ ++ return (memcpy(xmalloc(s), p, s)); ++} ++#endif /* IN_RCS */ + +-#if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII) ++#if (defined(STDC_HEADERS) && STDC_HEADERS) || \ ++ (!defined(isascii) && !HAVE_ISASCII) + # define IN_CTYPE_DOMAIN(c) 1 + #else + # define IN_CTYPE_DOMAIN(c) isascii (c) +@@ -87,7 +128,8 @@ + of `digit' even when the host does not conform to POSIX. */ + #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) + +-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ ++#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || \ ++ (defined(__STRICT_ANSI__) && __STRICT_ANSI__) + # define __attribute__(x) + #endif + +@@ -95,6 +137,15 @@ + # define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) + #endif + ++#ifndef __IDSTRING ++#define __IDSTRING(varname, string) \ ++ static const char varname[] __attribute__((__used__)) = \ ++ "@(""#)" #varname ": " string ++#endif ++ ++__IDSTRING(rcsid_code, "$MirOS: src/gnu/usr.bin/cvs/lib/getdate.y,v 1.14 2021/01/30 02:28:27 tg Exp $"); ++/* placeholder line for __IDSTRING(rcsid_bron, "$miros: ..."); so that cpp #line directives work */ ++ + /* Shift A right by B bits portably, by dividing A by 2**B and + truncating towards minus infinity. A and B should be free of side + effects, and B should be in the range 0 <= B <= INT_BITS - 2, where +@@ -191,7 +242,7 @@ + + union YYSTYPE; + static int yylex (union YYSTYPE *, parser_control *); +-static int yyerror (parser_control *, char *); ++static int yyerror (parser_control *, const char *); + static long int time_zone_hhmm (textint, long int); + + %} +@@ -1081,7 +1132,7 @@ + + /* Do nothing if the parser reports an error. */ + static int +-yyerror (parser_control *pc ATTRIBUTE_UNUSED, char *s ATTRIBUTE_UNUSED) ++yyerror (parser_control *pc ATTRIBUTE_UNUSED, const char *s ATTRIBUTE_UNUSED) + { + return 0; + } +@@ -1124,9 +1175,9 @@ + if (tz) + { + size_t tzsize = strlen (tz) + 1; +- tz = (tzsize <= TZBUFSIZE ++ tz = (tzsize == 1 ? NULL : (tzsize <= TZBUFSIZE + ? memcpy (tzbuf, tz, tzsize) +- : xmemdup (tz, tzsize)); ++ : xmemdup (tz, tzsize))); + } + return tz; + } +@@ -1354,7 +1405,8 @@ + + sizeof pc.time_zone * CHAR_BIT / 3]; + if (!tz_was_altered) + tz0 = get_tz (tz0buf); +- sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0), ++ snprintf(tz1buf, sizeof(tz1buf), ++ "XXX%s%ld:%02d", "-" + (time_zone < 0), + abs_time_zone_hour, abs_time_zone_min); + if (setenv ("TZ", tz1buf, 1) != 0) + goto fail; +@@ -1452,42 +1504,65 @@ + ok = false; + done: + if (tz_was_altered) +- ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0; ++ ok &= (tz0 ? setenv("TZ", tz0, 1) : (unsetenv("TZ"), 0)) == 0; + if (tz0 != tz0buf) + free (tz0); + return ok; + } + + #if TEST ++ATTRIBUTE_NORETURN void ++xalloc_die(void) ++{ ++ fprintf(stderr, "memory exhausted\n"); ++ exit(EXIT_FAILURE); ++} + + int +-main (int ac, char **av) ++main(int argc, char **argv) + { + char buff[BUFSIZ]; ++ int cmd = 0; ++ ++ if (argc > 1) { ++ int i = 1; ++ buff[0] = '\0'; ++ while (i < argc) { ++ if (i > 1) ++ strlcat(buff, " ", BUFSIZ); ++ strlcat(buff, argv[i++], BUFSIZ); ++ } ++ cmd++; ++ goto once; ++ } + +- printf ("Enter date, or blank line to exit.\n\t> "); ++ printf("Enter date, or blank line to exit.\n> "); + fflush (stdout); + + buff[BUFSIZ - 1] = '\0'; +- while (fgets (buff, BUFSIZ - 1, stdin) && buff[0]) ++ while (fgets(buff, BUFSIZ - 1, stdin) && buff[0] && ++ buff[0] != '\r' && buff[0] != '\n') + { + struct timespec d; + struct tm const *tm; ++ once: + if (! get_date (&d, buff, NULL)) + printf ("Bad format - couldn't convert.\n"); + else if (! (tm = localtime (&d.tv_sec))) + { +- long int sec = d.tv_sec; +- printf ("localtime (%ld) failed\n", sec); ++ printf ("localtime (%lld) failed\n", (long long)d.tv_sec); + } + else + { + int ns = d.tv_nsec; +- printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n", +- tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday, ++ printf ("%13lld =\t%04ld-%02d-%02d %02d:%02d:%02d.%09d\n", ++ (long long)d.tv_sec, (long)tm->tm_year + 1900, ++ tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, ns); + } +- printf ("\t> "); ++ if (cmd) ++ return 0; ++ printf ("> "); + fflush (stdout); + } + return 0; +--- cvs-1.12.13+real.orig/lib/getdelim.c ++++ cvs-1.12.13+real/lib/getdelim.c +@@ -48,7 +48,6 @@ + { + int result = 0; + ssize_t cur_len = 0; +- ssize_t len; + + if (lineptr == NULL || n == NULL || fp == NULL) + { +@@ -71,7 +70,6 @@ + + for (;;) + { +- char *t; + int i; + + i = getc (fp); +@@ -82,12 +80,12 @@ + } + + /* Make enough space for len+1 (for final NUL) bytes. */ +- if (cur_len + 1 >= *n) ++ if ((size_t)cur_len + 1U >= *n) + { + size_t needed = 2 * (cur_len + 1) + 1; /* Be generous. */ + char *new_lineptr; + +- if (needed < cur_len) ++ if (needed < (size_t)cur_len) + { + result = -1; + goto unlock_return; +--- cvs-1.12.13+real.orig/lib/gettext.h ++++ cvs-1.12.13+real/lib/gettext.h +@@ -19,7 +19,7 @@ + #define _LIBGETTEXT_H 1 + + /* NLS can be disabled through the configure --disable-nls option. */ +-#if ENABLE_NLS ++#if defined(ENABLE_NLS) && (ENABLE_NLS) + + /* Get declarations of GNU message catalog functions. */ + # include <libintl.h> +--- cvs-1.12.13+real.orig/lib/glob.c ++++ cvs-1.12.13+real/lib/glob.c +@@ -189,7 +189,7 @@ + # define GET_LOGIN_NAME_MAX() (-1) + #endif + +-static const char *next_brace_sub (const char *begin, int flags) __THROW; ++static const char *next_brace_sub (const char *begin, int flags) __THROWNL; + + #endif /* !defined _LIBC || !defined GLOB_ONLY_P */ + +@@ -198,8 +198,8 @@ + glob_t *pglob); + + #if !defined _LIBC || !defined GLOB_ONLY_P +-static int prefix_array (const char *prefix, char **array, size_t n) __THROW; +-static int collated_compare (const void *, const void *) __THROW; ++static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL; ++static int collated_compare (const void *, const void *) __THROWNL; + + + /* Find the end of the sub-pattern in a brace expression. */ +--- cvs-1.12.13+real.orig/lib/glob_.h ++++ cvs-1.12.13+real/lib/glob_.h +@@ -34,6 +34,9 @@ + #ifndef __THROW + # define __THROW + #endif ++#ifndef __THROWNL ++# define __THROWNL ++#endif + + #ifndef __size_t + # define __size_t size_t +--- cvs-1.12.13+real.orig/lib/minmax.h ++++ cvs-1.12.13+real/lib/minmax.h +@@ -28,7 +28,7 @@ + included after this file. Likewise for <sys/param.h>. + If more than one of these system headers define MIN and MAX, pick just + one of the headers (because the definitions most likely are the same). */ +-#if HAVE_MINMAX_IN_LIMITS_H ++#if defined(HAVE_MINMAX_IN_LIMITS_H) && (HAVE_MINMAX_IN_LIMITS_H) + # include <limits.h> + #elif HAVE_MINMAX_IN_SYS_PARAM_H + # include <sys/param.h> +--- cvs-1.12.13+real.orig/lib/pagealign_alloc.c ++++ cvs-1.12.13+real/lib/pagealign_alloc.c +@@ -44,6 +44,10 @@ + #include "xalloc.h" + #include "gettext.h" + ++#if HAVE_MMAP && !defined(HAVE_MAP_ANONYMOUS) ++#include <stdio.h> ++#endif ++ + #define _(str) gettext (str) + + #if HAVE_MMAP +@@ -132,6 +136,7 @@ + const int fd = -1; + const int flags = MAP_ANONYMOUS | MAP_PRIVATE; + # else /* !HAVE_MAP_ANONYMOUS */ ++ static int beenhere = 0; + static int fd = -1; /* Only open /dev/zero once in order to avoid limiting + the amount of memory we may allocate based on the + number of open file descriptors. */ +@@ -140,7 +145,20 @@ + { + fd = open ("/dev/zero", O_RDONLY, 0666); + if (fd < 0) +- error (EXIT_FAILURE, errno, _("Failed to open /dev/zero for read")); ++ { ++ if (!beenhere) ++ { ++ beenhere = 1; ++ error (EXIT_FAILURE, errno, _("Failed to open /dev/zero for read")); ++ } ++ else ++ { ++ fprintf (stderr, "Fatal in pagealign: %s\n", ++ _("Failed to open /dev/zero for read")); ++ fflush (stderr); ++ _exit (EXIT_FAILURE); ++ } ++ } + } + # endif /* HAVE_MAP_ANONYMOUS */ + ret = mmap (NULL, size, PROT_READ | PROT_WRITE, flags, fd, 0); +--- cvs-1.12.13+real.orig/lib/regcomp.c ++++ cvs-1.12.13+real/lib/regcomp.c +@@ -1652,8 +1652,6 @@ + && dfa->edests[node].nelem + && !dfa->nodes[dfa->edests[node].elems[0]].duplicated) + { +- Idx org_node, cur_node; +- org_node = cur_node = node; + err = duplicate_node_closure (dfa, node, node, node, constraint); + if (BE (err != REG_NOERROR, 0)) + return err; +--- cvs-1.12.13+real.orig/lib/regex_internal.c ++++ cvs-1.12.13+real/lib/regex_internal.c +@@ -629,7 +629,7 @@ + + if (pstr->is_utf8) + { +- const unsigned char *raw, *p, *q, *end; ++ const unsigned char *raw, *p, *end; + + /* Special case UTF-8. Multi-byte chars start with any + byte other than 0x80 - 0xbf. */ +@@ -641,17 +641,8 @@ + mbstate_t cur_state; + wchar_t wc2; + Idx mlen = raw + pstr->len - p; +- unsigned char buf[6]; + size_t mbclen; + +- q = p; +- if (BE (pstr->trans != NULL, 0)) +- { +- int i = mlen < 6 ? mlen : 6; +- while (--i >= 0) +- buf[i] = pstr->trans[p[i]]; +- q = buf; +- } + /* XXX Don't use mbrtowc, we know which conversion + to use (UTF-8 -> UCS4). */ + memset (&cur_state, 0, sizeof (cur_state)); +--- cvs-1.12.13+real.orig/lib/regex_internal.h ++++ cvs-1.12.13+real/lib/regex_internal.h +@@ -451,7 +451,9 @@ + #define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) + #define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) + ++#ifdef HAVE_ALLOCA_H + #include <alloca.h> ++#endif + + #ifndef _LIBC + # if HAVE_ALLOCA +--- cvs-1.12.13+real.orig/lib/strftime.c ++++ cvs-1.12.13+real/lib/strftime.c +@@ -1,5 +1,6 @@ + /* Copyright (C) 1991-1999, 2000, 2001, 2003, 2004, 2005 Free Software + Foundation, Inc. ++ Copyright (c) 2021 mirabilos <m@mirbsd.org> + + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@prep.ai.mit.edu. +@@ -1222,8 +1223,7 @@ + } + if (modifier == L_('O')) + goto bad_format; +- else +- DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE, ++ DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE, + tp->tm_year + (unsigned int) TM_YEAR_BASE); + + case L_('y'): +--- cvs-1.12.13+real.orig/lib/sunos57-select.c ++++ cvs-1.12.13+real/lib/sunos57-select.c +@@ -40,6 +40,11 @@ + #include <sys/stat.h> + #include <errno.h> + ++#if defined(STDC_HEADERS) || defined(HAVE_STRING_H) ++# include <string.h> ++#else ++# include <strings.h> ++#endif + #ifdef HAVE_UNISTD_H + # include <unistd.h> + #endif /* HAVE_UNISTD_H */ +--- cvs-1.12.13+real.orig/lib/system.h ++++ cvs-1.12.13+real/lib/system.h +@@ -304,7 +304,7 @@ + + + +-/* Some file systems are case-insensitive. If FOLD_FN_CHAR is ++/* Some filesystems 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 + to lower case. Under Windows NT, / and \ are both path component +@@ -315,7 +315,7 @@ + # define fncmp strcmp + #endif + +-/* Different file systems can have different naming patterns which designate ++/* Different filesystems can have different naming patterns which designate + * a path as absolute. + */ + #ifndef ISABSOLUTE +--- cvs-1.12.13+real.orig/lib/tempname.c ++++ cvs-1.12.13+real/lib/tempname.c +@@ -148,7 +148,7 @@ + if (try_tmpdir) + { + d = __secure_getenv ("TMPDIR"); +- if (d != NULL && direxists (d)) ++ if (d != NULL && *d && direxists (d)) + dir = d; + else if (dir != NULL && direxists (dir)) + /* nothing */ ; +--- cvs-1.12.13+real.orig/lib/test-getdate.sh ++++ cvs-1.12.13+real/lib/test-getdate.sh +@@ -1,4 +1,5 @@ + #! /bin/sh ++# $MirOS: src/gnu/usr.bin/cvs/lib/test-getdate.sh,v 1.2 2016/10/22 15:34:32 tg Exp $ + + # Test that a getdate executable meets its specification. + # +@@ -19,6 +20,11 @@ + # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + ++# as this uses POSIX behaviour and does not count leap seconds... ++if test -n "$GETDATE_LD_PRELOAD"; then ++ LD_PRELOAD=$GETDATE_LD_PRELOAD ++ export LD_PRELOAD ++fi + + ### + ### Globals +@@ -113,10 +119,9 @@ + NTZ=`TZ=$1 date +%Z` + if test "$NTZ" = "$UTZ" || test "$NTZ" = "$1"; then + skipreason="$1 is not a recognized timezone on this system" +- return `false` +- else +- return `:` ++ return 1 + fi ++ : + } + + +@@ -184,22 +189,22 @@ + + cat >getdate-expected <<EOF + Enter date, or blank line to exit. +- > Bad format - couldn't convert. +- > Bad format - couldn't convert. +- > 1972-12-05 00:00:00.000000000 +- > 1974-03-29 00:00:00.000000000 +- > 1996-05-12 13:57:45.000000000 +- > 2012-05-12 00:00:00.000000000 +- > 1996-05-12 00:00:00.000000000 +- > Bad format - couldn't convert. +- > Bad format - couldn't convert. +- > 1970-01-01 02:00:00.000000000 +- > Bad format - couldn't convert. +- > 1969-12-31 22:00:00.000000000 +- > Bad format - couldn't convert. +- > 1970-01-01 06:00:00.000000000 +- > 1997-01-12 00:00:00.000000000 +- > ++> Bad format - couldn't convert. ++> Bad format - couldn't convert. ++> 92361600 = 1972-12-05 00:00:00.000000000 ++> 133747200 = 1974-03-29 00:00:00.000000000 ++> 831909465 = 1996-05-12 13:57:45.000000000 ++> 1336780800 = 2012-05-12 00:00:00.000000000 ++> 831859200 = 1996-05-12 00:00:00.000000000 ++> Bad format - couldn't convert. ++> Bad format - couldn't convert. ++> 7200 = 1970-01-01 02:00:00.000000000 ++> Bad format - couldn't convert. ++> -7200 = 1969-12-31 22:00:00.000000000 ++> Bad format - couldn't convert. ++> 21600 = 1970-01-01 06:00:00.000000000 ++> 853027200 = 1997-01-12 00:00:00.000000000 ++> + EOF + + ./getdate >getdate-got <<EOF +@@ -235,22 +240,22 @@ + if valid_timezone $TZ; then + cat >getdate-expected <<EOF + Enter date, or blank line to exit. +- > 2005-03-01 00:00:00.000000000 +- > 2005-03-27 00:00:00.000000000 +- > 2005-03-28 01:00:00.000000000 +- > 2005-03-28 01:00:00.000000000 +- > 2005-03-29 01:00:00.000000000 +- > 2005-03-29 01:00:00.000000000 +- > 2005-03-30 01:00:00.000000000 +- > 2005-03-30 01:00:00.000000000 +- > 2005-03-31 01:00:00.000000000 +- > 2005-03-31 01:00:00.000000000 +- > 2005-04-01 01:00:00.000000000 +- > 2005-04-01 01:00:00.000000000 +- > 2005-04-10 01:00:00.000000000 +- > 2005-04-10 01:00:00.000000000 +- > 2005-04-01 00:00:00.000000000 +- > ++> 1109635200 = 2005-03-01 00:00:00.000000000 ++> 1111881600 = 2005-03-27 00:00:00.000000000 ++> 1111968000 = 2005-03-28 01:00:00.000000000 ++> 1111968000 = 2005-03-28 01:00:00.000000000 ++> 1112054400 = 2005-03-29 01:00:00.000000000 ++> 1112054400 = 2005-03-29 01:00:00.000000000 ++> 1112140800 = 2005-03-30 01:00:00.000000000 ++> 1112140800 = 2005-03-30 01:00:00.000000000 ++> 1112227200 = 2005-03-31 01:00:00.000000000 ++> 1112227200 = 2005-03-31 01:00:00.000000000 ++> 1112313600 = 2005-04-01 01:00:00.000000000 ++> 1112313600 = 2005-04-01 01:00:00.000000000 ++> 1113091200 = 2005-04-10 01:00:00.000000000 ++> 1113091200 = 2005-04-10 01:00:00.000000000 ++> 1112310000 = 2005-04-01 00:00:00.000000000 ++> + EOF + + ./getdate >getdate-got <<EOF +@@ -297,20 +302,20 @@ + if valid_timezone $TZ; then + cat >getdate-expected <<EOF + Enter date, or blank line to exit. +- > 2005-03-01 00:00:00.000000000 +- > 2005-02-28 18:00:00.000000000 +- > 2005-04-01 00:00:00.000000000 +- > Bad format - couldn't convert. +- > 2005-04-30 19:00:00.000000000 +- > 2005-04-30 20:00:00.000000000 +- > 2005-05-01 00:00:00.000000000 +- > 2005-04-30 20:00:00.000000000 +- > Bad format - couldn't convert. +- > 2005-05-31 19:00:00.000000000 +- > 2005-05-31 20:00:00.000000000 +- > 2005-06-01 00:00:00.000000000 +- > 2005-05-31 20:00:00.000000000 +- > ++> 1109653200 = 2005-03-01 00:00:00.000000000 ++> 1109631600 = 2005-02-28 18:00:00.000000000 ++> 1112331600 = 2005-04-01 00:00:00.000000000 ++> Bad format - couldn't convert. ++> 1114902000 = 2005-04-30 19:00:00.000000000 ++> 1114905600 = 2005-04-30 20:00:00.000000000 ++> 1114920000 = 2005-05-01 00:00:00.000000000 ++> 1114905600 = 2005-04-30 20:00:00.000000000 ++> Bad format - couldn't convert. ++> 1117580400 = 2005-05-31 19:00:00.000000000 ++> 1117584000 = 2005-05-31 20:00:00.000000000 ++> 1117598400 = 2005-06-01 00:00:00.000000000 ++> 1117584000 = 2005-05-31 20:00:00.000000000 ++> + EOF + + ./getdate >getdate-got <<EOF +--- cvs-1.12.13+real.orig/lib/vasnprintf.c ++++ cvs-1.12.13+real/lib/vasnprintf.c +@@ -26,7 +26,9 @@ + # include <config.h> + #endif + #ifndef IN_LIBINTL ++# ifdef HAVE_ALLOCA_H + # include <alloca.h> ++# endif + #endif + + /* Specification. */ +@@ -100,7 +102,12 @@ + # define DIRECTIVE char_directive + # define DIRECTIVES char_directives + # define PRINTF_PARSE printf_parse ++#if 0 ++/* disabled for security reasons, to avoid having %n in writable memory */ + # define USE_SNPRINTF (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) ++#else ++# define USE_SNPRINTF 0 ++#endif + # if HAVE_DECL__SNPRINTF + /* Windows. */ + # define SNPRINTF _snprintf +@@ -591,11 +598,12 @@ + { + size_t maxlen; + int count; +- int retcount; ++#if USE_SNPRINTF ++ int retcount = 0; ++#endif + + maxlen = allocated - length; + count = -1; +- retcount = 0; + + #if USE_SNPRINTF + # define SNPRINTF_BUF(arg) \ +--- cvs-1.12.13+real.orig/lib/xalloc.h ++++ cvs-1.12.13+real/lib/xalloc.h +@@ -29,7 +29,7 @@ + + + # ifndef __attribute__ +-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ ++# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || (defined(__STRICT_ANSI__) && (__STRICT_ANSI__)) + # define __attribute__(x) + # endif + # endif +--- cvs-1.12.13+real.orig/m4/getcwd-path-max.m4 ++++ cvs-1.12.13+real/m4/getcwd-path-max.m4 +@@ -65,8 +65,8 @@ + { + #ifndef PATH_MAX + /* The Hurd doesn't define this, so getcwd can't exhibit the bug -- +- at least not on a local file system. And if we were to start worrying +- about remote file systems, we'd have to enable the wrapper function ++ at least not on a local filesystem. And if we were to start worrying ++ about remote filesystems, we'd have to enable the wrapper function + all of the time, just to be safe. That's not worth the cost. */ + exit (0); + #elif ((INT_MAX / (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1) \ +--- cvs-1.12.13+real.orig/m4/getdate.m4 ++++ cvs-1.12.13+real/m4/getdate.m4 +@@ -6,7 +6,7 @@ + + AC_DEFUN([gl_GETDATE], + [ +- AC_LIBSOURCES([getdate.h, getdate.y]) ++ AC_LIBSOURCES([getdate.h, getdate.c]) + AC_LIBOBJ([getdate]) + + dnl Prerequisites of lib/getdate.h. +--- cvs-1.12.13+real.orig/m4/longdouble.m4 ++++ cvs-1.12.13+real/m4/longdouble.m4 +@@ -8,21 +8,12 @@ + dnl Test whether the compiler supports the 'long double' type. + dnl Prerequisite: AC_PROG_CC + ++dnl $MirOS: src/gnu/usr.bin/cvs/m4/longdouble.m4,v 1.4 2016/10/22 03:36:43 tg Exp $ ++ + AC_DEFUN([gt_TYPE_LONGDOUBLE], + [ +- AC_CACHE_CHECK([for long double], gt_cv_c_long_double, +- [if test "$GCC" = yes; then +- gt_cv_c_long_double=yes +- else +- AC_TRY_COMPILE([ +- /* The Stardent Vistra knows sizeof(long double), but does not support it. */ +- long double foo = 0.0; +- /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ +- int array [2*(sizeof(long double) >= sizeof(double)) - 1]; +- ], , +- gt_cv_c_long_double=yes, gt_cv_c_long_double=no) +- fi]) +- if test $gt_cv_c_long_double = yes; then ++ AC_CHECK_TYPE([long double], [gt_cv_c_long_double=yes], [gt_cv_c_long_double=no]) ++ if test x"$gt_cv_c_long_double" = x"yes"; then + AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the 'long double' type.]) + fi + ]) +--- cvs-1.12.13+real.orig/m4/mktime.m4 ++++ cvs-1.12.13+real/m4/mktime.m4 +@@ -6,6 +6,9 @@ + + dnl From Jim Meyering. + ++dnl Test program updated to git faefb77009239f82ac2f77ac0c10d71d4f38af07 ++dnl for Debian. ++ + # Redefine AC_FUNC_MKTIME, to fix a bug in Autoconf 2.57 and earlier. + # This redefinition can be removed once a new version of Autoconf comes out. + # The redefinition is taken from +@@ -19,27 +22,16 @@ + AC_CACHE_CHECK([for working mktime], ac_cv_func_working_mktime, + [AC_RUN_IFELSE([AC_LANG_SOURCE( + [[/* Test program from Paul Eggert and Tony Leneis. */ +-#if TIME_WITH_SYS_TIME +-# include <sys/time.h> +-# include <time.h> +-#else +-# if HAVE_SYS_TIME_H +-# include <sys/time.h> +-# else +-# include <time.h> +-# endif +-#endif ++#include <limits.h> ++#include <stdlib.h> ++#include <time.h> + +-#if HAVE_STDLIB_H +-# include <stdlib.h> +-#endif +- +-#if HAVE_UNISTD_H ++#ifdef HAVE_UNISTD_H + # include <unistd.h> + #endif + +-#if !HAVE_ALARM +-# define alarm(X) /* empty */ ++#if HAVE_DECL_ALARM ++# include <signal.h> + #endif + + /* Work around redefinition to rpl_putenv by other config tests. */ +@@ -55,9 +47,9 @@ + }; + #define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0])) + +-/* Fail if mktime fails to convert a date in the spring-forward gap. ++/* Return 0 if mktime fails to convert a date in the spring-forward gap. + Based on a problem report from Andreas Jaeger. */ +-static void ++static int + spring_forward_gap () + { + /* glibc (up to about 1998-10-07) failed this test. */ +@@ -76,29 +68,25 @@ + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_isdst = -1; +- if (mktime (&tm) == (time_t)-1) +- exit (1); ++ return mktime (&tm) != (time_t) -1; + } + +-static void +-mktime_test1 (now) +- time_t now; ++static int ++mktime_test1 (time_t now) + { + struct tm *lt; +- if ((lt = localtime (&now)) && mktime (lt) != now) +- exit (1); ++ return ! (lt = localtime (&now)) || mktime (lt) == now; + } + +-static void +-mktime_test (now) +- time_t now; ++static int ++mktime_test (time_t now) + { +- mktime_test1 (now); +- mktime_test1 ((time_t) (time_t_max - now)); +- mktime_test1 ((time_t) (time_t_min + now)); ++ return (mktime_test1 (now) ++ && mktime_test1 ((time_t) (time_t_max - now)) ++ && mktime_test1 ((time_t) (time_t_min + now))); + } + +-static void ++static int + irix_6_4_bug () + { + /* Based on code from Ariel Faigon. */ +@@ -111,13 +99,11 @@ + tm.tm_sec = 0; + tm.tm_isdst = -1; + mktime (&tm); +- if (tm.tm_mon != 2 || tm.tm_mday != 31) +- exit (1); ++ return tm.tm_mon == 2 && tm.tm_mday == 31; + } + +-static void +-bigtime_test (j) +- int j; ++static int ++bigtime_test (int j) + { + struct tm tm; + time_t now; +@@ -127,56 +113,110 @@ + { + struct tm *lt = localtime (&now); + if (! (lt +- && lt->tm_year == tm.tm_year +- && lt->tm_mon == tm.tm_mon +- && lt->tm_mday == tm.tm_mday +- && lt->tm_hour == tm.tm_hour +- && lt->tm_min == tm.tm_min +- && lt->tm_sec == tm.tm_sec +- && lt->tm_yday == tm.tm_yday +- && lt->tm_wday == tm.tm_wday +- && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst) +- == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst)))) +- exit (1); ++ && lt->tm_year == tm.tm_year ++ && lt->tm_mon == tm.tm_mon ++ && lt->tm_mday == tm.tm_mday ++ && lt->tm_hour == tm.tm_hour ++ && lt->tm_min == tm.tm_min ++ && lt->tm_sec == tm.tm_sec ++ && lt->tm_yday == tm.tm_yday ++ && lt->tm_wday == tm.tm_wday ++ && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst) ++ == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst)))) ++ return 0; + } ++ return 1; ++} ++ ++static int ++year_2050_test () ++{ ++ /* The correct answer for 2050-02-01 00:00:00 in Pacific time, ++ ignoring leap seconds. */ ++ unsigned long int answer = 2527315200UL; ++ ++ struct tm tm; ++ time_t t; ++ tm.tm_year = 2050 - 1900; ++ tm.tm_mon = 2 - 1; ++ tm.tm_mday = 1; ++ tm.tm_hour = tm.tm_min = tm.tm_sec = 0; ++ tm.tm_isdst = -1; ++ ++ /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0" ++ instead of "TZ=America/Vancouver" in order to detect the bug even ++ on systems that don't support the Olson extension, or don't have the ++ full zoneinfo tables installed. */ ++ putenv ("TZ=PST8PDT,M4.1.0,M10.5.0"); ++ ++ t = mktime (&tm); ++ ++ /* Check that the result is either a failure, or close enough ++ to the correct answer that we can assume the discrepancy is ++ due to leap seconds. */ ++ return (t == (time_t) -1 ++ || (0 < t && answer - 120 <= t && t <= answer + 120)); + } + + int + main () + { ++ int result = 0; + time_t t, delta; + int i, j; ++ int time_t_signed_magnitude = (time_t) ~ (time_t) 0 < (time_t) -1; ++ int time_t_signed = ! ((time_t) 0 < (time_t) -1); + ++#if HAVE_DECL_ALARM + /* This test makes some buggy mktime implementations loop. + Give up after 60 seconds; a mktime slower than that + isn't worth using anyway. */ ++ signal (SIGALRM, SIG_DFL); + alarm (60); ++#endif ++ ++ time_t_max = (! time_t_signed ++ ? (time_t) -1 ++ : ((((time_t) 1 << (sizeof (time_t) * CHAR_BIT - 2)) - 1) ++ * 2 + 1)); ++ time_t_min = (! time_t_signed ++ ? (time_t) 0 ++ : time_t_signed_magnitude ++ ? ~ (time_t) 0 ++ : ~ time_t_max); + +- for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2) +- continue; +- time_t_max--; +- if ((time_t) -1 < 0) +- for (time_t_min = -1; (time_t) (time_t_min * 2) < 0; time_t_min *= 2) +- continue; + delta = time_t_max / 997; /* a suitable prime number */ + for (i = 0; i < N_STRINGS; i++) + { + if (tz_strings[i]) +- putenv (tz_strings[i]); ++ putenv (tz_strings[i]); + +- for (t = 0; t <= time_t_max - delta; t += delta) +- mktime_test (t); +- mktime_test ((time_t) 1); +- mktime_test ((time_t) (60 * 60)); +- mktime_test ((time_t) (60 * 60 * 24)); +- +- for (j = 1; 0 < j; j *= 2) +- bigtime_test (j); +- bigtime_test (j - 1); ++ for (t = 0; t <= time_t_max - delta && (result & 1) == 0; t += delta) ++ if (! mktime_test (t)) ++ result |= 1; ++ if ((result & 2) == 0 ++ && ! (mktime_test ((time_t) 1) ++ && mktime_test ((time_t) (60 * 60)) ++ && mktime_test ((time_t) (60 * 60 * 24)))) ++ result |= 2; ++ ++ for (j = 1; (result & 4) == 0; j <<= 1) ++ { ++ if (! bigtime_test (j)) ++ result |= 4; ++ if (INT_MAX / 2 < j) ++ break; ++ } ++ if ((result & 8) == 0 && ! bigtime_test (INT_MAX)) ++ result |= 8; + } +- irix_6_4_bug (); +- spring_forward_gap (); +- exit (0); ++ if (! irix_6_4_bug ()) ++ result |= 16; ++ if (! spring_forward_gap ()) ++ result |= 32; ++ if (! year_2050_test ()) ++ result |= 64; ++ return result; + }]])], + [ac_cv_func_working_mktime=yes], + [ac_cv_func_working_mktime=no], +--- cvs-1.12.13+real.orig/man/cvs.5 ++++ cvs-1.12.13+real/man/cvs.5 +@@ -1,3 +1,4 @@ ++.\" $MirOS: src/gnu/usr.bin/cvs/man/cvs.5,v 1.3 2010/09/19 19:43:00 tg Exp $ + .TH cvs 5 "12 February 1992" + .\" Full space in nroff; half space in troff + .de SP +@@ -238,9 +239,9 @@ + .B add + for `tag', + .B mov +-for `tag -F', and ++for `tag \-F', and + .B del +-for `tag -d`), ++for `tag \-d`), + .I repository , + and any remaining are pairs of + .B "filename revision" . +--- cvs-1.12.13+real.orig/src/ChangeLog ++++ cvs-1.12.13+real/src/ChangeLog +@@ -11313,7 +11313,7 @@ + 1999-05-11 Larry Jones <larry.jones@sdrc.com> + + * server.c (serve_notify): Allocate enough memory to hold the +- "misformed Notify request" message in pending_error_text. ++ "malformed Notify request" message in pending_error_text. + + 1999-05-11 Jim Kingdon <http://www.cyclic.com> + +--- cvs-1.12.13+real.orig/src/add.c ++++ cvs-1.12.13+real/src/add.c +@@ -532,7 +532,8 @@ + free (bbuf); + } + Register (entries, finfo.file, "0", +- timestamp ? timestamp : vers->ts_user, ++ timestamp ? timestamp : ++ vers->ts_user_ists ? "locally added" : vers->ts_user, + vers->options, vers->tag, vers->date, NULL); + if (timestamp) free (timestamp); + #ifdef SERVER_SUPPORT +@@ -784,7 +785,7 @@ + } + + /* setup the log message */ +- message = Xasprintf ("Directory %s added to the repository\n%s%s%s%s%s%s", ++ message = Xasprintf ("Directory %s put under version control\n%s%s%s%s%s%s", + rcsdir, + tag ? "--> Using per-directory sticky tag `" : "", + tag ? tag : "", tag ? "'\n" : "", +--- cvs-1.12.13+real.orig/src/admin.c ++++ cvs-1.12.13+real/src/admin.c +@@ -147,6 +147,7 @@ + TRACE (TRACE_FUNCTION, "postadmin_proc (%s, %s)", repository, filter); + + /* %c = cvs_cmd_name ++ * %I = commit ID + * %R = referrer + * %p = shortrepos + * %r = repository +@@ -162,6 +163,7 @@ + #endif /* SUPPORT_OLD_INFO_FMT_STRINGS */ + filter, + "c", "s", cvs_cmd_name, ++ "I", "s", global_session_id, + #ifdef SERVER_SUPPORT + "R", "s", referrer ? referrer->original : "NONE", + #endif /* SERVER_SUPPORT */ +--- cvs-1.12.13+real.orig/src/annotate.c ++++ cvs-1.12.13+real/src/annotate.c +@@ -21,6 +21,7 @@ + + /* Options from the command line. */ + ++static int backwards = 0; + static int force_tag_match = 1; + static int force_binary = 0; + static char *tag = NULL; +@@ -36,7 +37,8 @@ + + static const char *const annotate_usage[] = + { +- "Usage: %s %s [-lRfF] [-r rev] [-D date] [files...]\n", ++ "Usage: %s %s [-blRfF] [-r rev] [-D date] [files...]\n", ++ "\t-b\tBackwards, show when a line was removed.\n", + "\t-l\tLocal directory only, no recursion.\n", + "\t-R\tProcess directories recursively.\n", + "\t-f\tUse head revision if tag/date not found.\n", +@@ -63,10 +65,13 @@ + usage (annotate_usage); + + optind = 0; +- while ((c = getopt (argc, argv, "+lr:D:fFR")) != -1) ++ while ((c = getopt (argc, argv, "+blr:D:fFR")) != -1) + { + switch (c) + { ++ case 'b': ++ backwards = 1; ++ break; + case 'l': + local = 1; + break; +@@ -105,6 +110,8 @@ + + ign_setup (); + ++ if (backwards) ++ send_arg ("-b"); + if (local) + send_arg ("-l"); + if (!force_tag_match) +@@ -280,7 +287,8 @@ + else + { + RCS_deltas (finfo->rcs, NULL, NULL, +- version, RCS_ANNOTATE, NULL, NULL, NULL, NULL); ++ version, backwards ? RCS_ANNOTATE_BACKWARDS : RCS_ANNOTATE, ++ NULL, NULL, NULL, NULL); + } + free (version); + return 0; +--- cvs-1.12.13+real.orig/src/buffer.c ++++ cvs-1.12.13+real/src/buffer.c +@@ -1,6 +1,9 @@ + /* ++ * Copyright © 2017 mirabilos <m@mirbsd.org> + * Copyright (C) 1996-2005 The Free Software Foundation, Inc. + * ++ * Portions Copyright (c) 2017 Patrick Keshishian ++ * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) +@@ -536,9 +539,10 @@ + void + buf_free_data (struct buffer *buffer) + { +- if (buf_empty_p (buffer)) return; ++ if (buffer->data) { + buf_free_datas (buffer->data, buffer->last); + buffer->data = buffer->last = NULL; ++ } + } + + +@@ -1049,7 +1053,14 @@ + } + + /* Put in the command. */ +- buf_append_char (outbuf, command); ++ switch (command) { ++ case CVS_OUTPUT_EX_LOGM: ++ buf_output0 (outbuf, "LOGM"); ++ break; ++ default: ++ buf_append_char (outbuf, command); ++ break; ++ } + buf_append_char (outbuf, ' '); + + if (inbuf->data != nldata) +--- cvs-1.12.13+real.orig/src/checkout.c ++++ cvs-1.12.13+real/src/checkout.c +@@ -422,7 +422,7 @@ + * + * ERRORS + * Exits with a fatal error message when various events occur, such as not +- * being able to resolve a path or failing ot chdir to a path. ++ * being able to resolve a path or failing to chdir to a path. + */ + int + safe_location (char *where) +--- cvs-1.12.13+real.orig/src/client.c ++++ cvs-1.12.13+real/src/client.c +@@ -3077,6 +3077,7 @@ + rs_optional), + RSP_LINE("M", handle_m, response_type_normal, rs_essential), + RSP_LINE("Mbinary", handle_mbinary, response_type_normal, rs_optional), ++ RSP_LINE("LOGM", handle_m, response_type_normal, rs_optional), + RSP_LINE("E", handle_e, response_type_normal, rs_essential), + RSP_LINE("F", handle_f, response_type_normal, rs_optional), + RSP_LINE("MT", handle_mt, response_type_normal, rs_optional), +@@ -3355,7 +3356,7 @@ + struct servent *s; + char *port_s; + +- if (envname && (port_s = getenv (envname))) ++ if (envname && (port_s = getenv (envname)) && *port_s) + { + int port = atoi (port_s); + if (port <= 0) +@@ -3510,6 +3511,17 @@ + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock == -1) + error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); ++ ++#ifdef TCP_NODELAY ++ /* Avoid latency due to Nagle algorithm. */ ++ { ++ int on = 1; ++ ++ if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on) < 0) ++ error (0, errno, "warning: cannot set TCP_NODELAY on socket"); ++ } ++#endif ++ + port_number = get_cvs_port_number (root); + + /* if we have a proxy connect to that instead */ +@@ -3558,9 +3570,9 @@ + * code. + */ + read_line_via (from_server, to_server, &read_buf); +- sscanf (read_buf, "%s %d", write_buf, &codenum); ++ count = sscanf (read_buf, "%*s %d", &codenum); + +- if ((codenum / 100) != 2) ++ if (count != 1 || (codenum / 100) != 2) + error (1, 0, "proxy server %s:%d does not support http tunnelling", + root->proxy_hostname, proxy_port_number); + free (read_buf); +@@ -3793,11 +3805,12 @@ + /* This is pretty simple. All we need to do is choose the correct + cvs binary and call piped_child. */ + +- char *command[3]; ++ char *command[4]; ++ int ncommand = 0; + +- command[0] = (root->cvs_server ++ command[ncommand++] = (root->cvs_server + ? root->cvs_server : getenv ("CVS_SERVER")); +- if (!command[0]) ++ if (!command[0] || !command[0][0]) + # ifdef SERVER_SUPPORT + /* FIXME: + * I'm casting out the const below because I know that piped_child, the +@@ -3807,7 +3820,7 @@ + * such that this casting isn't needed, but I don't know how. If I + * declare it as (const char *command[]), the compiler complains about + * an incompatible arg 1 being passed to piped_child and if I declare +- * it as (char *const command[3]), then the compiler complains when I ++ * it as (char *const command[4]), then the compiler complains when I + * assign values to command[i]. + */ + command[0] = (char *)program_path; +@@ -3819,11 +3832,15 @@ + } + # endif /* SERVER_SUPPORT */ + +- command[1] = "server"; +- command[2] = NULL; +- +- TRACE (TRACE_FUNCTION, "Forking server: %s %s", +- command[0] ? command[0] : "(null)", command[1]); ++ if (readonlyfs) ++ command[ncommand++] = "-R"; ++ command[ncommand++] = "server"; ++ command[ncommand++] = NULL; ++ ++ TRACE (TRACE_FUNCTION, "Forking server: %s %s %s", ++ command[0] ? command[0] : "(null)", ++ command[1] ? command[1] : "(null)", ++ command[2] ? command[2] : ""); + + child_pid = piped_child (command, &tofd, &fromfd, false); + if (child_pid < 0) +@@ -3901,8 +3918,12 @@ + case ext_method: + #ifdef NO_EXT_METHOD + error (0, 0, ":ext: method not supported by this port of CVS"); ++ if (0) ++ case extssh_method: ++ error (0, 0, ":extssh: method not supported by this port of CVS"); + error (1, 0, "try :server: instead"); + #else /* ! NO_EXT_METHOD */ ++ case extssh_method: + start_rsh_server (root, to_server_p, + from_server_p); + #endif /* NO_EXT_METHOD */ +@@ -4362,7 +4383,7 @@ + sprintf (tmp, "%lu\n", (unsigned long) newsize); + send_to_server (tmp, 0); + +- send_to_server (buf, newsize); ++ send_to_server ((const void *)buf, newsize); + } + } + else +@@ -4415,7 +4436,7 @@ + * one. + */ + if (newsize > 0) +- send_to_server (buf, newsize); ++ send_to_server ((const void *)buf, newsize); + } + free (buf); + free (mode_string); +@@ -4914,7 +4935,7 @@ + { + if (supported_request ("Max-dotdot")) + { +- char buf[10]; ++ char buf[12]; + sprintf (buf, "%d", max_level); + + send_to_server ("Max-dotdot ", 0); +--- cvs-1.12.13+real.orig/src/client.h ++++ cvs-1.12.13+real/src/client.h +@@ -213,6 +213,7 @@ + #if defined AUTH_CLIENT_SUPPORT || defined HAVE_KERBEROS || defined HAVE_GSSAPI + # include <sys/socket.h> + # include <netinet/in.h> ++# include <netinet/tcp.h> + # include <arpa/inet.h> + # include <netdb.h> + struct hostent *init_sockaddr (struct sockaddr_in *, char *, unsigned int); +--- cvs-1.12.13+real.orig/src/commit.c ++++ cvs-1.12.13+real/src/commit.c +@@ -1,5 +1,7 @@ + /* + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. ++ * Copyright (c) 2007 Benny Siegert <bsiegert@mirbsd.org> ++ * Copyright (c) 2005, 2007, 2021 mirabilos <m@mirbsd.org> + * + * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>, + * and others. +@@ -492,7 +494,7 @@ + + /* Now we keep track of which files we actually are going to + operate on, and only work with those files in the future. +- This saves time--we don't want to search the file system ++ This saves time--we don't want to search the filesystem + of the working directory twice. */ + if (size_overflow_p (xtimes (find_args.argc, sizeof (char **)))) + { +@@ -613,31 +615,7 @@ + + send_to_server ("ci\012", 0); + err = get_responses_and_close (); +- if (err != 0 && use_editor && saved_message != NULL) +- { +- /* If there was an error, don't nuke the user's carefully +- constructed prose. This is something of a kludge; a better +- solution is probably more along the lines of #150 in TODO +- (doing a second up-to-date check before accepting the +- log message has also been suggested, but that seems kind of +- iffy because the real up-to-date check could still fail, +- another error could occur, &c. Also, a second check would +- slow things down). */ +- +- char *fname; +- FILE *fp; +- +- fp = cvs_temp_file (&fname); +- if (fp == NULL) +- error (1, 0, "cannot create temporary file %s", fname); +- if (fwrite (saved_message, 1, strlen (saved_message), fp) +- != strlen (saved_message)) +- error (1, errno, "cannot write temporary file %s", fname); +- if (fclose (fp) < 0) +- error (0, errno, "cannot close temporary file %s", fname); +- error (0, 0, "saving log message in %s", fname); +- free (fname); +- } ++ logmsg_cleanup(err); + return err; + } + #endif +@@ -702,6 +680,7 @@ + sleep_past (last_register_time); + } + ++ logmsg_cleanup(err); + return err; + } + +@@ -853,7 +832,7 @@ + case T_ADDED: + case T_REMOVED: + { +- char *editor; ++ char *editor = NULL; + + /* + * some quick sanity checks; if no numeric -r option specified: +@@ -1196,7 +1175,7 @@ + doff = d - *c->buf; + expand_string (c->buf, c->length, doff + strlen (arg)); + d = *c->buf + doff; +- strncpy (d, arg, strlen (arg)); ++ memcpy (d, arg, strlen (arg)); + d += strlen (arg); + free (arg); + +@@ -1250,6 +1229,7 @@ + #endif /* SUPPORT_OLD_INFO_FMT_STRINGS */ + filter, + "c", "s", cvs_cmd_name, ++ "I", "s", global_session_id, + #ifdef SERVER_SUPPORT + "R", "s", referrer ? referrer->original : "NONE", + #endif /* SERVER_SUPPORT */ +@@ -2255,9 +2235,10 @@ + this was added into the log message. */ + t = time (NULL); + ct = gmtime (&t); +- tmp = Xasprintf ("file %s was added on branch %s on %d-%02d-%02d %02d:%02d:%02d +0000", ++ tmp = Xasprintf ("file %s was added on branch %s on %ld-%02d-%02d %02d:%02d:%02d +0000", + file, tag, +- ct->tm_year + (ct->tm_year < 100 ? 0 : 1900), ++ (long)ct->tm_year ++ + (ct->tm_year < 100 ? 0 : 1900), + ct->tm_mon + 1, ct->tm_mday, + ct->tm_hour, ct->tm_min, ct->tm_sec); + +--- cvs-1.12.13+real.orig/src/cvs.h ++++ cvs-1.12.13+real/src/cvs.h +@@ -1,5 +1,9 @@ ++/* $MirOS: src/gnu/usr.bin/cvs/src/cvs.h,v 1.10 2021/01/30 02:06:05 tg Exp $ */ ++ + /* + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. ++ * Copyright (c) 2007 Benny Siegert <bsiegert@mirbsd.org> ++ * Copyright (c) 2017, 2021 mirabilos <m@mirbsd.org> + * + * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>, + * and others. +@@ -24,7 +28,7 @@ + /* Add GNU attribute suppport. */ + #ifndef __attribute__ + /* This feature is available in gcc versions 2.5 and later. */ +-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ ++# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || (defined(__STRICT_ANSI__) && (__STRICT_ANSI__)) + # define __attribute__(Spec) /* empty */ + # else + # if __GNUC__ == 2 && __GNUC_MINOR__ < 96 +@@ -365,6 +369,7 @@ + + extern const char *program_name, *program_path, *cvs_cmd_name; + extern char *Editor; ++extern char *LogMsgFile; + extern int cvsadmin_root; + extern char *CurDir; + extern int really_quiet, quiet; +@@ -504,6 +509,8 @@ + int unlink_file (const char *f); + int unlink_file_dir (const char *f); + ++int suck (int argc, char *argv[]); ++ + /* This is the structure that the recursion processor passes to the + fileproc to tell it about a particular file. */ + struct file_info +@@ -585,7 +592,8 @@ + void check_entries (char *dir); + void close_module (DBM * db); + void copy_file (const char *from, const char *to); +-void fperrmsg (FILE * fp, int status, int errnum, char *message,...); ++void fpwarnmsg (FILE * fp, int errnum, char *message, ...) ++ __attribute__ ((__format__(__printf__, 3, 4))); + + int ign_name (char *name); + void ign_add (char *ign, int hold); +@@ -618,7 +626,8 @@ + void cleanup_register (void (*handler) (void)); + + void update_delproc (Node * p); +-void usage (const char *const *cpp); ++void usage (const char *const *cpp) ++ __attribute__((__noreturn__)); + void xchmod (const char *fname, int writable); + List *Find_Names (char *repository, int which, int aflag, + List ** optentries); +@@ -629,6 +638,7 @@ + FILE *xlogfp, List *xchanges); + void do_editor (const char *dir, char **messagep, + const char *repository, List *changes); ++void logmsg_cleanup (int err); + + void do_verify (char **messagep, const char *repository, List *changes); + +@@ -726,7 +736,7 @@ + /* This is the timestamp from stating the file in the working directory. + It is NULL if there is no file in the working directory. It is + "Is-modified" if we know the file is modified but don't have its +- contents. */ ++ contents. See also: ts_user_ists. */ + char *ts_user; + /* Timestamp from CVS/Entries. For the server, ts_user and ts_rcs + are computed in a slightly different way, but the fact remains that +@@ -759,6 +769,9 @@ + + /* Pointer to parsed src file info */ + RCSNode *srcfile; ++ ++ /* 1 if ts_user is known to be the actual timestamp of a local file */ ++ unsigned char ts_user_ists; + }; + typedef struct vers_ts Vers_TS; + +@@ -911,11 +924,15 @@ + + /* From server.c and documented there. */ + void cvs_output (const char *, size_t); ++void cvs_output_ex (const char *, size_t, int); + void cvs_output_binary (char *, size_t); + void cvs_outerr (const char *, size_t); + void cvs_flusherr (void); + void cvs_flushout (void); + void cvs_output_tagged (const char *, const char *); ++int supported_response (const char *); ++ ++#define CVS_OUTPUT_EX_LOGM 0x80000001 + + extern const char *global_session_id; + +--- cvs-1.12.13+real.orig/src/cvsrc.c ++++ cvs-1.12.13+real/src/cvsrc.c +@@ -41,6 +41,7 @@ + size_t line_chars_allocated; + + char *optstart; ++ int white_len = 0; + + int command_len; + int found = 0; +@@ -96,9 +97,12 @@ + if (line[0] == '#') + continue; + ++ while (isspace(line[white_len])) ++ ++white_len; ++ + /* stop if we match the current command */ +- if (!strncmp (line, cmdname, command_len) +- && isspace ((unsigned char) *(line + command_len))) ++ if (!strncmp (line + white_len, cmdname, command_len) ++ && isspace ((unsigned char) *(line + white_len + command_len))) + { + found = 1; + break; +@@ -120,7 +124,7 @@ + if (found) + { + /* skip over command in the options line */ +- for (optstart = strtok (line + command_len, "\t \n"); ++ for (optstart = strtok (line + white_len + command_len, "\t \n"); + optstart; + optstart = strtok (NULL, "\t \n")) + { +--- cvs-1.12.13+real.orig/src/diff.c ++++ cvs-1.12.13+real/src/diff.c +@@ -21,6 +21,8 @@ + + #include "cvs.h" + ++#define TAG_BHEAD ".bhead" ++ + enum diff_file + { + DIFF_ERROR, +@@ -444,9 +446,9 @@ + } + #endif + +- if (diff_rev1 != NULL) ++ if (diff_rev1 != NULL && strcmp(diff_rev1, TAG_BHEAD)) + tag_check_valid (diff_rev1, argc, argv, local, 0, "", false); +- if (diff_rev2 != NULL) ++ if (diff_rev2 != NULL && strcmp(diff_rev2, TAG_BHEAD)) + tag_check_valid (diff_rev2, argc, argv, local, 0, "", false); + + which = W_LOCAL; +@@ -903,8 +905,14 @@ + + if (diff_rev1 || diff_date1) + { +- /* special handling for TAG_HEAD */ +- if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0) ++ /* ++ * the special handling is broken, -rbranchname is the ++ * head (tip) of the branch already, -rHEAD is supposed ++ * to be the head (tip) of the MAIN branch (trunk); we ++ * introduce ".bhead" here, for now, but only here ++ */ ++ /* special handling for TAG_BHEAD */ ++ if (diff_rev1 && strcmp (diff_rev1, TAG_BHEAD) == 0) + { + if (vers->vn_rcs != NULL && vers->srcfile != NULL) + use_rev1 = RCS_branch_head (vers->srcfile, vers->vn_rcs); +@@ -919,8 +927,8 @@ + } + if (diff_rev2 || diff_date2) + { +- /* special handling for TAG_HEAD */ +- if (diff_rev2 && strcmp (diff_rev2, TAG_HEAD) == 0) ++ /* special handling for TAG_BHEAD */ ++ if (diff_rev2 && strcmp (diff_rev2, TAG_BHEAD) == 0) + { + if (vers->vn_rcs && vers->srcfile) + use_rev2 = RCS_branch_head (vers->srcfile, vers->vn_rcs); +--- cvs-1.12.13+real.orig/src/edit.c ++++ cvs-1.12.13+real/src/edit.c +@@ -266,7 +266,7 @@ + cvs_output (p++, 1); + if (*p == '\0') + { +- /* Only happens if attribute is misformed. */ ++ /* Only happens if attribute is malformed. */ + cvs_output ("\n", 1); + break; + } +@@ -828,6 +828,7 @@ + #endif /* SUPPORT_OLD_INFO_FMT_STRINGS */ + filter, + "c", "s", cvs_cmd_name, ++ "I", "s", global_session_id, + #ifdef SERVER_SUPPORT + "R", "s", referrer ? referrer->original : "NONE", + #endif /* SERVER_SUPPORT */ +--- cvs-1.12.13+real.orig/src/error.c ++++ cvs-1.12.13+real/src/error.c +@@ -1,5 +1,6 @@ + /* error.c -- error handler for noninteractive utilities + Copyright (C) 1990-1992 Free Software Foundation, Inc. ++ Copyright (c) 2011, 2021 mirabilos <m@mirbsd.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -57,7 +58,7 @@ + * represents the system dependent message returned by strerror (ERRNUM), when + * ERRNUM is non-zero. + * +- * Exit with status EXIT_FAILURE if STATUS is nonzero. ++ * error() exits with status EXIT_FAILURE if STATUS is nonzero. + * + * If this function fails to get any memory it might request, it attempts to + * log a "memory exhausted" message to the syslog, when syslog is available, +@@ -65,7 +66,7 @@ + * below for more information on this functions memory allocation. + * + * INPUTS +- * status When non-zero, exit with EXIT_FAILURE rather than returning. ++ * status warning() returns this value for the error() macro. + * errnum When non-zero, interpret as global ERRNO for the purpose of + * generating additional error text. + * message A printf style format string. +@@ -104,8 +105,8 @@ + * RETURNS + * Sometimes. ;) + */ +-void +-error (int status, int errnum, const char *message, ...) ++int ++warning(int status, int errnum, const char *message, ...) + { + va_list args; + int save_errno = errno; +@@ -180,7 +181,7 @@ + + /* Done, if we're exiting. */ + if (status) +- exit (EXIT_FAILURE); ++ return (status); + + /* Free anything we may have allocated. */ + if (buf != statbuf) free (buf); +@@ -191,7 +192,7 @@ + errno = save_errno; + + /* Done. */ +- return; ++ return (status); + + memerror: + /* Make one last attempt to log the problem in the syslog since that +@@ -208,7 +209,7 @@ + * with the message here. + */ + #if HAVE_SYSLOG_H +- syslog (LOG_DAEMON | LOG_EMERG, "Memory exhausted. Aborting."); ++ syslog (LOG_DAEMON | LOG_CRIT, "Memory exhausted. Aborting."); + #endif /* HAVE_SYSLOG_H */ + + goto sidestep_done; +@@ -219,18 +220,18 @@ + * error while attempting to send the last error message to the client. + */ + +- syslog (LOG_DAEMON | LOG_EMERG, ++ syslog (LOG_DAEMON | LOG_ALERT, + "error (%d, %d) called recursively. Original message was:", + last_status, last_errnum); +- syslog (LOG_DAEMON | LOG_EMERG, "%s", last_message); ++ syslog (LOG_DAEMON | LOG_ALERT, "%s", last_message); + + +- syslog (LOG_DAEMON | LOG_EMERG, ++ syslog (LOG_DAEMON | LOG_ALERT, + "error (%d, %d) called recursively. Second message was:", + status, errnum); +- syslog (LOG_DAEMON | LOG_EMERG, "%s", buf2); ++ syslog (LOG_DAEMON | LOG_ALERT, "%s", buf2); + +- syslog (LOG_DAEMON | LOG_EMERG, "Aborting."); ++ syslog (LOG_DAEMON | LOG_ALERT, "Aborting."); + #endif /* HAVE_SYSLOG_H */ + + sidestep_done: +@@ -247,10 +248,10 @@ + /* Print the program name and error message MESSAGE, which is a printf-style + format string with optional args to the file specified by FP. + If ERRNUM is nonzero, print its corresponding system error message. +- Exit with status EXIT_FAILURE if STATUS is nonzero. */ ++*/ + /* VARARGS */ + void +-fperrmsg (FILE *fp, int status, int errnum, char *message, ...) ++fpwarnmsg (FILE *fp, int errnum, char *message, ...) + { + va_list args; + +@@ -262,6 +263,4 @@ + fprintf (fp, ": %s", strerror (errnum)); + putc ('\n', fp); + fflush (fp); +- if (status) +- exit (EXIT_FAILURE); + } +--- cvs-1.12.13+real.orig/src/fileattr.c ++++ cvs-1.12.13+real/src/fileattr.c +@@ -514,6 +514,7 @@ + TRACE (TRACE_FUNCTION, "postwatch_proc (%s, %s)", repository, filter); + + /* %c = command name ++ * %I = commit ID + * %p = shortrepos + * %r = repository + */ +@@ -528,6 +529,7 @@ + #endif /* SUPPORT_OLD_INFO_FMT_STRINGS */ + filter, + "c", "s", cvs_cmd_name, ++ "I", "s", global_session_id, + #ifdef SERVER_SUPPORT + "R", "s", referrer ? referrer->original : "NONE", + #endif /* SERVER_SUPPORT */ +--- cvs-1.12.13+real.orig/src/filesubr.c ++++ cvs-1.12.13+real/src/filesubr.c +@@ -1,5 +1,6 @@ + /* filesubr.c --- subroutines for dealing with files + Jim Blandy <jimb@cyclic.com> ++ © 2010, 2017, 2021 mirabilos <m@mirbsd.org> + + This file is part of GNU CVS. + +@@ -15,7 +16,7 @@ + + /* 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. */ ++ filesystem semantics. */ + + #include "cvs.h" + #include "lstat.h" +@@ -645,6 +646,10 @@ + error (1, errno, "cannot read file %s for comparing", file2); + + /* assert (read1 == read2); */ ++#if defined(__GNUC__) && /* stupid */ (__GNUC__ > 4) ++ if (read1 > buf_size) ++ __builtin_unreachable(); ++#endif + + ret = memcmp(buf1, buf2, read1); + } while (ret == 0 && read1 == buf_size); +@@ -808,7 +813,7 @@ + if (home != NULL) + return home; + +- if (!server_active && (env = getenv ("HOME")) != NULL) ++ if (!server_active && (env = getenv ("HOME")) != NULL && *env) + home = env; + else if ((pw = (struct passwd *) getpwuid (getuid ())) + && pw->pw_dir) +@@ -863,7 +868,11 @@ + const char * + get_system_temp_dir (void) + { +- if (!tmpdir_env) tmpdir_env = getenv (TMPDIR_ENV); ++ if (!tmpdir_env) { ++ tmpdir_env = getenv (TMPDIR_ENV); ++ if (tmpdir_env && !*tmpdir_env) ++ tmpdir_env = NULL; ++ } + return tmpdir_env; + } + +--- cvs-1.12.13+real.orig/src/history.c ++++ cvs-1.12.13+real/src/history.c +@@ -1,5 +1,6 @@ + /* + * Copyright (C) 1994-2005 The Free Software Foundation, Inc. ++ * Copyright (c) 2005, 2010, 2021 mirabilos <m@mirbsd.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -362,10 +363,11 @@ + + /* + * By default, sort by date, time +- * XXX: This fails after 2030 when date slides into sign bit + */ +- if ((i = ((long) (left->date) - (long) (right->date))) != 0) +- return i; ++ if (left->date > right->date) ++ return (1); ++ if (left->date < right->date) ++ return (-1); + + /* For matching dates, keep the sort stable by using record index */ + return left->idx - right->idx; +@@ -376,10 +378,10 @@ + /* Get the name of the history log, either from CVSROOT/config, or via the + * hard-coded default. + */ +-static const char * ++static char * + get_history_log_name (time_t now) + { +- char *log_name; ++ char *log_name = NULL; + + if (config->HistoryLogPath) + { +@@ -762,7 +764,7 @@ + history_write (int type, const char *update_dir, const char *revs, + const char *name, const char *repository) + { +- const char *fname; ++ char *fname = NULL; + char *workdir; + char *username = getcaller (); + int fd; +@@ -897,16 +899,16 @@ + + if (!revs) + revs = ""; ++ if (!history_lock (current_parsed_root->directory)) ++ /* history_lock() will already have printed an error on failure. */ ++ goto out; ++ + now = time (NULL); +- line = Xasprintf ("%c%08lx|%s|%s|%s|%s|%s\n", type, (long) now, ++ line = Xasprintf ("%c%08lx|%s|%s|%s|%s|%s\n", type, (unsigned long)now, + username, workdir, repos, revs, name); + + fname = get_history_log_name (now); + +- if (!history_lock (current_parsed_root->directory)) +- /* history_lock() will already have printed an error on failure. */ +- goto out; +- + fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | O_CREAT | OPEN_BINARY, 0666); + if (fd < 0) + { +@@ -936,6 +938,7 @@ + error (1, errno, "cannot close history file: %s", fname); + free (workdir); + out: ++ free (fname); + clear_history_lock (); + } + +@@ -1561,7 +1564,7 @@ + tm = localtime (&(lr->date)); + + (void) printf ("%c %04d-%02d-%02d %02d:%02d %s %-*s", ty, +- tm->tm_year+1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, ++ (int)(tm->tm_year+1900), tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, + tm->tm_min, tz_name, user_len, lr->user); + + workdir = xmalloc (strlen (lr->dir) + strlen (lr->end) + 10); +--- cvs-1.12.13+real.orig/src/import.c ++++ cvs-1.12.13+real/src/import.c +@@ -1,5 +1,8 @@ + /* + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. ++ * Copyright (c) 2007 Benny Siegert <bsiegert@mirbsd.org> ++ * Copyright (c) 2005, 2007, 2010, 2016, 2017, 2021 ++ * mirabilos <m@mirbsd.org> + * + * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>, + * and others. +@@ -25,7 +28,7 @@ + #include "lstat.h" + #include "save-cwd.h" + +-static char *get_comment (const char *user); ++static const char *get_comment (const char *user); + static int add_rev (char *message, RCSNode *rcs, char *vfile, + char *vers); + static int add_tags (RCSNode *rcs, char *vfile, char *vtag, int targc, +@@ -238,6 +241,23 @@ + regfree (&pat); + } + ++ /* ++ * If you use even vendor branches, something evil[TM] can happen. ++ */ ++ { ++ regex_t pat; ++ assert (!regcomp (&pat, "^[1-9][0-9]*\\.[1-9][0-9]*\\.[0-9]*[13579]$", ++ REG_EXTENDED)); ++ if (regexec (&pat, vbranch, 0, NULL, 0)) ++ { ++ error (0, 0, ++ "warning: you are using an even vendor branch, which can\n" ++ "lead to problems: '%s'. Use an odd branch such as '1.1.3' instead.", ++ vbranch); ++ } ++ regfree (&pat); ++ } ++ + /* Set vhead to the branch's parent. */ + vhead = xstrdup (vbranch); + cp = strrchr (vhead, '.'); +@@ -311,6 +331,7 @@ + free (vhead); + send_to_server ("import\012", 0); + err += get_responses_and_close (); ++ logmsg_cleanup(err); + return err; + } + #endif +@@ -436,6 +457,7 @@ + free (vbranch); + free (vhead); + ++ logmsg_cleanup(err); + return err; + } + +@@ -595,7 +617,7 @@ + /* Attempt to make the Attic directory, in case it + does not exist. */ + (void) sprintf (rcs, "%s/%s", repository, CVSATTIC); +- if (CVS_MKDIR (rcs, 0777 ) != 0 && errno != EEXIST) ++ if (noexec == 0 && CVS_MKDIR (rcs, 0777 ) != 0 && errno != EEXIST) + error (1, errno, "cannot make directory `%s'", rcs); + + /* Note that the above clobbered the path name, so we +@@ -790,7 +812,7 @@ + { + if (!noexec) + { +- fperrmsg (logfp, 0, status == -1 ? ierrno : 0, ++ fpwarnmsg (logfp, status == -1 ? ierrno : 0, + "ERROR: Check-in of %s failed", rcs->path); + error (0, status == -1 ? ierrno : 0, + "ERROR: Check-in of %s failed", rcs->path); +@@ -825,7 +847,7 @@ + if ((retcode = RCS_settag (rcs, vtag, vbranch)) != 0) + { + ierrno = errno; +- fperrmsg (logfp, 0, retcode == -1 ? ierrno : 0, ++ fpwarnmsg (logfp, retcode == -1 ? ierrno : 0, + "ERROR: Failed to set tag %s in %s", vtag, rcs->path); + error (0, retcode == -1 ? ierrno : 0, + "ERROR: Failed to set tag %s in %s", vtag, rcs->path); +@@ -849,7 +871,7 @@ + else + { + ierrno = errno; +- fperrmsg (logfp, 0, retcode == -1 ? ierrno : 0, ++ fpwarnmsg (logfp, retcode == -1 ? ierrno : 0, + "WARNING: Couldn't add tag %s to %s", targv[i], + rcs->path); + error (0, retcode == -1 ? ierrno : 0, +@@ -866,7 +888,8 @@ + */ + struct compair + { +- char *suffix, *comlead; ++ const char *suffix; ++ const char *comlead; + }; + + static const struct compair comtable[] = +@@ -973,13 +996,13 @@ + + + +-static char * ++static const char * + get_comment (const char *user) + { + char *cp, *suffix; + char *suffix_path; + int i; +- char *retval; ++ const char *retval; + + suffix_path = xmalloc (strlen (user) + 5); + cp = strrchr (user, '.'); +@@ -1144,7 +1167,7 @@ + { + /* not fatal, continue import */ + if (add_logfp != NULL) +- fperrmsg (add_logfp, 0, errno, ++ fpwarnmsg (add_logfp, errno, + "ERROR: cannot lstat file %s", userfile); + error (0, errno, "cannot lstat file %s", userfile); + goto read_error; +@@ -1167,7 +1190,7 @@ + { + /* not fatal, continue import */ + if (add_logfp != NULL) +- fperrmsg (add_logfp, 0, errno, ++ fpwarnmsg (add_logfp, errno, + "ERROR: cannot read file %s", userfile); + error (0, errno, "ERROR: cannot read file %s", userfile); + goto read_error; +@@ -1253,7 +1276,7 @@ + (void) time (&now); + ftm = gmtime (&now); + (void) sprintf (altdate1, DATEFORM, +- ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), ++ (long)ftm->tm_year + (ftm->tm_year < 100 ? 0L : 1900L), + ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, + ftm->tm_min, ftm->tm_sec); + author = getcaller (); +@@ -1459,7 +1482,7 @@ + { + ierrno = errno; + if (add_logfp != NULL) +- fperrmsg (add_logfp, 0, ierrno, ++ fpwarnmsg (add_logfp, ierrno, + "WARNING: cannot change mode of file %s", rcs); + error (0, ierrno, "WARNING: cannot change mode of file %s", rcs); + err++; +@@ -1479,14 +1502,14 @@ + if (fclose (fpuser) < 0) + error (0, errno, "cannot close %s", user); + if (add_logfp != NULL) +- fperrmsg (add_logfp, 0, ierrno, "ERROR: cannot write file %s", rcs); ++ fpwarnmsg (add_logfp, ierrno, "ERROR: cannot write file %s", rcs); + error (0, ierrno, "ERROR: cannot write file %s", rcs); + if (ierrno == ENOSPC) + { + if (CVS_UNLINK (rcs) < 0) + error (0, errno, "cannot remove %s", rcs); + if (add_logfp != NULL) +- fperrmsg (add_logfp, 0, 0, "ERROR: out of space - aborting"); ++ fpwarnmsg (add_logfp, 0, "ERROR: out of space - aborting"); + error (1, 0, "ERROR: out of space - aborting"); + } + read_error: +@@ -1709,7 +1732,7 @@ + return 0; + if (save_cwd (&cwd)) + { +- fperrmsg (logfp, 0, errno, "Failed to save current directory."); ++ fpwarnmsg (logfp, errno, "Failed to save current directory."); + return 1; + } + +@@ -1733,7 +1756,7 @@ + if (CVS_CHDIR (dir) < 0) + { + ierrno = errno; +- fperrmsg (logfp, 0, ierrno, "ERROR: cannot chdir to %s", repository); ++ fpwarnmsg (logfp, ierrno, "ERROR: cannot chdir to %s", repository); + error (0, ierrno, "ERROR: cannot chdir to %s", repository); + err = 1; + goto out; +@@ -1743,7 +1766,7 @@ + rcs = Xasprintf ("%s%s", repository, RCSEXT); + if (isfile (repository) || isfile (rcs)) + { +- fperrmsg (logfp, 0, 0, ++ fpwarnmsg (logfp, 0, + "ERROR: %s is a file, should be a directory!", + repository); + error (0, 0, "ERROR: %s is a file, should be a directory!", +@@ -1754,7 +1777,7 @@ + if (noexec == 0 && CVS_MKDIR (repository, 0777) < 0) + { + ierrno = errno; +- fperrmsg (logfp, 0, ierrno, ++ fpwarnmsg (logfp, ierrno, + "ERROR: cannot mkdir %s -- not added", repository); + error (0, ierrno, + "ERROR: cannot mkdir %s -- not added", repository); +--- cvs-1.12.13+real.orig/src/kerberos4-client.c ++++ cvs-1.12.13+real/src/kerberos4-client.c +@@ -17,6 +17,8 @@ + #include "buffer.h" + #include "socket-client.h" + ++#include <netinet/tcp.h> ++ + # include <krb.h> + + extern char *krb_realmofhost (); +@@ -48,6 +50,16 @@ + if (s < 0) + error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); + ++#ifdef TCP_NODELAY ++ /* Avoid latency due to Nagle algorithm. */ ++ { ++ int on = 1; ++ ++ if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on) < 0) ++ error (0, errno, "warning: cannot set TCP_NODELAY on socket"); ++ } ++#endif ++ + port = get_cvs_port_number (root); + + hp = init_sockaddr (&sin, root->hostname, port); +--- cvs-1.12.13+real.orig/src/lock.c ++++ cvs-1.12.13+real/src/lock.c +@@ -58,7 +58,7 @@ + which periodically get made about how locks might be different: + + 1. Check for EROFS. Maybe useful, although in the presence of NFS +- EROFS does *not* mean that the file system is unchanging. ++ EROFS does *not* mean that the filesystem is unchanging. + + 2. Provide an option to disable locks for operations which only + read (see above for some of the consequences). +@@ -1319,6 +1319,10 @@ + lock->repository = Xasprintf ("%s/%s", xrepository, CVSROOTADM); + lock->free_repository = true; + ++ /* do nothing if we know it fails anyway */ ++ if (readonlyfs) ++ return 0; ++ + /* get the lock dir for our own */ + if (set_lock (lock, 1) != L_OK) + { +--- cvs-1.12.13+real.orig/src/log-buffer.c ++++ cvs-1.12.13+real/src/log-buffer.c +@@ -481,7 +481,7 @@ + * We do this _after_ authentication on purpose. Wouldn't really like to + * worry about logging passwords... + */ +- if (log) ++ if (log && *log) + { + int len = strlen (log); + char *buf = xmalloc (len + 5); +--- cvs-1.12.13+real.orig/src/log.c ++++ cvs-1.12.13+real/src/log.c +@@ -1,4 +1,5 @@ + /* ++ * Copyright © 2017 mirabilos <m@mirbsd.org> + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. + * + * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>, +@@ -145,6 +146,7 @@ + RCSNode *, RCSVers *, int); + static int log_branch (Node *, void *); + static int version_compare (const char *, const char *, int); ++static void logm_output (const char *); + + static struct log_data log_data; + static int is_rlog; +@@ -1681,11 +1683,10 @@ + cvs_output ("*** empty log message ***\n", 0); + else + { ++ /* assert: last thing cvs_output’ed was a newline */ + /* FIXME: Technically, the log message could contain a null + byte. */ +- cvs_output (p->data, 0); +- if (((char *)p->data)[strlen (p->data) - 1] != '\n') +- cvs_output ("\n", 1); ++ logm_output(p->data); + } + } + +@@ -1780,3 +1781,23 @@ + ++v2; + } + } ++ ++static void ++logm_output(const char *str) ++{ ++ /* assert: str is not empty */ ++ size_t len = strlen(str); ++ int buftag = 'M'; ++ static char has_logm = 0; ++ ++ if (server_active) { ++ if (!has_logm) ++ has_logm = supported_response("LOGM") ? 1 : 2; ++ if (has_logm == 1) ++ buftag = CVS_OUTPUT_EX_LOGM; ++ } ++ ++ cvs_output_ex(str, len, buftag); ++ if (/*len > 0 &&*/ str[len - 1] != '\n') ++ cvs_output_ex("\n", 1, buftag); ++} +--- cvs-1.12.13+real.orig/src/login.c ++++ cvs-1.12.13+real/src/login.c +@@ -44,7 +44,7 @@ + char *passfile; + + /* Environment should override file. */ +- if ((passfile = getenv ("CVS_PASSFILE")) != NULL) ++ if ((passfile = getenv ("CVS_PASSFILE")) != NULL && *passfile) + return xstrdup (passfile); + + /* Construct absolute pathname to user's password file. */ +@@ -200,11 +200,21 @@ + return NULL; + } + *p = ' '; +- tmp_root_canonical = normalize_cvsroot (tmp_root); +- if (strcmp (cvsroot_canonical, tmp_root_canonical) == 0) +- password = p + 1; +- +- free (tmp_root_canonical); ++ switch (tmp_root->method) ++ { ++ case gserver_method: ++ case pserver_method: ++#ifdef HAVE_KERBEROS ++ case kserver_method: ++#endif /* HAVE_KERBEROS */ ++ tmp_root_canonical = normalize_cvsroot (tmp_root); ++ if (strcmp (cvsroot_canonical, tmp_root_canonical) == 0) ++ password = p + 1; ++ free (tmp_root_canonical); ++ break; ++ default: ++ break; ++ } + } + + return password; +@@ -309,7 +319,9 @@ + fp = CVS_FOPEN (passfile, "r"); + if (fp == NULL) + { ++ if (errno != ENOENT) { + error (0, errno, "warning: failed to open %s for reading", passfile); ++ } + goto process; + } + +@@ -432,7 +444,7 @@ + * + * I don't think so, unless we change the way rename_file works to + * attempt a cp/rm sequence when rename fails since rename doesn't +- * work across file systems and it isn't uncommon to have /tmp ++ * work across filesystems and it isn't uncommon to have /tmp + * on its own partition. + * + * For that matter, it's probably not uncommon to have a home +--- cvs-1.12.13+real.orig/src/logmsg.c ++++ cvs-1.12.13+real/src/logmsg.c +@@ -1,5 +1,7 @@ + /* + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. ++ * Copyright (c) 2007 Benny Siegert <bsiegert@mirbsd.org> ++ * Copyright (c) 2005, 2006, 2008, 2010, 2021 mirabilos <m@mirbsd.org> + * + * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>, + * and others. +@@ -31,6 +33,8 @@ + static FILE *fp; + static Ctype type; + ++char *LogMsgFile = NULL; ++ + struct verifymsg_proc_data + { + /* The name of the temp file storing the log message to be verified. This +@@ -201,6 +205,7 @@ + char *fname; + struct stat pre_stbuf, post_stbuf; + int retcode = 0; ++ int finish = 0; + + assert (!current_parsed_root->isremote != !repository); + +@@ -224,6 +229,10 @@ + (*messagep)[strlen (*messagep) - 1] != '\n') + (void) fprintf (fp, "\n"); + } ++ else ++ (void) fputc ('\n', fp); ++ if (finish) ++ goto finish_off; + + if (repository != NULL) + /* tack templates on if necessary */ +@@ -267,6 +276,9 @@ + (void) fprintf (fp, + "%s----------------------------------------------------------------------\n", + CVSEDITPREFIX); ++ if (readonlyfs) ++ (void) fprintf (fp, "%sATTENTION: read-only mode selected!\n", ++ CVSEDITPREFIX); + (void) fprintf (fp, + "%sEnter Log. Lines beginning with `%.*s' are removed automatically\n%s\n", + CVSEDITPREFIX, CVSEDITPREFIXLEN, CVSEDITPREFIX, +@@ -280,28 +292,38 @@ + "%s----------------------------------------------------------------------\n", + CVSEDITPREFIX); + ++ finish_off: + /* finish off the temp file */ + if (fclose (fp) == EOF) + error (1, errno, "%s", fname); +- if (stat (fname, &pre_stbuf) == -1) ++ if (LogMsgFile) ++ { ++ if (unlink_file (LogMsgFile) < 0) ++ error (0, errno, "warning: cannot remove temp file %s", LogMsgFile); ++ free (LogMsgFile); ++ } ++ LogMsgFile = fname; ++ if (finish) ++ return; ++ if (stat (LogMsgFile, &pre_stbuf) == -1) + pre_stbuf.st_mtime = 0; + + /* run the editor */ + run_setup (Editor); +- run_add_arg (fname); ++ run_add_arg (LogMsgFile); + if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, + RUN_NORMAL | RUN_SIGIGNORE)) != 0) + error (0, retcode == -1 ? errno : 0, "warning: editor session failed"); + + /* put the entire message back into the *messagep variable */ + +- fp = xfopen (fname, "r"); ++ fp = xfopen (LogMsgFile, "r"); + + if (*messagep) + free (*messagep); + +- if (stat (fname, &post_stbuf) != 0) +- error (1, errno, "cannot find size of temp file %s", fname); ++ if (stat (LogMsgFile, &post_stbuf) != 0) ++ error (1, errno, "cannot find size of temp file %s", LogMsgFile); + + if (post_stbuf.st_size == 0) + *messagep = NULL; +@@ -326,7 +348,7 @@ + if (line_length == -1) + { + if (ferror (fp)) +- error (0, errno, "warning: cannot read %s", fname); ++ error (0, errno, "warning: cannot read %s", LogMsgFile); + break; + } + if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0) +@@ -339,7 +361,7 @@ + } + } + if (fclose (fp) < 0) +- error (0, errno, "warning: cannot close %s", fname); ++ error (0, errno, "warning: cannot close %s", LogMsgFile); + + /* canonicalize emply messages */ + if (*messagep != NULL && +@@ -349,7 +371,11 @@ + *messagep = NULL; + } + +- if (pre_stbuf.st_mtime == post_stbuf.st_mtime || *messagep == NULL) ++ if (pre_stbuf.st_mtime == post_stbuf.st_mtime || ++ *messagep == NULL || ++ (*messagep)[0] == '\0' || ++ strcmp (*messagep, "\n") == 0 || ++ strcmp (*messagep, "\n\n") == 0) + { + for (;;) + { +@@ -361,9 +387,11 @@ + if (line_length < 0) + { + error (0, errno, "cannot read from stdin"); +- if (unlink_file (fname) < 0) ++ if (unlink_file (LogMsgFile) < 0) + error (0, errno, +- "warning: cannot remove temp file %s", fname); ++ "warning: cannot remove temp file %s", LogMsgFile); ++ free (LogMsgFile); ++ LogMsgFile = NULL; + error (1, 0, "aborting"); + } + else if (line_length == 0 +@@ -371,8 +399,10 @@ + break; + if (*line == 'a' || *line == 'A') + { +- if (unlink_file (fname) < 0) +- error (0, errno, "warning: cannot remove temp file %s", fname); ++ if (unlink_file (LogMsgFile) < 0) ++ error (0, errno, "warning: cannot remove temp file %s", LogMsgFile); ++ free (LogMsgFile); ++ LogMsgFile = NULL; + error (1, 0, "aborted by user"); + } + if (*line == 'e' || *line == 'E') +@@ -387,15 +417,14 @@ + } + if (line) + free (line); +- if (unlink_file (fname) < 0) +- error (0, errno, "warning: cannot remove temp file %s", fname); +- free (fname); ++ finish = 1; ++ goto again; + } + + /* Runs the user-defined verification script as part of the commit or import + process. This verification is meant to be run whether or not the user + included the -m attribute. unlike the do_editor function, this is +- independant of the running of an editor for getting a message. ++ independent of the running of an editor for getting a message. + */ + void + do_verify (char **messagep, const char *repository, List *changes) +@@ -670,7 +699,7 @@ + expand_string (c->buf, c->length, + doff + strlen (c->srepos) + 1); + d = *c->buf + doff; +- strncpy (d, c->srepos, strlen (c->srepos)); ++ memcpy (d, c->srepos, strlen (c->srepos)); + d += strlen (c->srepos); + *d++ = ' '; + } +@@ -690,7 +719,7 @@ + doff = d - *c->buf; + expand_string (c->buf, c->length, doff + strlen (arg)); + d = *c->buf + doff; +- strncpy (d, arg, strlen (arg)); ++ memcpy (d, arg, strlen (arg)); + d += strlen (arg); + #ifdef SUPPORT_OLD_INFO_FMT_STRINGS + if (!c->onearg) +@@ -785,6 +814,7 @@ + `%s' is left as an exercise for the reader. */ + + /* %c = cvs_cmd_name ++ * %I = commit ID + * %p = shortrepos + * %r = repository + * %{sVv} = file name, old revision (precommit), new revision (postcommit) +@@ -800,6 +830,7 @@ + #endif /* SUPPORT_OLD_INFO_FMT_STRINGS */ + filter, + "c", "s", cvs_cmd_name, ++ "I", "s", global_session_id, + #ifdef SERVER_SUPPORT + "R", "s", referrer ? referrer->original : "NONE", + #endif /* SERVER_SUPPORT */ +@@ -922,6 +953,7 @@ + #endif /* SUPPORT_OLD_INFO_FMT_STRINGS */ + script, + "c", "s", cvs_cmd_name, ++ "I", "s", global_session_id, + #ifdef SERVER_SUPPORT + "R", "s", referrer + ? referrer->original : "NONE", +@@ -975,3 +1007,20 @@ + return abs (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, + RUN_NORMAL | RUN_SIGIGNORE)); + } ++ ++void ++logmsg_cleanup (int err) ++{ ++ if (!use_editor || LogMsgFile == NULL) ++ return; ++ ++ if (err == 0) ++ { ++ if (unlink_file (LogMsgFile) < 0) ++ error (0, errno, "warning: cannot remove temp file %s", LogMsgFile); ++ } ++ else ++ error (0, 0, "your log message was saved in %s", LogMsgFile); ++ free (LogMsgFile); ++ LogMsgFile = NULL; ++} +--- cvs-1.12.13+real.orig/src/ls.c ++++ cvs-1.12.13+real/src/ls.c +@@ -3,6 +3,7 @@ + * Copyright (c) 1989-1992, Brian Berliner + * Copyright (c) 2001, Tony Hoyle + * Copyright (c) 2004, Derek R. Price & Ximbiot <http://ximbiot.com> ++ * Copyright (c) 2005, 2021 mirabilos <m@mirbsd.org> + * + * You may distribute under the terms of the GNU General Public License as + * specified in the README file that comes with the CVS source distribution. +@@ -456,7 +457,7 @@ + /* Search for our parent directory. */ + char *parent; + parent = xmalloc (strlen (update_dir) - strlen (dir) + 1); +- strncpy (parent, update_dir, strlen (update_dir) - strlen (dir)); ++ memcpy (parent, update_dir, strlen (update_dir) - strlen (dir)); + parent[strlen (update_dir) - strlen (dir)] = '\0'; + strip_trailing_slashes (parent); + p = findnode (callerdat, parent); +--- cvs-1.12.13+real.orig/src/main.c ++++ cvs-1.12.13+real/src/main.c +@@ -24,6 +24,10 @@ + #include "strftime.h" + #include "xgethostname.h" + ++#ifdef USE_LIBBSD ++uint32_t arc4random(void); ++#endif ++ + const char *program_name; + const char *program_path; + const char *cvs_cmd_name; +@@ -170,6 +174,7 @@ + #ifdef SERVER_SUPPORT + { "server", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, + #endif ++ { "suck", NULL, NULL, suck, 0 }, + { "status", "st", "stat", cvsstatus, CVS_CMD_USES_WORK_DIR }, + { "tag", "ta", "freeze", cvstag, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, + { "unedit", NULL, NULL, unedit, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, +@@ -230,7 +235,7 @@ + { + "CVS commands are:\n", + " add Add a new file/directory to the repository\n", +- " admin Administration front end for rcs\n", ++ " admin Administration front-end for RCS\n", + " annotate Show last revision where each line was modified\n", + " checkout Checkout sources for editing\n", + " commit Check files into the repository\n", +@@ -242,7 +247,7 @@ + " import Import sources into CVS, using vendor branches\n", + " init Create a CVS repository if it doesn't exist\n", + #if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT) +- " kserver Kerberos server mode\n", ++ " kserver Act in Kerberos server mode\n", + #endif + " log Print out history information for files\n", + #ifdef AUTH_CLIENT_SUPPORT +@@ -251,18 +256,19 @@ + #endif /* AUTH_CLIENT_SUPPORT */ + " ls List files available from CVS\n", + #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT) +- " pserver Password server mode\n", ++ " pserver Act in password server mode\n", + #endif + " rannotate Show last revision where each line of module was modified\n", +- " rdiff Create 'patch' format diffs between releases\n", +- " release Indicate that a Module is no longer in use\n", ++ " rdiff Create 'patch' format diffs between revisions\n", ++ " release Indicate that a work subdirectory is no longer in use\n", + " remove Remove an entry from the repository\n", + " rlog Print out history information for a module\n", + " rls List files in a module\n", + " rtag Add a symbolic tag to a module\n", + #ifdef SERVER_SUPPORT +- " server Server mode\n", ++ " server Act in server mode\n", + #endif ++ " suck Download RCS ,v file raw\n", + " status Display status information on checked out files\n", + " tag Add a symbolic tag to checked out version of files\n", + " unedit Undo an edit command\n", +@@ -283,6 +289,7 @@ + " -q Cause CVS to be somewhat quiet.\n", + " -r Make checked-out files read-only.\n", + " -w Make checked-out files read-write (default).\n", ++ " -g Force group-write permissions on checked-out files.\n", + " -n Do not execute anything that will change the disk.\n", + " -t Show trace of program execution (repeat for more\n", + " verbosity) -- try with -n.\n", +@@ -458,46 +465,6 @@ + + + +- +-enum {RANDOM_BYTES = 8}; +-enum {COMMITID_RAW_SIZE = (sizeof(time_t) + RANDOM_BYTES)}; +- +-static char const alphabet[62] = +- "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +- +-/* Divide BUF by D, returning the remainder. Replace BUF by the +- quotient. BUF[0] is the most significant part of BUF. +- D must not exceed UINT_MAX >> CHAR_BIT. */ +-static unsigned int +-divide_by (unsigned char buf[COMMITID_RAW_SIZE], unsigned int d) +-{ +- unsigned int carry = 0; +- int i; +- for (i = 0; i < COMMITID_RAW_SIZE; i++) +- { +- unsigned int byte = buf[i]; +- unsigned int dividend = (carry << CHAR_BIT) + byte; +- buf[i] = dividend / d; +- carry = dividend % d; +- } +- return carry; +-} +- +-static void +-convert (char const input[COMMITID_RAW_SIZE], char *output) +-{ +- static char const zero[COMMITID_RAW_SIZE] = { 0, }; +- unsigned char buf[COMMITID_RAW_SIZE]; +- size_t o = 0; +- memcpy (buf, input, COMMITID_RAW_SIZE); +- while (memcmp (buf, zero, COMMITID_RAW_SIZE) != 0) +- output[o++] = alphabet[divide_by (buf, sizeof alphabet)]; +- if (! o) +- output[o++] = '0'; +- output[o] = '\0'; +-} +- +- + int + main (int argc, char **argv) + { +@@ -511,7 +478,7 @@ + int help = 0; /* Has the user asked for help? This + lets us support the `cvs -H cmd' + convention to give help for cmd. */ +- static const char short_options[] = "+QqrwtnRvb:T:e:d:Hfz:s:xa"; ++ static const char short_options[] = "+QqrwgtnRvb:T:e:d:Hfz:s:xal"; + static struct option long_options[] = + { + {"help", 0, NULL, 'H'}, +@@ -521,6 +488,7 @@ + {"help-options", 0, NULL, 4}, + #ifdef SERVER_SUPPORT + {"allow-root", required_argument, NULL, 3}, ++ {"allow-root-regexp", required_argument, NULL, 14}, + #endif /* SERVER_SUPPORT */ + {0, 0, 0, 0} + }; +@@ -562,11 +530,11 @@ + * Query the environment variables up-front, so that + * they can be overridden by command line arguments + */ +- if ((cp = getenv (EDITOR1_ENV)) != NULL) ++ if ((cp = getenv (EDITOR1_ENV)) != NULL && *cp) + Editor = cp; +- else if ((cp = getenv (EDITOR2_ENV)) != NULL) ++ else if ((cp = getenv (EDITOR2_ENV)) != NULL && *cp) + Editor = cp; +- else if ((cp = getenv (EDITOR3_ENV)) != NULL) ++ else if ((cp = getenv (EDITOR3_ENV)) != NULL && *cp) + Editor = cp; + if (getenv (CVSREAD_ENV) != NULL) + cvswrite = 0; +@@ -645,6 +613,10 @@ + /* --allow-root */ + root_allow_add (optarg, gConfigPath); + break; ++ case 14: ++ /* --allow-root-regexp */ ++ root_allow_regexp_add (optarg, gConfigPath); ++ break; + #endif /* SERVER_SUPPORT */ + case 'Q': + really_quiet = 1; +@@ -658,6 +630,13 @@ + case 'w': + cvswrite = 1; + break; ++ case 'g': ++ /* ++ * Force full write permissions for the group. ++ * See the user's manual for details and dangers. ++ */ ++ umask(umask(S_IRWXG|S_IRWXO) & S_IRWXO); ++ break; + case 't': + trace++; + break; +@@ -669,14 +648,18 @@ + noexec = 1; + logoff = 1; + break; ++ case 'l': ++ /* no-op to simply ignore the old -l option */ ++ break; + case 'v': + (void) fputs ("\n", stdout); + version (0, NULL); + (void) fputs ("\n", stdout); + (void) fputs ("\ + Copyright (C) 2005 Free Software Foundation, Inc.\n\ ++Copyright (c) 2021 mirabilos <m@mirbsd.org>\n\ + \n\ +-Senior active maintainers include Larry Jones, Derek R. Price,\n\ ++Senior no longer active maintainers include Larry Jones, Derek R. Price,\n\ + and Mark D. Baushke. Please see the AUTHORS and README files from the CVS\n\ + distribution kit for a complete list of contributors and copyrights.\n", + stdout); +@@ -764,56 +747,12 @@ + if (argc < 1) + usage (usg); + +- if (readonlyfs && !really_quiet) { +- error (0, 0, +- "WARNING: Read-only repository access mode selected via `cvs -R'.\n\ +-Using this option to access a repository which some users write to may\n\ +-cause intermittent sandbox corruption."); +- } +- + /* Calculate the cvs global session ID */ + +- { +- char buf[COMMITID_RAW_SIZE] = { 0, }; +- char out[COMMITID_RAW_SIZE * 2]; +- ssize_t len = 0; +- time_t rightnow = time (NULL); +- char *startrand = buf + sizeof (time_t); +- unsigned char *p = (unsigned char *) startrand; +- size_t randbytes = RANDOM_BYTES; +- int flags = O_RDONLY; +- int fd; +-#ifdef O_NOCTTY +- flags |= O_NOCTTY; +-#endif +- if (rightnow != (time_t)-1) +- while (rightnow > 0) { +- *--p = rightnow % (UCHAR_MAX + 1); +- rightnow /= UCHAR_MAX + 1; +- } +- else { +- /* try to use more random data */ +- randbytes = COMMITID_RAW_SIZE; +- startrand = buf; +- } +- fd = open ("/dev/urandom", flags); +- if (fd >= 0) { +- len = read (fd, startrand, randbytes); +- close (fd); +- } +- if (len <= 0) { +- /* no random data was available so use pid */ +- long int pid = (long int)getpid (); +- p = (unsigned char *) (startrand + sizeof (pid)); +- while (pid > 0) { +- *--p = pid % (UCHAR_MAX + 1); +- pid /= UCHAR_MAX + 1; +- } +- } +- convert(buf, out); +- global_session_id = strdup (out); +- } +- ++ global_session_id = Xasprintf("1%010llX%04X%04X", ++ (unsigned long long)time(NULL), ++ (unsigned int)(getpid() & 0xFFFF), ++ (unsigned int)(arc4random() & 0xFFFF)); + + TRACE (TRACE_FUNCTION, "main: Session ID is %s", global_session_id); + +@@ -856,7 +795,7 @@ + a command-line flag to set the umask, since we'll have to + parse it before we get here. */ + +- if ((cp = getenv (CVSUMASK_ENV)) != NULL) ++ if ((cp = getenv (CVSUMASK_ENV)) != NULL && *cp) + { + /* FIXME: Should be accepting symbolic as well as numeric mask. */ + cvsumask = strtol (cp, &end, 8) & 0777; +@@ -992,7 +931,7 @@ + if (!CVSroot_parsed) + { + char *tmp = getenv (CVSROOT_ENV); +- if (tmp) ++ if (tmp && *tmp) + { + if (!(CVSroot_parsed = parse_cvsroot (tmp))) + error (1, 0, "Bad CVSROOT: `%s'.", tmp); +@@ -1011,7 +950,7 @@ + /* Now we've reconciled CVSROOT from the command line, the + CVS/Root file, and the environment variable. Do the + last sanity checks on the variable. */ +- if (!CVSroot_parsed) ++ if (!CVSroot_parsed && cm->func != version) + { + error (0, 0, + "No CVSROOT specified! Please use the `-d' option"); +@@ -1043,6 +982,11 @@ + + assert (current_parsed_root == NULL); + ++ /* Handle running 'cvs version' with no CVSROOT. */ ++ ++ if (cm->func == version && !CVSroot_parsed) ++ server_active = !0; ++ + /* If we're running the server, we want to execute this main + loop once and only once (we won't be serving multiple roots + from this connection, so there's no need to do it more than +@@ -1173,6 +1117,7 @@ + dellist (&root_directories); + } /* end of stuff that gets done if the user DOESN'T ask for help */ + ++ config = NULL; + root_allow_free (); + + /* This is exit rather than return because apparently that keeps +@@ -1244,7 +1189,7 @@ + if (*++p) + { + if (*date) free (*date); +- *date = Make_Date (p); ++ *date = strcmp (p, "BASE") ? Make_Date (p) : xstrdup (p); + } + } + else if (strlen (input)) +@@ -1285,7 +1230,7 @@ + ftm = localtime (&unixtime); + + (void) sprintf (date, DATEFORM, +- ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), ++ (long)ftm->tm_year + (ftm->tm_year < 100 ? 0L : 1900L), + ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, + ftm->tm_min, ftm->tm_sec); + ret = xstrdup (date); +@@ -1315,8 +1260,10 @@ + void + date_to_tm (struct tm *dest, const char *source) + { ++ int y; ++ + if (sscanf (source, SDATEFORM, +- &dest->tm_year, &dest->tm_mon, &dest->tm_mday, ++ &y, &dest->tm_mon, &dest->tm_mday, + &dest->tm_hour, &dest->tm_min, &dest->tm_sec) + != 6) + /* Is there a better way to handle errors here? I made this +@@ -1324,9 +1271,7 @@ + deal with fatal errors. */ + error (0, 0, "internal error: bad date %s", source); + +- if (dest->tm_year > 100) +- dest->tm_year -= 1900; +- ++ dest->tm_year = y - ((y > 100) ? 1900 : 0); + dest->tm_mon -= 1; + } + +@@ -1348,10 +1293,10 @@ + {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + +- sprintf (dest, "%d %s %d %02d:%02d:%02d -0000", source->tm_mday, ++ sprintf (dest, "%d %s %ld %02d:%02d:%02d -0000", source->tm_mday, + source->tm_mon < 0 || source->tm_mon > 11 + ? "???" : month_names[source->tm_mon], +- source->tm_year + 1900, source->tm_hour, source->tm_min, ++ (long)source->tm_year + 1900, source->tm_hour, source->tm_min, + source->tm_sec); + } + +@@ -1458,7 +1403,7 @@ + { + (void) fprintf (stderr, *cpp++, program_name, cvs_cmd_name); + for (; *cpp; cpp++) +- (void) fprintf (stderr, *cpp); ++ (void) fprintf (stderr, "%s", *cpp); + exit (EXIT_FAILURE); + } + +--- cvs-1.12.13+real.orig/src/mkmodules.c ++++ cvs-1.12.13+real/src/mkmodules.c +@@ -19,9 +19,9 @@ + #define DBLKSIZ 4096 /* since GNU ndbm doesn't define it */ + #endif + +-static int checkout_file (char *file, char *temp); ++static int checkout_file (const char *file, char *temp); + static char *make_tempfile (void); +-static void rename_rcsfile (char *temp, char *real); ++static void rename_rcsfile (const char *temp, const char *real); + + #ifndef MY_NDBM + static void rename_dbmfile (char *temp); +@@ -31,13 +31,13 @@ + /* Structure which describes an administrative file. */ + struct admin_file { + /* Name of the file, within the CVSROOT directory. */ +- char *filename; ++ const char *filename; + + /* This is a one line description of what the file is for. It is not + currently used, although one wonders whether it should be, somehow. + If NULL, then don't process this file in mkmodules (FIXME?: a bit of + a kludge; probably should replace this with a flags field). */ +- char *errormsg; ++ const char *errormsg; + + /* Contents which the file should have in a new repository. To avoid + problems with brain-dead compilers which choke on long string constants, +@@ -68,6 +68,7 @@ + "# If any format strings are present in the filter, they will be replaced\n", + "# as follows:\n", + "# %c = canonical name of the command being executed\n", ++ "# %I = unique (randomly generated) commit ID\n", + #ifdef PROXY_SUPPORT + "# %R = the name of the referrer, if any, otherwise the value NONE\n", + #endif +@@ -82,7 +83,7 @@ + "# Thus %{sv} is a legal format string, but will only be replaced with\n", + "# file name and new revision.\n", + "# It also generates multiple arguments for each file being operated upon.\n", +- "# That is, if two files, file1 & file2, are being commited from 1.1 to\n", ++ "# That is, if two files, file1 & file2, are being committed from 1.1 to\n", + "# version 1.1.2.1 and from 1.1.2.2 to 1.1.2.3, respectively, %{sVv} will\n", + "# generate the following six arguments in this order:\n", + "# file1, 1.1, 1.1.2.1, file2, 1.1.2.2, 1.1.2.3.\n", +@@ -124,13 +125,14 @@ + "#\n", + "# Making sure that the entered bug-id number is correct.\n", + "# Validating that the code that was reviewed is indeed the code being\n", +- "# checked in (using the bug-id number or a seperate review\n", ++ "# checked in (using the bug-id number or a separate review\n", + "# number to identify this particular code set.).\n", + "#\n", + "# If any of the above test failed, then the commit would be aborted.\n", + "#\n", + "# Format strings present in the filter will be replaced as follows:\n", + "# %c = canonical name of the command being executed\n", ++ "# %I = unique (randomly generated) commit ID\n", + #ifdef PROXY_SUPPORT + "# %R = the name of the referrer, if any, otherwise the value NONE\n", + #endif +@@ -152,8 +154,8 @@ + + static const char *const commitinfo_contents[] = { + "# The \"commitinfo\" file is used to control pre-commit checks.\n", +- "# The filter on the right is invoked with the repository and a list \n", +- "# of files to check. A non-zero exit of the filter program will \n", ++ "# The filter on the right is invoked with the repository and a list\n", ++ "# of files to check. A non-zero exit of the filter program will\n", + "# cause the commit to be aborted.\n", + "#\n", + "# The first entry on a line is a regular expression which is tested\n", +@@ -163,6 +165,7 @@ + "#\n", + "# Format strings present in the filter will be replaced as follows:\n", + "# %c = canonical name of the command being executed\n", ++ "# %I = unique (randomly generated) commit ID\n", + #ifdef PROXY_SUPPORT + "# %R = the name of the referrer, if any, otherwise the value NONE\n", + #endif +@@ -199,6 +202,7 @@ + "# | \"N\" (not branch)\n", + "# %o = operation = \"add\" | \"mov\" | \"del\"\n", + "# %c = canonical name of the command being executed\n", ++ "# %I = unique (randomly generated) commit ID\n", + #ifdef PROXY_SUPPORT + "# %R = the name of the referrer, if any, otherwise the value NONE\n", + #endif +@@ -245,6 +249,7 @@ + "# If any format strings are present in the filter, they will be replaced\n", + "# as follows:\n", + "# %c = canonical name of the command being executed\n", ++ "# %I = unique (randomly generated) commit ID\n", + #ifdef PROXY_SUPPORT + "# %R = the name of the referrer, if any, otherwise the value NONE\n", + #endif +@@ -271,6 +276,7 @@ + "# If any format strings are present in the filter, they will be replaced\n", + "# as follows:\n", + "# %c = canonical name of the command being executed\n", ++ "# %I = unique (randomly generated) commit ID\n", + #ifdef PROXY_SUPPORT + "# %R = the name of the referrer, if any, otherwise the value NONE\n", + #endif +@@ -299,6 +305,7 @@ + "# If any format strings are present in the filter, they will be replaced\n", + "# as follows:\n", + "# %c = canonical name of the command being executed\n", ++ "# %I = unique (randomly generated) commit ID\n", + #ifdef PROXY_SUPPORT + "# %R = the name of the referrer, if any, otherwise the value NONE\n", + #endif +@@ -328,6 +335,7 @@ + "# | \"N\" (not branch)\n", + "# %o = operation = \"add\" | \"mov\" | \"del\"\n", + "# %c = canonical name of the command being executed\n", ++ "# %I = unique (randomly generated) commit ID\n", + #ifdef PROXY_SUPPORT + "# %R = the name of the referrer, if any, otherwise the value NONE\n", + #endif +@@ -363,11 +371,12 @@ + + static const char *const postwatch_contents[] = { + "# The \"postwatch\" file is called after any command finishes writing new\n", +- "# file attibute (watch/edit) information in a directory.\n", ++ "# file attribute (watch/edit) information in a directory.\n", + "#\n", + "# If any format strings are present in the filter, they will be replaced\n", + "# as follows:\n", + "# %c = canonical name of the command being executed\n", ++ "# %I = unique (randomly generated) commit ID\n", + #ifdef PROXY_SUPPORT + "# %R = the name of the referrer, if any, otherwise the value NONE\n", + #endif +@@ -446,6 +455,7 @@ + "#\n", + "# format strings are replaceed as follows:\n", + "# %c = canonical name of the command being executed\n", ++ "# %I = unique (randomly generated) commit ID\n", + #ifdef PROXY_SUPPORT + "# %R = the name of the referrer, if any, otherwise the value NONE\n", + #endif +@@ -465,11 +475,10 @@ + "# key [options] directory files...\n", + "#\n", + "# Where \"options\" are composed of:\n", +- "# -i prog Run \"prog\" on \"cvs commit\" from top-level of module.\n", + "# -o prog Run \"prog\" on \"cvs checkout\" of module.\n", + "# -e prog Run \"prog\" on \"cvs export\" of module.\n", ++ "# -s status Assign a status to the module.\n", + "# -t prog Run \"prog\" on \"cvs rtag\" of module.\n", +- "# -u prog Run \"prog\" on \"cvs update\" of module.\n", + "# -d dir Place module in directory \"dir\" instead of module name.\n", + "# -l Top-level directory only -- do not recurse.\n", + "#\n", +@@ -489,67 +498,68 @@ + }; + + static const char *const config_contents[] = { +- "# Set `SystemAuth' to `no' if pserver shouldn't check system users/passwords.\n", ++ "# Set 'SystemAuth' to 'no' if pserver shouldn't check system users/passwords.\n", + "#SystemAuth=no\n", + "\n", +- "# Set `LocalKeyword' to specify a local alias for a standard keyword.\n", ++ "# Set 'LocalKeyword' to specify a local alias for a standard keyword.\n", + "#LocalKeyword=MYCVS=CVSHeader\n", + "\n", +- "# Set `KeywordExpand' to `i' followed by a list of keywords to expand or\n", +- "# `e' followed by a list of keywords to not expand.\n" +- "#KeywordExpand=iMYCVS,Name,Date\n", ++ "# Set 'KeywordExpand' to 'i' followed by a list of keywords to expand or\n", ++ "# 'e' followed by a list of keywords to not expand.\n" ++ "#KeywordExpand=iMYCVS,Name,Date,Mdocdate\n", + "#KeywordExpand=eCVSHeader\n", + "\n", + #ifdef PRESERVE_PERMISSIONS_SUPPORT +- "# Set `PreservePermissions' to `yes' to save file status information\n", ++ "# Set 'PreservePermissions' to 'yes' to save file status information\n", + "# in the repository.\n", + "#PreservePermissions=no\n", + "\n", + #endif +- "# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top\n", +- "# level of the new working directory when using the `cvs checkout'\n", ++ "# Set 'TopLevelAdmin' to 'yes' to create a CVS directory at the top\n", ++ "# level of the new working directory when using the 'cvs checkout'\n", + "# command.\n", + "#TopLevelAdmin=no\n", + "\n", + "# Put CVS lock files in this directory rather than directly in the repository.\n", + "#LockDir=/var/lock/cvs\n", + "\n", +- "# Set `LogHistory' to `all' or `" ALL_HISTORY_REC_TYPES "' to log all transactions to the\n", +- "# history file, or a subset as needed (ie `TMAR' logs all write operations)\n", ++ "# Set 'LogHistory' to 'all' or '" ALL_HISTORY_REC_TYPES "' to log all transactions to the\n", ++ "# history file, or a subset as needed (ie 'TMAR' logs all write operations)\n", + "#LogHistory=" ALL_HISTORY_REC_TYPES "\n", ++ "LogHistory=TMAR\n", + "\n", +- "# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg\n", +- "# script to change the log message. Set it to `stat' to force CVS to verify\n", ++ "# Set 'RereadLogAfterVerify' to 'always' (the default) to allow the verifymsg\n", ++ "# script to change the log message. Set it to 'stat' to force CVS to verify\n", + "# that the file has changed before reading it (this can take up to an extra\n", + "# second per directory being committed, so it is not recommended for large\n", +- "# repositories. Set it to `never' (the previous CVS behavior) to prevent\n", ++ "# repositories. Set it to 'never' (the previous CVS behavior) to prevent\n", + "# verifymsg scripts from changing the log message.\n", + "#RereadLogAfterVerify=always\n", + "\n", +- "# Set `UserAdminOptions' to the list of `cvs admin' commands (options)\n", +- "# that users not in the `cvsadmin' group are allowed to run. This\n", +- "# defaults to `k', or only allowing the changing of the default\n", +- "# keyword expansion mode for files for users not in the `cvsadmin' group.\n", +- "# This value is ignored if the `cvsadmin' group does not exist.\n", ++ "# Set 'UserAdminOptions' to the list of 'cvs admin' commands (options)\n", ++ "# that users not in the '_cvsadmin' group are allowed to run. This\n", ++ "# defaults to 'k', or only allowing the changing of the default\n", ++ "# keyword expansion mode for files for users not in the '_cvsadmin' group.\n", ++ "# This value is ignored if the '_cvsadmin' group does not exist.\n", + "#\n", +- "# The following string would enable all `cvs admin' commands for all\n", ++ "# The following string would enable all 'cvs admin' commands for all\n", + "# users:\n", + "#UserAdminOptions=aAbceIklLmnNostuU\n", + #ifdef SUPPORT_OLD_INFO_FMT_STRINGS + "\n", +- "# Set `UseNewInfoFmtStrings' to `no' if you must support a legacy system by\n", ++ "# Set 'UseNewInfoFmtStrings' to 'no' if you must support a legacy system by\n", + "# enabling the deprecated old style info file command line format strings.\n", + "# Be warned that these strings could be disabled in any new version of CVS.\n", + "UseNewInfoFmtStrings=yes\n", + #endif /* SUPPORT_OLD_INFO_FMT_STRINGS */ + "\n", +- "# Set `ImportNewFilesToVendorBranchOnly' to `yes' if you wish to force\n", +- "# every `cvs import' command to behave as if the `-X' flag was\n", ++ "# Set 'ImportNewFilesToVendorBranchOnly' to 'yes' if you wish to force\n", ++ "# every 'cvs import' command to behave as if the '-X' flag was\n", + "# specified.\n", + "#ImportNewFilesToVendorBranchOnly=no\n", + #ifdef PROXY_SUPPORT + "\n", +- "# Set `PrimaryServer' to the CVSROOT to the primary, or write, server when\n", ++ "# Set 'PrimaryServer' to the CVSROOT to the primary, or write, server when\n", + "# establishing one or more read-only mirrors which serve as proxies for\n", + "# the write server in write mode or redirect the client to the primary for\n", + "# write requests.\n", +@@ -558,13 +568,13 @@ + "#\n", + "# PrimaryServer=:fork:localhost/cvsroot\n", + "\n", +- "# Set `MaxProxyBufferSize' to the the maximum allowable secondary\n", ++ "# Set 'MaxProxyBufferSize' to the the maximum allowable secondary\n", + "# buffer memory cache size before the buffer begins being stored to disk, in\n", +- "# bytes. Must be a positive integer but may end in `k', `M', `G', or `T' (for\n", +- "# kiilo, mega, giga, & tera, respectively). If an otherwise valid number you\n", ++ "# bytes. Must be a positive integer but may end in 'K', 'M', 'G', or 'T' (for\n", ++ "# Kibi, Mebi, Gibi, & Tebi, respectively). If an otherwise valid number you\n", + "# specify is greater than the SIZE_MAX defined by your system's C compiler,\n", + "# then it will be resolved to SIZE_MAX without a warning. Defaults to 8M (8\n", +- "# megabytes).\n", ++ "# Mebibytes). The 'i' from 'Ki', 'Mi', etc. is omitted.\n", + "#\n", + "# High values for MaxProxyBufferSize may speed up a secondary server\n", + "# with old hardware and a lot of available memory but can actually slow a\n", +@@ -575,23 +585,23 @@ + "# MaxProxyBufferSize=1G\n", + #endif /* PROXY_SUPPORT */ + "\n", +- "# Set `MaxCommentLeaderLength' to the maximum length permitted for the\n", ++ "# Set 'MaxCommentLeaderLength' to the maximum length permitted for the\n", + "# automagically determined comment leader used when expanding the Log\n", + "# keyword, in bytes. CVS's behavior when the automagically determined\n", +- "# comment leader exceeds this length is dependant on the value of\n", +- "# `UseArchiveCommentLeader' set in this file. `unlimited' is a valid\n", ++ "# comment leader exceeds this length is dependent on the value of\n", ++ "# 'UseArchiveCommentLeader' set in this file. 'unlimited' is a valid\n", + "# setting for this value. Defaults to 20 bytes.\n", + "#\n", + "# For example:\n", + "#\n", + "# MaxCommentLeaderLength=20\n", + "\n", +- "# Set `UseArchiveCommentLeader' to `yes' to cause CVS to fall back on\n", ++ "# Set 'UseArchiveCommentLeader' to 'yes' to cause CVS to fall back on\n", + "# the comment leader set in the RCS archive file, if any, when the\n", +- "# automagically determined comment leader exceeds `MaxCommentLeaderLength'\n", +- "# bytes. If `UseArchiveCommentLeader' is not set and a comment leader\n", +- "# greater than `MaxCommentLeaderLength' is calculated, the Log keyword\n", +- "# being examined will not be expanded. Defaults to `no'.\n", ++ "# automagically determined comment leader exceeds 'MaxCommentLeaderLength'\n", ++ "# bytes. If 'UseArchiveCommentLeader' is not set and a comment leader\n", ++ "# greater than 'MaxCommentLeaderLength' is calculated, the Log keyword\n", ++ "# being examined will not be expanded. Defaults to 'no'.\n", + "#\n", + "# For example:\n", + "#\n", +@@ -816,7 +826,7 @@ + } + + if (restore_cwd (&cwd)) +- error (1, errno, "Failed to restore current directory, `%s'.", ++ error (1, errno, "Failed to restore current directory, '%s'.", + cwd.name); + free_cwd (&cwd); + +@@ -857,7 +867,7 @@ + there is an error, print a message and return 1 (FIXME: probably + not a very clean convention). On success, return 0. */ + static int +-checkout_file (char *file, char *temp) ++checkout_file (const char *file, char *temp) + { + char *rcs; + RCSNode *rcsnode; +@@ -878,7 +888,7 @@ + { + /* Probably not necessary (?); RCS_parsercsfile already printed a + message. */ +- error (0, 0, "Failed to parse `%s'.", rcs); ++ error (0, 0, "Failed to parse '%s'.", rcs); + free (rcs); + return 1; + } +@@ -962,20 +972,22 @@ + key.dptr = vp; + while (*vp && !isspace ((unsigned char) *vp)) + vp++; +- key.dsize = vp - key.dptr; ++ key.dsize = vp - (char *)key.dptr; + *vp++ = '\0'; /* NULL terminate the key */ + while (*vp && isspace ((unsigned char) *vp)) + vp++; /* skip whitespace to value */ + if (*vp == '\0') + { +- error (0, 0, "warning: NULL value for key `%s'", key.dptr); ++ error (0, 0, "warning: NULL value for key '%s'", ++ (char *)key.dptr); + continue; + } + val.dptr = vp; + val.dsize = strlen (vp); + if (dbm_store (db, key, val, DBM_INSERT) == 1) + { +- error (0, 0, "duplicate key found for `%s'", key.dptr); ++ error (0, 0, "duplicate key found for '%s'", ++ (char *)key.dptr); + err++; + } + } +@@ -1097,7 +1109,7 @@ + #endif /* !MY_NDBM */ + + static void +-rename_rcsfile (char *temp, char *real) ++rename_rcsfile (const char *temp, const char *real) + { + char *bak; + struct stat statbuf; +@@ -1175,6 +1187,9 @@ + which needs to be created. */ + mkdir_if_needed (current_parsed_root->directory); + ++ if (noexec) ++ return (0); ++ + adm = Xasprintf ("%s/%s", current_parsed_root->directory, CVSROOTADM); + mkdir_if_needed (adm); + +@@ -1237,8 +1252,8 @@ + } + } + +- /* Turn on history logging by default. The user can remove the file +- to disable it. */ ++ /* Turn on history logging of write operations by default. ++ The user can remove the file to disable it. */ + strcpy (info, adm); + strcat (info, "/"); + strcat (info, CVSROOTADM_HISTORY); +@@ -1249,11 +1264,6 @@ + fp = xfopen (info, "w"); + if (fclose (fp) < 0) + error (1, errno, "cannot close %s", info); +- +- /* Make the new history file world-writeable, since every CVS +- user will need to be able to write to it. We use chmod() +- because xchmod() is too shy. */ +- chmod (info, 0666); + } + + /* Make an empty val-tags file to prevent problems creating it later. */ +@@ -1267,11 +1277,6 @@ + fp = xfopen (info, "w"); + if (fclose (fp) < 0) + error (1, errno, "cannot close %s", info); +- +- /* Make the new val-tags file world-writeable, since every CVS +- user will need to be able to write to it. We use chmod() +- because xchmod() is too shy. */ +- chmod (info, 0666); + } + + free (info); +--- cvs-1.12.13+real.orig/src/modules.c ++++ cvs-1.12.13+real/src/modules.c +@@ -450,7 +450,7 @@ + case '?': + error (0, 0, + "modules file has invalid option for key %s value %s", +- key.dptr, value); ++ (char *)key.dptr, value); + err++; + goto do_module_return; + } +--- cvs-1.12.13+real.orig/src/parseinfo.c ++++ cvs-1.12.13+real/src/parseinfo.c +@@ -230,7 +230,7 @@ + return true; + } + +- /* Record the factor character (kilo, mega, giga, tera). */ ++ /* Record the factor character (kibi, mebi, gibi, tebi). */ + if (!isdigit (p[strlen(p) - 1])) + { + switch (p[strlen(p) - 1]) +@@ -241,16 +241,16 @@ + factor = xtimes (factor, 1024); + case 'M': + factor = xtimes (factor, 1024); +- case 'k': ++ case 'K': + factor = xtimes (factor, 1024); + break; + default: + error (0, 0, + "%s: Unknown %s factor: `%c'", +- infopath, option, p[strlen(p)]); ++ infopath, option, p[strlen(p) - 1]); + return false; + } +- TRACE (TRACE_DATA, "readSizeT(): Found factor %u for %s", ++ TRACE (TRACE_DATA, "readSizeT(): Found factor %zu for %s", + factor, option); + } + +@@ -274,9 +274,9 @@ + /* Don't return an error, just max out. */ + num = SIZE_MAX; + +- TRACE (TRACE_DATA, "readSizeT(): read number %u for %s", num, option); ++ TRACE (TRACE_DATA, "readSizeT(): read number %zu for %s", num, option); + *val = xtimes (strtoul (p, NULL, 10), factor); +- TRACE (TRACE_DATA, "readSizeT(): returnning %u for %s", *val, option); ++ TRACE (TRACE_DATA, "readSizeT(): returnning %zu for %s", *val, option); + return true; + } + +@@ -298,7 +298,7 @@ + new->MaxCompressionLevel = 9; + #endif /* SERVER_SUPPORT */ + #ifdef PROXY_SUPPORT +- new->MaxProxyBufferSize = (size_t)(8 * 1024 * 1024); /* 8 megabytes, ++ new->MaxProxyBufferSize = (size_t)(8 * 1024 * 1024); /* 8 mebibytes, + * by default. + */ + #endif /* PROXY_SUPPORT */ +@@ -392,6 +392,9 @@ + */ + bool processing = true; + bool processed = true; ++#ifdef SERVER_SUPPORT ++ size_t dummy_sizet; ++#endif + + TRACE (TRACE_FUNCTION, "parse_config (%s)", cvsroot); + +@@ -613,18 +616,23 @@ + } + else if (strcmp (line, "LogHistory") == 0) + { +- if (strcmp (p, "all") != 0) +- { +- static bool gotone = false; +- if (gotone) +- error (0, 0, "\ ++ static char *prevpath = NULL; ++ static unsigned int prevln; ++ ++ if (prevpath != NULL) { ++ error (0, 0, "\ + %s [%u]: warning: duplicate LogHistory entry found.", +- infopath, ln); +- else +- gotone = true; +- free (retval->logHistory); +- retval->logHistory = xstrdup (p); ++ infopath, ln); ++ error (0, 0, "\ ++%s [%u]: notice: this was the first definition.", ++ prevpath, prevln); ++ } else { ++ prevln = ln; ++ prevpath = xstrdup(infopath); + } ++ free(retval->logHistory); ++ retval->logHistory = xstrdup(strcmp(p, "all") ? p : ++ ALL_HISTORY_REC_TYPES); + } + else if (strcmp (line, "RereadLogAfterVerify") == 0) + { +@@ -689,13 +697,44 @@ + readBool (infopath, "UseArchiveCommentLeader", p, + &retval->UseArchiveCommentLeader); + #ifdef SERVER_SUPPORT +- else if (!strcmp (line, "MinCompressionLevel")) +- readSizeT (infopath, "MinCompressionLevel", p, +- &retval->MinCompressionLevel); +- else if (!strcmp (line, "MaxCompressionLevel")) +- readSizeT (infopath, "MaxCompressionLevel", p, +- &retval->MaxCompressionLevel); ++ else if (!strcmp (line, "MinCompressionLevel")) { ++ readSizeT (infopath, "MinCompressionLevel", p, &dummy_sizet); ++ retval->MinCompressionLevel = dummy_sizet; ++ } ++ else if (!strcmp (line, "MaxCompressionLevel")) { ++ readSizeT (infopath, "MaxCompressionLevel", p, &dummy_sizet); ++ retval->MaxCompressionLevel = dummy_sizet; ++ } + #endif /* SERVER_SUPPORT */ ++ else if (!strcmp (line, "tag")) { ++ char *pp; ++ ++ pp = Xasprintf("%s=Id", p); ++ RCS_setlocalid (infopath, ln, &retval->keywords, pp); ++ free(pp); ++ ++#if !defined(LOCK_COMPATIBILITY) || !defined(SUPPORT_OLD_INFO_FMT_STRINGS) ++ error (0, 0, "%s: found keyword '%s' in repository", ++ infopath, line); ++ error (readonlyfs ? 0 : 1, 0, readonlyfs ++ ? "Danger: Granting read access to incompatible repository!" ++ : "Do not try to access a cvs 1.11 repository!"); ++#endif ++ } ++#if !defined(LOCK_COMPATIBILITY) || !defined(SUPPORT_OLD_INFO_FMT_STRINGS) ++ else if ((!strcmp (line, "umask")) ++ || (!strcmp (line, "DisableXProg")) || (!strcmp (line, "dlimit")) ++ || (!strcmp (line, "forceReadOnlyFS"))) { ++ /* We are dealing with keywords removed between cvs 1.11.1p1 ++ and cvs 1.12.10; odds are we are not being able to handle ++ access or concurrent access with 1.11 cvs correctly */ ++ error (0, 0, "%s: found keyword '%s' in repository", ++ infopath, line); ++ error (readonlyfs ? 0 : 1, 0, readonlyfs ++ ? "Danger: Granting read access to incompatible repository!" ++ : "Do not try to access a cvs 1.11 repository!"); ++ } ++#endif + else + /* We may be dealing with a keyword which was added in a + subsequent version of CVS. In that case it is a good idea +--- cvs-1.12.13+real.orig/src/parseinfo.h ++++ cvs-1.12.13+real/src/parseinfo.h +@@ -1,3 +1,5 @@ ++/* $MirOS: src/gnu/usr.bin/cvs/src/parseinfo.h,v 1.4 2010/09/19 19:43:07 tg Exp $ */ ++ + /* + * Copyright (c) 2004 Derek Price, Ximbiot <http://ximbiot.com>, + * and the Free Software Foundation +@@ -53,8 +55,8 @@ + size_t MaxProxyBufferSize; + #endif /* PROXY_SUPPORT */ + #ifdef SERVER_SUPPORT +- size_t MinCompressionLevel; +- size_t MaxCompressionLevel; ++ unsigned MinCompressionLevel; ++ unsigned MaxCompressionLevel; + #endif /* SERVER_SUPPORT */ + #ifdef PRESERVE_PERMISSIONS_SUPPORT + bool preserve_perms; +--- cvs-1.12.13+real.orig/src/patch.c ++++ cvs-1.12.13+real/src/patch.c +@@ -46,13 +46,13 @@ + + static const char *const patch_usage[] = + { +- "Usage: %s %s [-flR] [-c|-u] [-s|-t] [-V %%d] [-k kopt]\n", ++ "Usage: %s %s [-flR] [-c|-u[p]] [-s|-t] [-V %%d] [-k kopt]\n", + " -r rev|-D date [-r rev2 | -D date2] modules...\n", + "\t-f\tForce a head revision match if tag/date not found.\n", + "\t-l\tLocal directory only, not recursive\n", + "\t-R\tProcess directories recursively.\n", + "\t-c\tContext diffs (default)\n", +- "\t-u\tUnidiff format.\n", ++ "\t-u\tUnidiff format (-p works the same as in diff).\n", + "\t-s\tShort patch - one liner per file.\n", + "\t-t\tTop two diffs - last change made to the file.\n", + "\t-V vers\tUse RCS Version \"vers\" for keyword expansion.\n", +@@ -78,7 +78,7 @@ + usage (patch_usage); + + optind = 0; +- while ((c = getopt (argc, argv, "+V:k:cuftsQqlRD:r:")) != -1) ++ while ((c = getopt (argc, argv, "+V:k:cupftsQqlRD:r:")) != -1) + { + switch (c) + { +@@ -149,10 +149,13 @@ + "the -V option is obsolete and should not be used"); + break; + case 'u': +- unidiff = 1; /* Unidiff */ ++ unidiff |= 1; /* Unidiff */ + break; + case 'c': /* Context diff */ +- unidiff = 0; ++ unidiff &= ~1; ++ break; ++ case 'p': ++ unidiff |= 2; /* Unidiff context */ + break; + case '?': + default: +@@ -167,6 +170,8 @@ + if (argc < 1) + usage (patch_usage); + ++ if (!(unidiff & 1)) ++ unidiff = 0; + if (toptwo_diffs && patch_short) + error (1, 0, "-t and -s options are mutually exclusive"); + if (toptwo_diffs && (date1 != NULL || date2 != NULL || +@@ -202,6 +207,8 @@ + send_arg("-s"); + if (unidiff) + send_arg("-u"); ++ if (unidiff & 2) ++ send_arg("-p"); + + if (rev1) + option_with_arg ("-r", rev1); +@@ -270,6 +277,7 @@ + int which; + char *repository; + char *where; ++ char *cp; + + TRACE ( TRACE_FUNCTION, "patch_proc ( %s, %s, %s, %d, %d, %s, %s )", + xwhere ? xwhere : "(null)", +@@ -292,7 +300,6 @@ + /* if mfile isn't null, we need to set up to do only part of the module */ + if (mfile != NULL) + { +- char *cp; + char *path; + + /* if the portion of the module is a path, put the dir part on repos */ +@@ -342,14 +349,30 @@ + + if (rev1 != NULL && !rev1_validated) + { +- tag_check_valid (rev1, argc - 1, argv + 1, local_specified, 0, +- repository, false); ++ if ((cp = strchr(rev1, ':')) != NULL) ++ { ++ *cp++ = '\0'; ++ date1 = Make_Date (cp); ++ if (*rev1 == '\0') ++ rev1 = NULL; ++ } ++ if (rev1) ++ tag_check_valid (rev1, argc - 1, argv + 1, local_specified, 0, ++ repository, false); + rev1_validated = 1; + } + if (rev2 != NULL && !rev2_validated) + { +- tag_check_valid (rev2, argc - 1, argv + 1, local_specified, 0, +- repository, false); ++ if ((cp = strchr(rev2, ':')) != NULL) ++ { ++ *cp++ = '\0'; ++ date2 = Make_Date (cp); ++ if (*rev2 == '\0') ++ rev2 = NULL; ++ } ++ if (rev2) ++ tag_check_valid (rev2, argc - 1, argv + 1, local_specified, 0, ++ repository, false); + rev2_validated = 1; + } + +@@ -571,6 +594,7 @@ + + if (unidiff) run_add_arg_p (&dargc, &darg_allocated, &dargv, "-u"); + else run_add_arg_p (&dargc, &darg_allocated, &dargv, "-c"); ++ if (unidiff & 2) run_add_arg_p (&dargc, &darg_allocated, &dargv, "-p"); + switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, dargc, dargv, + tmpfile3)) + { +@@ -671,7 +695,10 @@ + program. */ + if (unidiff) + { +- cvs_output ("diff -u ", 0); ++ if (unidiff & 2) ++ cvs_output ("diff -up ", 0); ++ else ++ cvs_output ("diff -u ", 0); + cvs_output (file1, 0); + cvs_output (" ", 1); + cvs_output (file2, 0); +--- cvs-1.12.13+real.orig/src/rcs.c ++++ cvs-1.12.13+real/src/rcs.c +@@ -103,6 +103,7 @@ + static char *truncate_revnum_in_place (char *); + static char *truncate_revnum (const char *); + static char *printable_date (const char *); ++static char *mdoc_date (const char *); + static char *escape_keyword_value (const char *, int *); + static void expand_keywords (RCSNode *, RCSVers *, const char *, + const char *, size_t, enum kflag, char *, +@@ -2166,6 +2167,8 @@ + + if (! RCS_nodeisbranch (rcs, tag)) + { ++ if (! strcmp (date, "BASE")) ++ return RCS_gettag (rcs, tag, force_tag_match, simple_tag); + /* We can't get a particular date if the tag is not a + branch. */ + return NULL; +@@ -2177,6 +2180,15 @@ + else + branch = xstrdup (tag); + ++ if (! strcmp (date, "BASE")) ++ { ++ /* Cut off the branch suffix and return. */ ++ rev = strrchr (branch, '.'); ++ if (rev) ++ *rev = '\0'; ++ return branch; ++ } ++ + /* Fetch the revision of branch as of date. */ + rev = RCS_getdatebranch (rcs, date, branch); + free (branch); +@@ -2470,7 +2482,7 @@ + check_rev = xrev; + + local_branch_num = getenv("CVS_LOCAL_BRANCH_NUM"); +- if (local_branch_num) ++ if (local_branch_num && *local_branch_num) + { + rev_num = atoi(local_branch_num); + if (rev_num < 2) +@@ -3120,6 +3132,7 @@ + struct timespec revdate; + Node *p; + RCSVers *vers; ++ int y; + + /* make sure we have something to look at... */ + assert (rcs != NULL); +@@ -3134,7 +3147,7 @@ + vers = p->data; + + /* split up the date */ +- if (sscanf (vers->date, SDATEFORM, &xtm.tm_year, &xtm.tm_mon, ++ if (sscanf (vers->date, SDATEFORM, &y, &xtm.tm_mon, + &xtm.tm_mday, &xtm.tm_hour, &xtm.tm_min, &xtm.tm_sec) != 6) + error (1, 0, "%s: invalid date for revision %s (%s)", rcs->print_path, + rev, vers->date); +@@ -3144,15 +3157,14 @@ + 2000+, RCS files contain all four digits and we subtract 1900, + because the tm_year field should contain years since 1900. */ + +- if (xtm.tm_year >= 100 && xtm.tm_year < 2000) ++ if (y >= 100 && y < 2000) + error (0, 0, "%s: non-standard date format for revision %s (%s)", + rcs->print_path, rev, vers->date); +- if (xtm.tm_year >= 1900) +- xtm.tm_year -= 1900; ++ xtm.tm_year = y - ((y >= 1900) ? 1900 : 0); + + /* put the date in a form getdate can grok */ +- tdate = Xasprintf ("%d-%d-%d %d:%d:%d -0000", +- xtm.tm_year + 1900, xtm.tm_mon, xtm.tm_mday, ++ tdate = Xasprintf ("%ld-%d-%d %d:%d:%d -0000", ++ (long)xtm.tm_year + 1900, xtm.tm_mon, xtm.tm_mday, + xtm.tm_hour, xtm.tm_min, xtm.tm_sec); + + /* Turn it into seconds since the epoch. +@@ -3173,7 +3185,7 @@ + /* Put an appropriate string into `date', if we were given one. */ + ftm = gmtime (&revdate.tv_sec); + (void) sprintf (date, DATEFORM, +- ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), ++ (long)ftm->tm_year + (ftm->tm_year < 100 ? 0L : 1900L), + ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, + ftm->tm_min, ftm->tm_sec); + } +@@ -3475,6 +3487,7 @@ + KEYWORD_REVISION, + KEYWORD_SOURCE, + KEYWORD_STATE, ++ KEYWORD_MDOCDATE, + KEYWORD_LOCALID + }; + struct rcs_keyword +@@ -3511,6 +3524,7 @@ + KEYWORD_INIT (new, KEYWORD_REVISION, "Revision"); + KEYWORD_INIT (new, KEYWORD_SOURCE, "Source"); + KEYWORD_INIT (new, KEYWORD_STATE, "State"); ++ KEYWORD_INIT (new, KEYWORD_MDOCDATE, "Mdocdate"); + + return new; + } +@@ -3544,6 +3558,30 @@ + + + ++/* Convert an RCS date string into an mdoc string. This is like ++ the RCS date2str function, but for manual pages. */ ++static char * ++mdoc_date (const char *rcs_date) ++{ ++ int year, mon, mday, hour, min, sec; ++ char buf[100]; ++ const char *months[] = { "January", "February", "March", "April", ++ "May", "June", "July", "August", ++ "September", "October", "November", "December", ++ "corrupt" }; ++ ++ (void) sscanf (rcs_date, SDATEFORM, &year, &mon, &mday, &hour, &min, ++ &sec); ++ if (mon < 1 || mon > 12) ++ mon = 13; ++ if (year < 1900) ++ year += 1900; ++ sprintf (buf, "%s %d %04d", months[mon - 1], mday, year); ++ return xstrdup (buf); ++} ++ ++ ++ + /* Escape the characters in a string so that it can be included in an + RCS value. */ + static char * +@@ -3680,13 +3718,13 @@ + srch_len -= (srch_next + 1) - srch; + srch = srch_next + 1; + +- /* Look for the first non alphabetic character after the '$'. */ ++ /* Look for the first non alphanumeric character after the '$'. */ + send = srch + srch_len; + for (s = srch; s < send; s++) +- if (! isalpha ((unsigned char) *s)) ++ if (! isalnum ((unsigned char) *s)) + break; + +- /* If the first non alphabetic character is not '$' or ':', ++ /* If the first non alphanumeric character is not '$' or ':', + then this is not an RCS keyword. */ + if (s == send || (*s != '$' && *s != ':')) + continue; +@@ -3741,6 +3779,11 @@ + free_value = 1; + break; + ++ case KEYWORD_MDOCDATE: ++ value = mdoc_date (ver->date); ++ free_value = 1; ++ break; ++ + case KEYWORD_CVSHEADER: + case KEYWORD_HEADER: + case KEYWORD_ID: +@@ -4177,6 +4220,9 @@ + : (sout != RUN_TTY ? sout + : "(stdout)")))); + ++ if (rev && *rev == '-') ++ ++rev; ++ + assert (rev == NULL || isdigit ((unsigned char) *rev)); + + if (noexec && !server_active && workfile != NULL) +@@ -5081,7 +5127,7 @@ + (void) time (&modtime); + ftm = gmtime (&modtime); + delta->date = Xasprintf (DATEFORM, +- ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), ++ (long)ftm->tm_year + (ftm->tm_year < 100 ? 0L : 1900L), + ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, + ftm->tm_min, ftm->tm_sec); + if (flags & RCS_FLAGS_DEAD) +@@ -7235,6 +7281,7 @@ + /* Walk the deltas in RCS to get to revision VERSION. + + If OP is RCS_ANNOTATE, then write annotations using cvs_output. ++ If OP is RCS_ANNOTATE_BACKWARDS, do the same backwards. + + If OP is RCS_FETCH, then put the contents of VERSION into a + newly-malloc'd array and put a pointer to it in *TEXT. Each line +@@ -7263,6 +7310,7 @@ + RCSVers *vers; + RCSVers *prev_vers; + RCSVers *trunk_vers; ++ RCSVers *top_vers; + char *next; + int ishead, isnext, isversion, onbranch; + Node *node; +@@ -7285,6 +7333,7 @@ + vers = NULL; + prev_vers = NULL; + trunk_vers = NULL; ++ top_vers = NULL; + next = NULL; + onbranch = 0; + foundhead = 0; +@@ -7332,12 +7381,28 @@ + vers = node->data; + next = vers->next; + ++ /* The top version is either HEAD or ++ the last version on the branch. */ ++ if (top_vers == NULL || ++ (onbranch && (op == RCS_ANNOTATE_BACKWARDS))) ++ top_vers = vers; ++ + /* Compare key and trunkversion now, because key points to + storage controlled by rcsbuf_getkey. */ + if (STREQ (branchversion, key)) + isversion = 1; + else + isversion = 0; ++ ++ /* If we are going back and up a branch, and this is ++ the version we should start annotating, we need to ++ clear out all accumulated annotations. */ ++ if ((op == RCS_ANNOTATE_BACKWARDS) && onbranch && STREQ (version, key)) { ++ unsigned int ln; ++ ++ for (ln = 0; ln < curlines.nlines; ++ln) ++ curlines.vector[ln]->vers = NULL; ++ } + } + + while (1) +@@ -7365,17 +7430,27 @@ + rcsbuf_valpolish (rcsbuf, value, 0, &vallen); + if (ishead) + { +- if (! linevector_add (&curlines, value, vallen, NULL, 0)) ++ if (! linevector_add (&curlines, value, vallen, ++ (op == RCS_ANNOTATE_BACKWARDS) ? vers : NULL, 0)) + error (1, 0, "invalid rcs file %s", rcs->print_path); + + ishead = 0; + } + else if (isnext) + { ++ RCSVers *addv, *delv; ++ ++ if (op == RCS_ANNOTATE_BACKWARDS) { ++ addv = onbranch ? NULL : prev_vers; ++ delv = onbranch ? vers : NULL; ++ } else { ++ addv = onbranch ? vers : NULL; ++ delv = onbranch ? NULL : prev_vers; ++ } ++ + if (! apply_rcs_changes (&curlines, value, vallen, + rcs->path, +- onbranch ? vers : NULL, +- onbranch ? NULL : prev_vers)) ++ addv, delv)) + error (1, 0, "invalid change text in %s", rcs->print_path); + } + break; +@@ -7384,6 +7459,14 @@ + + if (isversion) + { ++ /* If we're going backwards and not up a branch, and we ++ reached the version to start at, we're done. */ ++ if ((op == RCS_ANNOTATE_BACKWARDS) && !onbranch && STREQ (version, key)) { ++ foundhead = 1; ++ linevector_copy (&headlines, &curlines); ++ break; ++ } ++ + /* This is either the version we want, or it is the + branchpoint to the version we want. */ + if (STREQ (branchversion, version)) +@@ -7391,7 +7474,9 @@ + /* This is the version we want. */ + linevector_copy (&headlines, &curlines); + foundhead = 1; +- if (onbranch) ++ /* If we are annotating backwards, we have to ++ continue tracking when we're tracking a branch. */ ++ if (onbranch && !(op == RCS_ANNOTATE_BACKWARDS)) + { + /* We have found this version by tracking up a + branch. Restore back to the lines we saved +@@ -7480,6 +7565,7 @@ + switch (op) + { + case RCS_ANNOTATE: ++ case RCS_ANNOTATE_BACKWARDS: + { + unsigned int ln; + +--- cvs-1.12.13+real.orig/src/rcs.h ++++ cvs-1.12.13+real/src/rcs.h +@@ -1,3 +1,5 @@ ++/* $MirOS: src/gnu/usr.bin/cvs/src/rcs.h,v 1.5 2010/09/19 19:43:09 tg Exp $ */ ++ + /* + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. + * +@@ -33,7 +35,7 @@ + CVS) will put this into RCS files. Considered obsolete. */ + #define RCSDEAD "dead" + +-#define DATEFORM "%02d.%02d.%02d.%02d.%02d.%02d" ++#define DATEFORM "%02ld.%02d.%02d.%02d.%02d.%02d" + #define SDATEFORM "%d.%d.%d.%d.%d.%d" + + /* +@@ -189,7 +191,7 @@ + struct rcsbuffer; + + /* What RCS_deltas is supposed to do. */ +-enum rcs_delta_op {RCS_ANNOTATE, RCS_FETCH}; ++enum rcs_delta_op {RCS_ANNOTATE, RCS_ANNOTATE_BACKWARDS, RCS_FETCH}; + + /* + * exported interfaces +--- cvs-1.12.13+real.orig/src/rcscmds.c ++++ cvs-1.12.13+real/src/rcscmds.c +@@ -1,5 +1,6 @@ + /* + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. ++ * Copyright (c) 2021 mirabilos <m@mirbsd.org> + * + * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>, + * and others. +@@ -92,7 +93,10 @@ + static void + call_diff_add_arg (const char *s) + { +- TRACE (TRACE_DATA, "call_diff_add_arg (%s)", s); ++ if (s) ++ TRACE (TRACE_DATA, "call_diff_add_arg (%s)", s); ++ else ++ TRACE (TRACE_DATA, "call_diff_add_arg NULL"); + run_add_arg_p (&call_diff_argc, &call_diff_arg_allocated, &call_diff_argv, + s); + } +--- cvs-1.12.13+real.orig/src/root.c ++++ cvs-1.12.13+real/src/root.c +@@ -1,4 +1,7 @@ + /* ++ * Copyright © 2017 ++ * mirabilos <m@mirbsd.org> ++ * + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. + * + * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>, +@@ -265,6 +268,7 @@ + directories. Then we can check against them when a remote user + hands us a CVSROOT directory. */ + static List *root_allow; ++static List *root_allow_regexp; + + static void + delconfig (Node *n) +@@ -288,15 +292,65 @@ + } + + void ++root_allow_regexp_add (const char *arg, const char *configPath) ++{ ++ Node *n; ++ ++ if (!root_allow_regexp) root_allow_regexp = getlist(); ++ n = getnode(); ++ n->key = xstrdup (arg); ++ ++ /* This is a regexp, not the final cvsroot path - we cannot attach ++ it a config. So we attach configPath and we'll root_allow_add() ++ the actual, matching root in root_allow_compare_regexp() */ ++ n->data = (void*)configPath; ++ ++ addnode (root_allow_regexp, n); ++} ++ ++void + root_allow_free (void) + { + dellist (&root_allow); ++ dellist (&root_allow_regexp); ++} ++ ++int ++root_allow_used (void) ++{ ++ return root_allow || root_allow_regexp; ++} ++ ++/* walklist() callback for determining if 'root_to_check' matches ++ n->key (a regexp). If yes, 'root_to_check' will be added as if ++ directly specified through --allow-root. ++ */ ++static int ++root_allow_compare_regexp (Node *n, void *root_to_check) ++{ ++ int status; ++ regex_t re; ++ ++ if (regcomp(&re, n->key, ++ REG_EXTENDED|REG_NOSUB) != 0) ++ { ++ return 0; /* report error? */ ++ } ++ status = regexec(&re, root_to_check, (size_t) 0, NULL, 0); ++ regfree(&re); ++ if (status == 0) ++ { ++ /* n->data contains gConfigPath */ ++ root_allow_add (root_to_check, n->data); ++ return 1; ++ } ++ return 0; + } + + bool + root_allow_ok (const char *arg) + { +- if (!root_allow) ++ if (!root_allow_used()) + { + /* Probably someone upgraded from CVS before 1.9.10 to 1.9.10 + or later without reading the documentation about +@@ -308,12 +362,18 @@ + back "error" rather than waiting for the next request which + expects responses. */ + printf ("\ +-error 0 Server configuration missing --allow-root in inetd.conf\n"); ++error 0 Server configuration missing --allow-root or --allow-root-regexp in inetd.conf\n"); + exit (EXIT_FAILURE); + } + ++ /* Look for 'arg' in the list of full-path allowed roots */ + if (findnode (root_allow, arg)) + return true; ++ ++ /* Match 'arg' against the list of allowed roots regexps */ ++ if (walklist (root_allow_regexp, root_allow_compare_regexp, (void*)arg)) ++ return true; ++ + return false; + } + +@@ -436,6 +496,9 @@ + } + + ++#if defined(CLIENT_SUPPORT) || defined (SERVER_SUPPORT) ++static char *validate_hostname(const char *) __attribute__((__malloc__)); ++#endif /* defined(CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */ + + /* + * Parse a CVSROOT string to allocate and return a new cvsroot_t structure. +@@ -535,6 +598,12 @@ + method = ""; + #endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */ + ++ if (NULL == method) ++ { ++ error (0, 0, "Missing method in CVSROOT."); ++ goto error_exit; ++ } ++ + /* Now we have an access method -- see if it's valid. */ + + if (!strcasecmp (method, "local")) +@@ -547,6 +616,16 @@ + newroot->method = gserver_method; + else if (!strcasecmp (method, "server")) + newroot->method = server_method; ++ else if (strncmp (method, "ext=", 4) == 0) ++ { ++ newroot->cvs_rsh = xstrdup(method + 4); ++ newroot->method = ext_method; ++ } ++ else if (!strcasecmp (method, "extssh")) ++ { ++ newroot->cvs_rsh = xstrdup("ssh"); ++ newroot->method = extssh_method; ++ } + else if (!strcasecmp (method, "ext")) + newroot->method = ext_method; + else if (!strcasecmp (method, "fork")) +@@ -573,37 +652,40 @@ + TRACE (TRACE_DATA, "CVSROOT option=`%s' value=`%s'", p, q); + if (!strcasecmp (p, "proxy")) + { +- newroot->proxy_hostname = xstrdup (q); ++ if (!(newroot->proxy_hostname = validate_hostname(q))) { ++ error(0, 0, "Invalid proxy hostname: %s", q); ++ goto error_exit; ++ } + } + else if (!strcasecmp (p, "proxyport")) + { + char *r = q; +- if (*r == '-') r++; +- while (*r) +- { +- if (!isdigit(*r++)) +- { ++ ++ do { ++ if (!isdigit(*r)) { ++ proxy_port_error: + error (0, 0, + "CVSROOT may only specify a positive, non-zero, integer proxy port (not `%s').", + q); + goto error_exit; + } +- } +- if ((newroot->proxy_port = atoi (q)) <= 0) +- error (0, 0, +-"CVSROOT may only specify a positive, non-zero, integer proxy port (not `%s').", +- q); ++ } while (*++r); ++ if ((newroot->proxy_port = atoi(q)) <= 0 || ++ newroot->proxy_port > 65535) ++ goto proxy_port_error; + } + else if (!strcasecmp (p, "CVS_RSH")) + { + /* override CVS_RSH environment variable */ +- if (newroot->method == ext_method) +- newroot->cvs_rsh = xstrdup (q); ++ if (newroot->method == ext_method ++ || newroot->method == extssh_method) ++ newroot->cvs_rsh = xstrdup (q); + } + else if (!strcasecmp (p, "CVS_SERVER")) + { + /* override CVS_SERVER environment variable */ + if (newroot->method == ext_method ++ || newroot->method == extssh_method + || newroot->method == fork_method) + newroot->cvs_server = xstrdup (q); + } +@@ -635,7 +717,8 @@ + newroot->isremote = (newroot->method != local_method); + + #if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) +- if (readonlyfs && newroot->isremote) ++ if (readonlyfs && newroot->isremote && (newroot->method != ext_method) ++ && (newroot->method != extssh_method) && (newroot->method != fork_method)) + error (1, 0, + "Read-only repository feature unavailable with remote roots (cvsroot = %s)", + cvsroot_copy); +@@ -682,7 +765,22 @@ + /* a blank username is impossible, so leave it NULL in that + * case so we know to use the default username + */ ++ { ++ /* for want of strcspn */ ++ if (/* no at, obviously */ strchr(cvsroot_copy, '@') || ++ /* no colon, interference with CVSROOT/passwd file */ ++ strchr(cvsroot_copy, ':') || ++ /* no linefeeds, interference with pserver protocol */ ++ strchr(cvsroot_copy, '\012')) { ++ error(0, 0, "Bad username \"%s\"", cvsroot_copy); ++ goto error_exit; ++ } ++ /* other limitations include not beginning with a ++ * hyphen-minus but that’s not even a requirement ++ * in POSIX, let alone other operating environments… ++ */ + newroot->username = xstrdup (cvsroot_copy); ++ } + + cvsroot_copy = ++p; + } +@@ -693,24 +791,18 @@ + if ((p = strchr (cvsroot_copy, ':')) != NULL) + { + *p++ = '\0'; +- if (strlen(p)) ++ if (*p) + { ++ char qch; ++ + q = p; +- if (*q == '-') q++; +- while (*q) ++ while ((qch = *q++)) + { +- if (!isdigit(*q++)) +- { +- error (0, 0, +-"CVSROOT may only specify a positive, non-zero, integer port (not `%s').", +- p); +- error (0, 0, +- "Perhaps you entered a relative pathname?"); +- goto error_exit; +- } ++ if (!isdigit(qch)) ++ goto parse_port_error; + } +- if ((newroot->port = atoi (p)) <= 0) +- { ++ if ((newroot->port = atoi(p)) <= 0 || newroot->port > 65535) { ++ parse_port_error: + error (0, 0, + "CVSROOT may only specify a positive, non-zero, integer port (not `%s').", + p); +@@ -720,12 +812,8 @@ + } + } + +- /* copy host */ +- if (*cvsroot_copy != '\0') +- /* blank hostnames are invalid, but for now leave the field NULL +- * and catch the error during the sanity checks later +- */ +- newroot->hostname = xstrdup (cvsroot_copy); ++ /* check and copy host */ ++ newroot->hostname = validate_hostname(cvsroot_copy); + + /* restore the '/' */ + cvsroot_copy = firstslash; +@@ -750,7 +838,9 @@ + #if defined(CLIENT_SUPPORT) || defined (SERVER_SUPPORT) + if (newroot->username && ! newroot->hostname) + { +- error (0, 0, "Missing hostname in CVSROOT."); ++ /* this defangs sanity.sh tests for remote reject, though */ ++ bad_hostname: ++ error (0, 0, "Missing or bad hostname in CVSROOT."); + goto error_exit; + } + +@@ -828,6 +918,7 @@ + case server_method: + case ext_method: + no_port = 1; ++ case extssh_method: + /* no_password already set */ + check_hostname = 1; + break; +@@ -863,16 +954,13 @@ + } + + if (check_hostname && !newroot->hostname) +- { +- error (0, 0, "Didn't specify hostname in CVSROOT."); +- goto error_exit; +- } ++ goto bad_hostname; + + if (no_port && newroot->port) + { + error (0, 0, +-"CVSROOT port specification is only valid for gserver, kserver,"); +- error (0, 0, "and pserver connection methods."); ++"CVSROOT port specification is only valid for extssh,"); ++ error (0, 0, "gserver, kserver and pserver connection methods."); + goto error_exit; + } + #endif /* defined(CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */ +@@ -1052,3 +1140,78 @@ + /* NOTREACHED */ + } + #endif ++ ++#if defined(CLIENT_SUPPORT) || defined (SERVER_SUPPORT) ++#define CLS_INVALID 0 ++#define CLS_INSIDE 1 ++#define CLS_OUTSIDE 2 ++#define CLS_SEPARATOR 4 ++/* EBCDIC safe */ ++#define CLASSIFY(x) classify[(unsigned char)(x)] ++static char * ++validate_hostname(const char *s) ++{ ++ char *buf, *cp; ++ size_t sz; ++ static char classify_initialised = 0, *classify; ++ ++ /* initialise classification table */ ++ if (!classify_initialised) { ++ const char *ccp; ++ ++ classify = xmalloc(256); ++ for (sz = 0; sz < 256; ++sz) ++ CLASSIFY(sz) = CLS_INVALID; ++ for (ccp = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; ++ *ccp; ++ccp) ++ CLASSIFY(*ccp) = CLS_INSIDE | CLS_OUTSIDE; ++ CLASSIFY('-') = CLS_INSIDE; ++ CLASSIFY('.') = CLS_SEPARATOR; ++ classify_initialised = 1; ++ } ++ ++ /* total size limit tolerating a trailing dot */ ++ if ((sz = strlen(s)) > 256) ++ return (NULL); ++ buf = xstrdup(s); ++ ++ /* drop trailing dot */ ++ if ((unsigned char)buf[sz - 1] == (unsigned char)'.') ++ buf[--sz] = '\0'; ++ /* recheck */ ++ if (sz > 255) { ++ err: ++ free(buf); ++ return (NULL); ++ } ++ ++ /* check each label */ ++ cp = buf; ++ loop: ++ /* must begin with [0-9A-Za-z] */ ++ if (!(CLASSIFY(*cp++) & CLS_OUTSIDE)) ++ goto err; ++ sz = 1; ++ /* arbitrary many [0-9A-Za-z-] */ ++ while (CLASSIFY(*cp) & CLS_INSIDE) { ++ ++cp; ++ ++sz; ++ } ++ /* except the last must have been [0-9A-Za-z] again */ ++ if (!(CLASSIFY(cp[-1]) & CLS_OUTSIDE)) ++ goto err; ++ /* maximum label size */ ++ if (sz > 63) ++ goto err; ++ /* next label? */ ++ if (CLASSIFY(*cp) & CLS_SEPARATOR) { ++ ++cp; ++ goto loop; ++ } ++ /* must be end of string now */ ++ if (*cp) ++ goto err; ++ /* it is, everything okay */ ++ return (buf); ++} ++#endif /* defined(CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */ +--- cvs-1.12.13+real.orig/src/root.h ++++ cvs-1.12.13+real/src/root.h +@@ -1,3 +1,5 @@ ++/* $MirOS: src/gnu/usr.bin/cvs/src/root.h,v 1.5 2017/01/08 19:13:05 tg Exp $ */ ++ + /* + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. + * +@@ -22,6 +24,7 @@ + kserver_method, + gserver_method, + ext_method, ++ extssh_method, + fork_method + } CVSmethod; + extern const char method_names[][16]; /* change this in root.c if you change +@@ -62,8 +65,10 @@ + __attribute__ ((__malloc__)); + void Create_Root (const char *dir, const char *rootdir); + void root_allow_add (const char *, const char *configPath); ++void root_allow_regexp_add (const char *, const char *configPath); + void root_allow_free (void); + bool root_allow_ok (const char *); ++int root_allow_used (void); + struct config *get_root_allow_config (const char *arg, const char *configPath); + const char *primary_root_translate (const char *root_in); + const char *primary_root_inverse_translate (const char *root_in); +--- cvs-1.12.13+real.orig/src/rsh-client.c ++++ cvs-1.12.13+real/src/rsh-client.c +@@ -53,11 +53,13 @@ + char *cvs_server = (root->cvs_server != NULL + ? root->cvs_server : getenv ("CVS_SERVER")); + int i = 0; +- /* This needs to fit "rsh", "-b", "-l", "USER", "host", +- "cmd (w/ args)", and NULL. We leave some room to grow. */ +- char *rsh_argv[10]; ++ /* This needs to fit "rsh", "-b", "-l", "USER", "-p", port, ++ "--", "host", "cvs", "-R", "server", and NULL. ++ We leave some room to grow. */ ++ char *rsh_argv[16]; ++ char argvport[16]; + +- if (!cvs_rsh) ++ if (!cvs_rsh || !*cvs_rsh) + /* People sometimes suggest or assume that this should default + to "remsh" on systems like HPUX in which that is the + system-supplied name for the rsh program. However, that +@@ -79,7 +81,7 @@ + if that is what they want (the manual already tells them + that). */ + cvs_rsh = RSH_DFLT; +- if (!cvs_server) ++ if (!cvs_server || !*cvs_server) + cvs_server = "cvs"; + + /* The command line starts out with rsh. */ +@@ -97,8 +99,20 @@ + rsh_argv[i++] = root->username; + } + ++ if (root->method == extssh_method && root->port) ++ { ++ snprintf(argvport, sizeof(argvport), "%d", root->port); ++ rsh_argv[i++] = "-p"; ++ rsh_argv[i++] = argvport; ++ } ++ ++ /* Only non-option arguments from here. (CVE-2017-12836) */ ++ rsh_argv[i++] = "--"; ++ + rsh_argv[i++] = root->hostname; + rsh_argv[i++] = cvs_server; ++ if (readonlyfs) ++ rsh_argv[i++] = "-R"; + rsh_argv[i++] = "server"; + + /* Mark the end of the arg list. */ +@@ -139,9 +153,9 @@ + int tofd, fromfd; + int child_pid; + +- if (!cvs_rsh) ++ if (!cvs_rsh || !*cvs_rsh) + cvs_rsh = RSH_DFLT; +- if (!cvs_server) ++ if (!cvs_server || !*cvs_server) + cvs_server = "cvs"; + + /* Pass the command to rsh as a single string. This shouldn't +@@ -154,10 +168,11 @@ + * on the server machine does not set CVSROOT to something + * containing a colon (or better yet, upgrade the server). + */ +- command = Xasprintf ("%s server", cvs_server); ++ command = Xasprintf ("%s%s server", cvs_server, readonlyfs ? " -R" : ""); + + { +- char *argv[10]; ++ char argvport[16]; ++ char *argv[16]; + char **p = argv; + + *p++ = cvs_rsh; +@@ -171,6 +186,15 @@ + *p++ = root->username; + } + ++ if (root->method == extssh_method && root->port) ++ { ++ snprintf(argvport, sizeof(argvport), "%d", root->port); ++ *p++ = "-p"; ++ *p++ = argvport; ++ } ++ ++ *p++ = "--"; ++ + *p++ = root->hostname; + *p++ = command; + *p++ = NULL; +--- cvs-1.12.13+real.orig/src/sanity.sh ++++ cvs-1.12.13+real/src/sanity.sh +@@ -1,11 +1,17 @@ + #! /bin/sh + : ++# $MirOS: src/gnu/usr.bin/cvs/src/sanity.sh,v 1.21 2021/01/30 02:06:07 tg Exp $ ++#- ++# set DISABLE_ANY_RSH=1 to skip rsh and ssh calls ++# + # sanity.sh -- a growing testsuite for cvs. + # + # The copyright notice said: "Copyright (C) 1992, 1993 Cygnus Support" + # I'm not adding new copyright notices for new years as our recent + # practice has been to include copying terms without copyright notices. + # ++# © 2016, 2017, 2021 mirabilos <m@mirbsd.org> ++# + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2, or (at your option) +@@ -22,7 +28,7 @@ + usage () + { + echo "Usage: `basename $0` --help" +- echo "Usage: `basename $0` [--eklr] [-c CONFIG-FILE] [-f FROM-TEST] \\" ++ echo "Usage: `basename $0` [-eklnpr] [-c CONFIG-FILE] [-f FROM-TEST] \\" + echo " [-h HOSTNAME] [-s CVS-FOR-CVS-SERVER] CVS-TO-TEST \\" + echo " [TESTS-TO-RUN...]" + } +@@ -37,59 +43,74 @@ + { + usage + echo +- echo "-H|--help display this text" ++ echo "-H|--help display this text" + echo "-c CONFIG-FILE" + echo "--config=CONFIG_FILE" +- echo " use an alternate test suite config file (defaults to" +- echo " \`sanity.config.sh' in the same directory as" +- echo " CVS-TO-TEST is found in)" +- echo "-e|--skipfail Treat tests that would otherwise be nonfatally skipped" +- echo " for reasons like missing tools as failures, exiting" +- echo " with an error message. Also treat warnings as" +- echo " failures." ++ echo " use an alternate test suite config file (defaults to" ++ echo " 'sanity.config.sh' in the same directory as" ++ echo " CVS-TO-TEST is found in)" ++ echo "-e|--skipfail Treat tests that would otherwise be nonfatally skipped" ++ echo " for reasons like missing tools as failures, exiting" ++ echo " with an error message. Also treat warnings as" ++ echo " failures." + echo "-f FROM-TEST" + echo "--from-test=FROM-TEST" +- echo " run TESTS-TO-RUN, skipping all tests in the list before" +- echo " FROM-TEST" ++ echo " run TESTS-TO-RUN, skipping all tests in the list before" ++ echo " FROM-TEST" + echo "-h HOSTNAME" + echo "--hostname HOSTNAME" +- echo " Use :ext:HOSTNAME to run remote tests rather than" +- echo " :fork:. Implies --remote and assumes that \$TESTDIR" +- echo " resolves to the same directory on both the client and" +- echo " the server." +- echo "-k|--keep try to keep directories created by individual tests" +- echo " around, exiting after the first test which supports" +- echo " --keep" +- echo "-l|--link-root" +- echo " test CVS using a symlink to a real CVSROOT" +- echo "-n|--noredirect" +- echo " test a secondary/primary CVS server (writeproxy)" +- echo " configuration with the Redirect response disabled" +- echo " (implies --proxy)." +- echo "-p|--proxy test a secondary/primary CVS server (writeproxy)" +- echo " configuration (implies --remote)." +- echo "-r|--remote test client/server, as opposed to local, CVS" ++ echo " Use :ext:HOSTNAME to run remote tests rather than" ++ echo " :fork:. Implies --remote and assumes that \$TESTDIR" ++ echo " resolves to the same directory on both the client and" ++ echo " the server." ++ echo "-k|--keep try to keep directories created by individual tests" ++ echo " around, exiting after the first test which supports" ++ echo " --keep" ++ echo "-l|--link-root test CVS using a symlink to a real CVSROOT" ++ echo "-n|--noredirect test a secondary/primary CVS server (writeproxy)" ++ echo " configuration with the Redirect response disabled" ++ echo " (implies --proxy)." ++ echo "-p|--proxy test a secondary/primary CVS server (writeproxy)" ++ echo " configuration (implies --remote)." ++ echo "-r|--remote test client/server, as opposed to local, CVS" + echo "-s CVS-FOR-CVS-SERVER" + echo "--server=CVS-FOR-CVS-SERVER" +- echo " use CVS-FOR-CVS-SERVER as the path to the CVS SERVER" +- echo " executable to be tested (defaults to CVS-TO-TEST and" +- echo " implies --remote)" +- echo +- echo "CVS-TO-TEST the path to the CVS executable to be tested; used as" +- echo " the path to the CVS client when CVS-FOR-CVS-SERVER is" +- echo " specified" +- echo "TESTS-TO-RUN the names of the tests to run (defaults to all tests)" ++ echo " use CVS-FOR-CVS-SERVER as the path to the CVS SERVER" ++ echo " executable to be tested (defaults to CVS-TO-TEST and" ++ echo " implies --remote)" ++ echo "" ++ echo "CVS-TO-TEST the path to the CVS executable to be tested; used as" ++ echo " the path to the CVS client when CVS-FOR-CVS-SERVER is" ++ echo " specified" ++ echo "TESTS-TO-RUN the names of the tests to run (defaults to all tests)" + exit 2 + } + + checklongoptarg() + { + if test "x$1" != xoptional && test -z "$OPTARG"; then +- echo "option \`--$LONGOPT' requires an argument" >&2 ++ echo "option '--$LONGOPT' requires an argument" >&2 + exit_usage + fi + } + ++do_save_TZ() ++{ ++ saveset_TZ=${TZ+false} ++ save_TZ=$TZ ++ TZ=UTC0; export TZ ++} ++ ++do_restore_TZ() ++{ ++ if $saveset_TZ :; then ++ unset TZ ++ else ++ TZ=$save_TZ ++ export TZ ++ fi ++} ++ + # See TODO list at end of file. + + # required to make this script work properly. +@@ -155,7 +176,7 @@ + checklongoptarg + ;; + h) +- echo "\`--h' is ambiguous. Could mean \`--help' or \`--hostname'" >&2 ++ echo "'--h' is ambiguous. Could mean '--help' or '--hostname'" >&2 + exit_usage + ;; + he|hel|help) +@@ -187,7 +208,7 @@ + OPTARG= + ;; + s) +- echo "\`--s' is ambiguous. Could mean \`--server' or \`--skipfail'" >&2 ++ echo "'--s' is ambiguous. Could mean '--server' or '--skipfail'" >&2 + exit_usage + ;; + se|ser|serv|serve|server) +@@ -312,7 +333,7 @@ + . "$configfile" + else + echo "WARNING: Failed to locate test suite config file" >&2 +- echo " \`$configfile'." >&2 ++ echo " '$configfile'." >&2 + fi + + +@@ -326,7 +347,7 @@ + # Verify that $CVS_RSH $remotehost works. + result=`$CVS_RSH $remotehost 'echo test'` + if test $? != 0 || test "x$result" != "xtest"; then +- echo "\`$CVS_RSH $remotehost' failed." >&2 ++ echo "'$CVS_RSH $remotehost' failed." >&2 + exit 1 + fi + fi +@@ -373,7 +394,7 @@ + fi + if $CVS_RSH $remotehost "${servercvs} --version </dev/null | + grep '^Concurrent.*(.*server)$' >/dev/null 2>&1"; then :; else +- echo "CVS executable \`$remotehost:${servercvs}' does not contain server support." >&2 ++ echo "CVS executable '$remotehost:${servercvs}' does not contain server support." >&2 + exit 1 + fi + else +@@ -388,7 +409,7 @@ + fi + if ${servercvs} --version </dev/null | + grep '^Concurrent.*(.*server)$' >/dev/null 2>&1; then :; else +- echo "CVS executable \`${servercvs}' does not contain server support." >&2 ++ echo "CVS executable '${servercvs}' does not contain server support." >&2 + exit 1 + fi + fi +@@ -399,7 +420,7 @@ + if $remote; then + if ${testcvs} --version </dev/null | + grep '^Concurrent.*(client.*)$' >/dev/null 2>&1; then :; else +- echo "CVS executable \`${testcvs}' does not contain client support." >&2 ++ echo "CVS executable '${testcvs}' does not contain client support." >&2 + exit 1 + fi + fi +@@ -418,7 +439,7 @@ + dokeep() + { + if ${keep}; then +- echo "Keeping ${TESTDIR} for test case \`${what}' and exiting due to --keep" ++ echo "Keeping ${TESTDIR} for test case '${what}' and exiting due to --keep" + exit 0 + fi + } +@@ -436,7 +457,7 @@ + echo '(Note that the test can take an hour or more to run and periodically stops' + echo 'for as long as one minute. Do not assume there is a problem just because' + echo 'nothing seems to happen for a long time. If you cannot live without' +-echo "running status, try the command: \`tail -f check.log' from another window.)" ++echo "running status, try the command: 'tail -f check.log' from another window.)" + + # Regexp to match what the CVS client will call itself in output that it prints. + # FIXME: we don't properly quote this--if the name contains . we'll +@@ -681,6 +702,10 @@ + #! $TESTSHELL + hostname=\$1 + shift ++if test x"\$hostname" = x"--"; then ++ hostname=\$1 ++ shift ++fi + exec \ + $CVS_RSH \ + \$hostname \ +@@ -750,7 +775,7 @@ + fi + fi + if $verbad; then +- echo "The command \`$vercmd' does not support the --version option." ++ echo "The command '$vercmd' does not support the --version option." + fi + # It does not really matter that --version is not supported + return 0 +@@ -796,10 +821,10 @@ + fi + done + if test -n "$TOOL"; then +- echo "Notice: The default version of \`$default_TOOL' is defective." >>$LOGFILE +- echo "using \`$TOOL' and hoping for the best." >>$LOGFILE +- echo "Notice: The default version of \`$default_TOOL' is defective." >&2 +- echo "using \`$TOOL' and hoping for the best." >&2 ++ echo "Notice: The default version of '$default_TOOL' is defective." >>$LOGFILE ++ echo "using '$TOOL' and hoping for the best." >>$LOGFILE ++ echo "Notice: The default version of '$default_TOOL' is defective." >&2 ++ echo "using '$TOOL' and hoping for the best." >&2 + echo $TOOL + else + echo $default_TOOL +@@ -812,7 +837,7 @@ + if $id -u >/dev/null 2>&1 && $id -un >/dev/null 2>&1; then + return 0 + else +- echo "Running these tests requires an \`id' program that understands the" ++ echo "Running these tests requires an 'id' program that understands the" + echo "-u and -n flags. Make sure that such an id (GNU, or many but not" + echo "all vendor-supplied versions) is in your path." + return 1 +@@ -941,8 +966,8 @@ + else + DOTSTAR='\(.\| + \)*' +- echo "Notice: DOTSTAR changed from sane \`.*' value to \`$DOTSTAR\`" +- echo "to workaround GNU expr version 1.10 thru 1.12 bug where \`.'" ++ echo "Notice: DOTSTAR changed from sane '.*' value to '$DOTSTAR'" ++ echo "to workaround GNU expr version 1.10 thru 1.12 bug where '.'" + echo "does not match a newline." + fi + return 0 +@@ -1059,7 +1084,7 @@ + rm -rf $TESTDIR/ls-test + fi + if $ls $TESTDIR/ls-test >/dev/null 2>&1; then +- echo "Notice: \`$ls' is defective." ++ echo "Notice: '$ls' is defective." + echo 'This is a version of ls which does not correctly' + echo 'return false for files that do not exist. Some tests may' + echo 'spuriously pass or fail.' +@@ -1205,11 +1230,16 @@ + # 77. + require_rsh () + { ++ if test x"$DISABLE_ANY_RSH" = x"1"; then ++ skipreason="administratively prohibited" ++ return 77 ++ fi ++ + host=${remotehost-"`hostname`"} + result=`$1 $host 'echo test'` + rc=$? + if test $? != 0 || test "x$result" != "xtest"; then +- skipreason="\`$1 $host' failed rc=$rc result=$result" ++ skipreason="'$1 $host' failed rc=$rc result=$result" + return 77 + fi + +@@ -1301,7 +1331,7 @@ + fail () + { + echo "FAIL: $1" | tee -a ${LOGFILE} +- echo "*** Please see the \`TESTS' and \`check.log' files for more information." >&2 ++ echo "*** Please see the 'TESTS' and 'check.log' files for more information." >&2 + # This way the tester can go and see what remnants were left + exit 1 + } +@@ -1313,7 +1343,7 @@ + if $remote && $LS $TMPDIR/cvs-serv* >/dev/null 2>&1; then + # A true value means ls found files/directories with these names. + # Give the server some time to finish, then retry. +- sleep 1 ++ sleep 2 + if $LS $TMPDIR/cvs-serv* >/dev/null 2>&1; then + warn "$1" "Found cvs-serv* directories in $TMPDIR." + # The above will exit if $skipfail +@@ -1503,6 +1533,9 @@ + # lack \|). + dotest () + { ++ #echo dotest >$TESTDIR/_dotest.fun ++ #pwd >$TESTDIR/_dotest.cwd ++ #printf '%s\n' "$2" >$TESTDIR/_dotest.cmd + rm -f $TESTDIR/dotest.ex? 2>&1 + eval "$2" >$TESTDIR/dotest.tmp 2>&1 + status=$? +@@ -1518,6 +1551,9 @@ + # Like dotest except only 2 args and result must exactly match stdin + dotest_lit () + { ++ #echo dotest_lit >$TESTDIR/_dotest.fun ++ #pwd >$TESTDIR/_dotest.cwd ++ #printf '%s\n' "$2" >$TESTDIR/_dotest.cmd + rm -f $TESTDIR/dotest.ex? 2>&1 + eval "$2" >$TESTDIR/dotest.tmp 2>&1 + status=$? +@@ -1543,6 +1579,9 @@ + # Like dotest except exitstatus should be nonzero. + dotest_fail () + { ++ #echo dotest_fail >$TESTDIR/_dotest.fun ++ #pwd >$TESTDIR/_dotest.cwd ++ #printf '%s\n' "$2" >$TESTDIR/_dotest.cmd + rm -f $TESTDIR/dotest.ex? 2>&1 + eval "$2" >$TESTDIR/dotest.tmp 2>&1 + status=$? +@@ -1558,6 +1597,9 @@ + # Like dotest except output is sorted. + dotest_sort () + { ++ #echo dotest_sort >$TESTDIR/_dotest.fun ++ #pwd >$TESTDIR/_dotest.cwd ++ #printf '%s\n' "$2" >$TESTDIR/_dotest.cmd + rm -f $TESTDIR/dotest.ex? 2>&1 + eval "$2" >$TESTDIR/dotest.tmp1 2>&1 + status=$? +@@ -1574,6 +1616,9 @@ + # Like dotest_fail except output is sorted. + dotest_fail_sort () + { ++ #echo dotest_fail_sort >$TESTDIR/_dotest.fun ++ #pwd >$TESTDIR/_dotest.cwd ++ #printf '%s\n' "$2" >$TESTDIR/_dotest.cmd + rm -f $TESTDIR/dotest.ex? 2>&1 + eval "$2" >$TESTDIR/dotest.tmp1 2>&1 + status=$? +@@ -1622,6 +1667,7 @@ + tests="$tests parseroot parseroot2 parseroot3 files spacefiles" + tests="${tests} commit-readonly commit-add-missing" + tests="${tests} status" ++ tests="${tests} suck" + # Branching, tagging, removing, adding, multiple directories + tests="${tests} rdiff rdiff-short" + tests="${tests} rdiff2 diff diffnl death death2" +@@ -1694,7 +1740,7 @@ + count=`expr $count + 1` + done + if test $count != 1; then +- echo "No such test \`$fromtest'." >&2 ++ echo "No such test '$fromtest'." >&2 + exit 2 + fi + # make sure it is in $tests +@@ -1702,7 +1748,7 @@ + *" $fromtest "*) + ;; + *) +- echo "No such test \`$fromtest'." >&2 ++ echo "No such test '$fromtest'." >&2 + exit 2 + ;; + esac +@@ -2600,6 +2646,25 @@ + ### + dotest init-1 "$testcvs init" + ++# We might need to allow "cvs admin" access and full history. ++mkdir wnt ++cd wnt ++dotest init-1a "$testcvs -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" ++cd CVSROOT ++sed -e 's/^#UserAdminOptions=/UserAdminOptions=/' \ ++ -e '/^LogHistory/d' \ ++ <config >tmpconfig ++mv tmpconfig config ++dotest init-1b "$testcvs -q ci -m allow-cvs-admin" "" \ ++".*/CVSROOT/config,v <-- config ++new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* ++$SPROG commit: Rebuilding administrative file database" ++cd ../.. ++rm -r wnt ++ ++write_secondary_wrapper() { :; } ++CVS_SERVER_secondary_wrapper_orig=$CVS_SERVER ++ + # Now hide the primary root behind a secondary if requested. + if $proxy; then + # Save the primary root. +@@ -2626,6 +2691,7 @@ + if $noredirect; then + # Wrap the CVS server to allow --primary-root to be set by the + # secondary. ++ write_secondary_wrapper() { + cat <<EOF >$TESTDIR/secondary-wrapper + #! $TESTSHELL + CVS_SERVER=$TESTDIR/primary-wrapper +@@ -2633,8 +2699,10 @@ + + # No need to check the PID of the last client since we are testing with + # Redirect disabled. +-proot_arg="--allow-root=$SECONDARY_CVSROOT_DIRNAME" +-exec $CVS_SERVER \$proot_arg "\$@" ++proot_arg="--allow-root=$SECONDARY_CVSROOT_DIRNAME \ ++ --allow-root=$TESTDIR/crerepos \ ++ --allow-root=$PRIMARY_CVSROOT_DIRNAME" ++exec $CVS_SERVER_secondary_wrapper_orig \$proot_arg "\$@" + EOF + cat <<EOF >$TESTDIR/primary-wrapper + #! $TESTSHELL +@@ -2644,7 +2712,8 @@ + fi + exec $CVS_SERVER "\$@" + EOF +- ++ } ++ write_secondary_wrapper + CVS_SERVER_secondary=$TESTDIR/secondary-wrapper + CVS_SERVER=$CVS_SERVER_secondary + +@@ -2685,10 +2754,10 @@ + # were written to. + case "\$cmd" in + add|import) +- # For \`add', we need a recursive update due to quirks in rsync syntax, ++ # For 'add', we need a recursive update due to quirks in rsync syntax, + # but it shouldn't affect efficiency since any new dir should be empty. + # +- # For \`import', a recursive update is necessary since subdirs may have ++ # For 'import', a recursive update is necessary since subdirs may have + # been added underneath the root dir we were passed. + $RSYNC -rglop \\ + $PRIMARY_CVSROOT_DIRNAME/"\$dir" \\ +@@ -2696,7 +2765,7 @@ + ;; + + tag) +- # \`tag' may have changed CVSROOT/val-tags too. ++ # 'tag' may have changed CVSROOT/val-tags too. + $RSYNC -glop \\ + $PRIMARY_CVSROOT_DIRNAME/CVSROOT/val-tags \\ + $SECONDARY_CVSROOT_DIRNAME/CVSROOT +@@ -2726,7 +2795,7 @@ + esac # \$dir + + # Avoid timestamp comparison issues with rsync. +-sleep 1 ++sleep 2 + EOF + chmod a+x $TESTDIR/sync-secondary + +@@ -2781,6 +2850,21 @@ + ### + dotest init-2 "$testcvs init" + ++# We might need to allow "cvs admin" access and full history. ++mkdir wnt ++cd wnt ++dotest init-2a "$testcvs -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" ++cd CVSROOT ++sed -e 's/^#UserAdminOptions=/UserAdminOptions=/' \ ++ -e '/^LogHistory/d' \ ++ <config >tmpconfig ++mv tmpconfig config ++dotest init-2b "$testcvs -q ci -m allow-cvs-admin" "" \ ++".*/CVSROOT/config,v <-- config ++new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* ++$SPROG commit: Rebuilding administrative file database" ++cd ../.. ++rm -r wnt + + + ### +@@ -2804,8 +2888,9 @@ + Concurrent Versions System (CVS) [0-9.]*.* + + Copyright (C) [0-9]* Free Software Foundation, Inc. ++Copyright (c) [0-9]* mirabilos .m.mirbsd.org. + +-Senior active maintainers include Larry Jones, Derek R. Price, ++Senior no longer active maintainers include Larry Jones, Derek R. Price, + and Mark D. Baushke. Please see the AUTHORS and README files from the CVS + distribution kit for a complete list of contributors and copyrights. + +@@ -2822,8 +2907,8 @@ + #Secondary Server: Concurrent Versions System (CVS) [0-9p.]* (.*server)' + if $remote; then + dotest version-2r "${testcvs} version" \ +-'Client: Concurrent Versions System (CVS) [0-9p.]* (client.*) +-Server: Concurrent Versions System (CVS) [0-9p.]* (.*server)' ++'Client: Concurrent Versions System (CVS) [0-9p.]*\(-Mir[^ ]*\)* (client.*) ++Server: Concurrent Versions System (CVS) [0-9p.]*\(-Mir[^ ]*\)* (.*server)' + else + dotest version-2 "${testcvs} version" \ + 'Concurrent Versions System (CVS) [0-9.]*.*' +@@ -2846,7 +2931,7 @@ + dotest basica-0a "$testcvs -q co -l ." + mkdir first-dir + dotest basica-0b "$testcvs add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd .. + rm -r 1 + +@@ -2865,17 +2950,17 @@ + # Remote CVS gives the "cannot open CVS/Entries" error, which is + # clearly a bug, but not a simple one to fix. + dotest basica-1a10 "$testcvs -n add sdir" \ +-"Directory $CVSROOT_DIRNAME/first-dir/sdir added to the repository" \ ++"Directory $CVSROOT_DIRNAME/first-dir/sdir put under version control" \ + "$SPROG add: cannot open CVS/Entries for reading: No such file or directory +-Directory $CVSROOT_DIRNAME/first-dir/sdir added to the repository" ++Directory $CVSROOT_DIRNAME/first-dir/sdir put under version control" + dotest_fail basica-1a11 \ + "test -d $CVSROOT_DIRNAME/first-dir/sdir" + dotest basica-2 "$testcvs add sdir" \ +-"Directory $CVSROOT_DIRNAME/first-dir/sdir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir/sdir put under version control" + cd sdir + mkdir ssdir + dotest basica-3 "$testcvs add ssdir" \ +-"Directory $CVSROOT_DIRNAME/first-dir/sdir/ssdir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir/sdir/ssdir put under version control" + cd ssdir + echo ssfile >ssfile + +@@ -3145,7 +3230,7 @@ + dotest basicb-0d0 "${testcvs} -q co -l ." "" + mkdir first-dir + dotest basicb-0e "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd .. + rm -r 2 + +@@ -3165,8 +3250,8 @@ + # special only when it is directly in $CVSROOT/CVSROOT. + mkdir Emptydir sdir2 + dotest basicb-2 "${testcvs} add Emptydir sdir2" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/Emptydir added to the repository +-Directory ${CVSROOT_DIRNAME}/first-dir/sdir2 added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/Emptydir put under version control ++Directory ${CVSROOT_DIRNAME}/first-dir/sdir2 put under version control" + cd Emptydir + echo sfile1 starts >sfile1 + dotest basicb-2a10 "${testcvs} -n add sfile1" \ +@@ -3288,7 +3373,7 @@ + dotest basicb-14 "${testcvs} -q co -l ." 'U topfile' + mkdir second-dir + dotest basicb-15 "${testcvs} add second-dir" \ +-"Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/second-dir put under version control" + cd second-dir + touch aa + dotest basicb-16 "${testcvs} add aa" \ +@@ -3327,10 +3412,17 @@ + # many other folks are still using the older 'invalid option' + # lib/getopt.c will use POSIX when __posixly_correct + # otherwise the other, so accept both of them. -- mdb ++ # Added optional single quotes. -- mirabilos ++ # The above is actually untrue, POSIX only documents some older ++ # texts that can be used and explicitly leaves open the format ++ # of these messages. Also, GNU getopt is broken and does not ++ # use __progname in the first place. *sigh* -- mirabilos ++ # Also supporting either argv0 with both errors and optional ++ # quotes now. -- mirabilos + dotest_fail basicb-21 "${testcvs} -q admin -H" \ +-"admin: invalid option -- H ++"admin: i[ln][lv][ea][gl][ai][ld] option -- '*H'* + ${CPROG} \[admin aborted\]: specify ${CPROG} -H admin for usage information" \ +-"admin: illegal option -- H ++"cvs: i[ln][lv][ea][gl][ai][ld] option -- '*H'* + ${CPROG} \[admin aborted\]: specify ${CPROG} -H admin for usage information" + cd .. + rmdir 1 +@@ -3356,8 +3448,8 @@ + dotest basicc-2 "$testcvs -q co -l ." + mkdir first-dir second-dir + dotest basicc-3 "${testcvs} add first-dir second-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository +-Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control ++Directory ${CVSROOT_DIRNAME}/second-dir put under version control" + # Old versions of CVS often didn't create this top-level CVS + # directory in the first place. I think that maybe the only + # way to get it to work currently is to let CVS create it, +@@ -3807,7 +3899,7 @@ + for i in dir1 dir2 dir3 dir4 dir5 dir6 dir7 dir8; do + mkdir $i + dotest deep-2-$i "${testcvs} add $i" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir1[/dir0-9]* added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir1[/dir0-9]* put under version control" + cd $i + echo file1 >file1 + dotest deep-3-$i "${testcvs} add file1" \ +@@ -3924,7 +4016,7 @@ + if test ! -d $i ; then + mkdir $i + dotest basic2-2-$i "${testcvs} add $i" \ +-"Directory ${CVSROOT_DIRNAME}/.*/$i added to the repository" ++"Directory ${CVSROOT_DIRNAME}/.*/$i put under version control" + fi + + cd $i +@@ -4907,14 +4999,14 @@ + + # try and list a file before it's created, during an old revision, in + # a period when it was dead and in the future +- time_prebirth=`date '+%Y-%m-%d %H:%M:%S'` ; sleep 1 ++ time_prebirth=`date '+%Y-%m-%d %H:%M:%S'` ; sleep 2 + touch dated + dotest ls-D-init-1 "$testcvs -Q add dated" + dotest ls-D-init-2 "$testcvs -Q ci -mm dated" +- time_newborn=`date '+%Y-%m-%d %H:%M:%S'` ; sleep 1 ++ time_newborn=`date '+%Y-%m-%d %H:%M:%S'` ; sleep 2 + echo mm >> dated + dotest ls-D-init-2 "$testcvs -Q ci -mm dated" +- time_predeath=`date '+%Y-%m-%d %H:%M:%S'` ; sleep 1 ++ time_predeath=`date '+%Y-%m-%d %H:%M:%S'` ; sleep 2 + rm dated + dotest ls-D-init-3 "$testcvs -Q rm dated" + dotest ls-D-init-4 "$testcvs -Q ci -mm dated" +@@ -4963,7 +5055,6 @@ + CVSROOT=":pserver;proxy=localhost;proxyport=8080:localhost/dev/null" + dotest parseroot-3r "$testcvs -d'$CVSROOT' logout" \ + "Logging out of :pserver:$username@localhost:2401/dev/null +-$CPROG logout: warning: failed to open $HOME/\.cvspass for reading: No such file or directory + $CPROG logout: Entry not found." + CVSROOT=":pserver;proxyport=8080:localhost/dev/null" + dotest_fail parseroot-4r "$testcvs -d'$CVSROOT' logout" \ +@@ -5010,7 +5101,7 @@ + dotest files-1 "${testcvs} -q co -l ." "" + mkdir first-dir + dotest files-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch tfile + dotest files-3 "${testcvs} add tfile" \ +@@ -5023,7 +5114,7 @@ + dotest files-6 "${testcvs} -q update -r C" "" + mkdir dir + dotest files-7 "${testcvs} add dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir added to the repository ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir put under version control + --> Using per-directory sticky tag .C'" + cd dir + touch .file +@@ -5032,12 +5123,12 @@ + ${SPROG} add: use .${SPROG} commit. to add this file permanently" + mkdir sdir + dotest files-7c "${testcvs} add sdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir added to the repository ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir put under version control + --> Using per-directory sticky tag .C'" + cd sdir + mkdir ssdir + dotest files-8 "${testcvs} add ssdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir added to the repository ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir put under version control + --> Using per-directory sticky tag .C'" + cd ssdir + touch .file +@@ -5117,10 +5208,10 @@ + initial revision: 1\.1" + mkdir 'first dir' + dotest spacefiles-4 "${testcvs} add 'first dir'" \ +-"Directory ${CVSROOT_DIRNAME}/first dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first dir put under version control" + mkdir ./-b + dotest spacefiles-5 "${testcvs} add -- -b" \ +-"Directory ${CVSROOT_DIRNAME}/-b added to the repository" ++"Directory ${CVSROOT_DIRNAME}/-b put under version control" + cd 'first dir' + touch 'a file' + dotest spacefiles-6 "${testcvs} add 'a file'" \ +@@ -5193,7 +5284,7 @@ + dotest status-init-1 "$testcvs -q co -l ." + mkdir first-dir + dotest status-init-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + echo a line >tfile + dotest status-init-3 "${testcvs} add tfile" \ +@@ -5285,7 +5376,7 @@ + cd .. + mkdir fourth-dir + dotest status-init-8 "$testcvs add fourth-dir" \ +-"Directory $CVSROOT_DIRNAME/fourth-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/fourth-dir put under version control" + cd fourth-dir + echo yet another line >t3file + dotest status-init-9 "$testcvs add t3file" \ +@@ -5297,7 +5388,7 @@ + cd ../first-dir + mkdir third-dir + dotest status-init-11 "$testcvs add third-dir" \ +-"Directory $CVSROOT_DIRNAME/first-dir/third-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir/third-dir put under version control" + cd third-dir + echo another line >t2file + dotest status-init-12 "$testcvs add t2file" \ +@@ -5650,7 +5741,7 @@ + dotest diff-1 "$testcvs -q co -l ." + mkdir first-dir + dotest diff-2 "$testcvs add first-dir" \ +-"Directory $CVSROOT_DIRNAME/first-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir put under version control" + cd first-dir + + # diff is anomalous. Most CVS commands print the "nothing +@@ -5697,7 +5788,7 @@ + dotest diffnl-000 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest diffnl-001 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + + ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nfive\nsix")}' </dev/null >abc +@@ -5861,7 +5952,7 @@ + # doesn't get confused by it. + mkdir subdir + dotest 65a0 "${testcvs} add subdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/subdir put under version control" + cd subdir + echo file in subdir >sfile + dotest 65a1 "${testcvs} add sfile" \ +@@ -6590,7 +6681,7 @@ + dotest rmadd-1 "$testcvs -q co -l ." + mkdir first-dir + dotest rmadd-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + echo first file1 >file1 + dotest rmadd-3 "${testcvs} add file1" \ +@@ -6668,6 +6759,7 @@ + >$CVSROOT_DIRNAME/CVSROOT/val-tags-tmp + mv $CVSROOT_DIRNAME/CVSROOT/val-tags-tmp \ + $CVSROOT_DIRNAME/CVSROOT/val-tags ++ rm -f $CVSROOT_DIRNAME/CVSROOT/val-tags.db + + dotest rmadd-18 "$testcvs -q update -p -r mynonbranch file1" \ + "first file1" +@@ -6733,7 +6825,7 @@ + # now try forced revision with recursion + mkdir sub + dotest rmadd-26 "${testcvs} -q add sub" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/sub added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/sub put under version control" + echo hello >sub/subfile + dotest rmadd-27 "${testcvs} -q add sub/subfile" \ + "${SPROG} add: use .${SPROG} commit. to add this file permanently" +@@ -6790,7 +6882,7 @@ + dotest rmadd2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest rmadd2-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + echo 'initial contents' >file1 + dotest rmadd2-3 "${testcvs} add file1" \ +@@ -6890,7 +6982,7 @@ + dotest rmadd3-init1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest rmadd3-init2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + + echo initial content for file1 >file1 +@@ -6941,7 +7033,7 @@ + dotest resurrection-init1 "$testcvs -q co -l ." '' + mkdir first-dir + dotest resurrection-init2 "$testcvs add first-dir" \ +-"Directory $CVSROOT_DIRNAME/first-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir put under version control" + cd first-dir + + echo initial content for file1 >file1 +@@ -7106,11 +7198,11 @@ + dotest dirs2-1 "$testcvs -q co -l ." + mkdir first-dir + dotest dirs2-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + mkdir sdir + dotest dirs2-3 "${testcvs} add sdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/sdir put under version control" + touch sdir/file1 + dotest dirs2-4 "${testcvs} add sdir/file1" \ + "${SPROG} add: scheduling file .sdir/file1. for addition +@@ -7452,7 +7544,7 @@ + '"${SPROG}"' add: use .'"${SPROG}"' commit. to add this file permanently' + mkdir dir1 + dotest branches2-9 "${testcvs} add dir1" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 put under version control + --> Using per-directory sticky tag "'`'"b1'" + echo "file3 first revision" > dir1/file3 + dotest branches2-10 "${testcvs} add dir1/file3" \ +@@ -7802,7 +7894,7 @@ + cd first-dir + mkdir dir2 + dotest branches2-25 "${testcvs} add dir2" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir2 added to the repository ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir2 put under version control + --> Using per-directory sticky tag "'`'"b1'" + echo "file4 first revision" > dir2/file4 + dotest branches2-26 "${testcvs} add dir2/file4" \ +@@ -7952,10 +8044,10 @@ + cd first-dir + mkdir branches mixed mixed2 versions + dotest branches4-2 "${testcvs} -q add branches mixed mixed2 versions" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/branches added to the repository +-Directory ${CVSROOT_DIRNAME}/first-dir/mixed added to the repository +-Directory ${CVSROOT_DIRNAME}/first-dir/mixed2 added to the repository +-Directory ${CVSROOT_DIRNAME}/first-dir/versions added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/branches put under version control ++Directory ${CVSROOT_DIRNAME}/first-dir/mixed put under version control ++Directory ${CVSROOT_DIRNAME}/first-dir/mixed2 put under version control ++Directory ${CVSROOT_DIRNAME}/first-dir/versions put under version control" + + echo file1 >branches/file1 + echo file2 >branches/file2 +@@ -8031,7 +8123,7 @@ + dotest tagc-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest tagc-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch file1 file2 + dotest tagc-3 "${testcvs} add file1 file2" \ +@@ -8052,7 +8144,7 @@ + T file2" + # Avoid timestamp granularity bugs (FIXME: CVS should be + # doing the sleep, right?). +- sleep 1 ++ sleep 2 + echo myedit >>file1 + dotest tagc-6a "${testcvs} rm -f file2" \ + "${SPROG} remove: scheduling .file2. for removal +@@ -8193,7 +8285,7 @@ + dotest tagf-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest tagf-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch file1 file2 + dotest tagf-3 "${testcvs} add file1 file2" \ +@@ -8397,7 +8489,7 @@ + dotest tag-space-init-1 "$testcvs -q co -l ." + mkdir first-dir + dotest tag-space-init-2 "$testcvs add first-dir" \ +-"Directory $CVSROOT_DIRNAME/first-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir put under version control" + cd first-dir + touch file1 + dotest tag-space-init-3 "$testcvs add file1" \ +@@ -8672,7 +8764,7 @@ + dotest rcslib-merge-1 "$testcvs -q co -l ." + mkdir first-dir + dotest rcslib-merge-2 "$testcvs -q add first-dir" \ +-"Directory $CVSROOT_DIRNAME.*/first-dir added to the repository" ++"Directory $CVSROOT_DIRNAME.*/first-dir put under version control" + cd ..; rm -r 1 + + dotest rcslib-merge-3 "$testcvs -q co first-dir" "" +@@ -9320,8 +9412,7 @@ + # Also the -d option. + + # Set a predictable time zone for these tests. +- save_TZ=$TZ +- TZ=UTC0; export TZ ++ do_save_TZ + + mkdir 1; cd 1 + mkdir adir bdir cdir +@@ -9444,7 +9535,7 @@ + dotest_fail importc-12 "test -d ${TESTDIR}/other" "" + + dokeep +- TZ=$save_TZ ++ do_restore_TZ + cd .. + rm -r 1 2 + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir +@@ -9757,7 +9848,19 @@ + N import-quirks-4/file1 + N import-quirks-4/file2 + N import-quirks-4/file3 +-No conflicts created by this import" ++No conflicts created by this import ++cvs import: warning: you are using an even vendor branch, which can ++lead to problems: '1.1.2'. Use an odd branch such as '1.1.3' instead." \ ++" ++ ++N import-quirks-4/file1 ++N import-quirks-4/file2 ++N import-quirks-4/file3 ++No conflicts created by this import ++cvs import: warning: you are using an even vendor branch, which can ++cvs import: warning: you are using an even vendor branch, which can ++lead to problems: '1.1.2'. Use an odd branch such as '1.1.3' instead. ++lead to problems: '1.1.2'. Use an odd branch such as '1.1.3' instead." + + dokeep + cd .. +@@ -9785,14 +9888,18 @@ + # Create the module. + dotest import-after-initial-1 \ + "$testcvs -Q import -m. $module X Y" '' ++ sync >/dev/null 2>&1 + + file=m + # Check it out and add a file. + dotest import-after-initial-2 "$testcvs -Q co $module" '' ++ sync >/dev/null 2>&1 + cd $module + echo original > $file + dotest import-after-initial-3 "${testcvs} -Q add $file" "" ++ sync >/dev/null 2>&1 + dotest import-after-initial-4 "$testcvs -Q ci -m. $file" ++ sync >/dev/null 2>&1 + + # Delay a little so the following import isn't done in the same + # second as the preceding commit. +@@ -9803,12 +9910,14 @@ + mkdir sub + cd sub + echo newer-via-import > $file ++ sync >/dev/null 2>&1 + dotest import-after-initial-5 \ + "$testcvs -Q import -m. $module X Y2" '' ++ sync >/dev/null 2>&1 + cd .. + + # Sleep a second so we're sure to be after the second of the import. +- sleep 1 ++ sleep 2 + + dotest import-after-initial-6 \ + "$testcvs -Q update -p -D now $file" 'original' +@@ -10380,7 +10489,7 @@ + dotest join2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest join2-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + echo 'initial contents of file1' >file1 + dotest join2-3 "${testcvs} add file1" \ +@@ -10489,7 +10598,7 @@ + dotest join3-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest join3-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + echo 'initial contents of file1' >file1 + dotest join3-3 "${testcvs} add file1" \ +@@ -11130,7 +11239,7 @@ + module=x + mkdir $module + dotest join-admin-0-2 "$testcvs -q add $module" \ +-"Directory $CVSROOT_DIRNAME/$module added to the repository" ++"Directory $CVSROOT_DIRNAME/$module put under version control" + cd $module + + # Create a file so applying the first tag works. +@@ -11182,7 +11291,7 @@ + module=x + mkdir $module + dotest join-admin-2-2 "$testcvs -q add $module" \ +-"Directory ${CVSROOT_DIRNAME}/x added to the repository" ++"Directory ${CVSROOT_DIRNAME}/x put under version control" + cd $module + + # Create a file so applying the first tag works. +@@ -11252,7 +11361,7 @@ + dotest join-rm-init-1 "$testcvs -q co -l ." '' + mkdir $module + dotest join-rm-init-2 "$testcvs -q add $module" \ +-"Directory $CVSROOT_DIRNAME/$module added to the repository" ++"Directory $CVSROOT_DIRNAME/$module put under version control" + cd $module + + # add some files. +@@ -11497,7 +11606,7 @@ + echo add a line >>a + mkdir dir1 + dotest conflicts-127b "${testcvs} add dir1" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 put under version control" + dotest conflicts-128 "${testcvs} -q ci -m changed" \ + "$CVSROOT_DIRNAME/first-dir/a,v <-- a + new revision: 1\.2; previous revision: 1\.1" +@@ -11945,7 +12054,7 @@ + dotest conflicts3-1 "$testcvs -q co -l ." + mkdir first-dir + dotest conflicts3-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd .. + mkdir 2; cd 2 + dotest conflicts3-3 "${testcvs} -q co -l first-dir" '' +@@ -11994,7 +12103,7 @@ + # and see that CVS doesn't lose its mind. + mkdir sdir + dotest conflicts3-14 "${testcvs} add sdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/sdir put under version control" + touch sdir/sfile + dotest conflicts3-14a "${testcvs} add sdir/sfile" \ + "${SPROG} add: scheduling file .sdir/sfile. for addition +@@ -12107,7 +12216,7 @@ + dotest clean-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest clean-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + echo "The usual boring test text." > cleanme.txt + dotest clean-3 "${testcvs} add cleanme.txt" \ +@@ -12437,12 +12546,12 @@ + cd first-dir + mkdir subdir + dotest modules-143a "${testcvs} add subdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/subdir put under version control" + + cd subdir + mkdir ssdir + dotest modules-143b "${testcvs} add ssdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/subdir/ssdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/subdir/ssdir put under version control" + + touch a b + +@@ -12699,9 +12808,9 @@ + mkdir first-dir second-dir third-dir + dotest modules2-setup-2 \ + "${testcvs} add first-dir second-dir third-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository +-Directory ${CVSROOT_DIRNAME}/second-dir added to the repository +-Directory ${CVSROOT_DIRNAME}/third-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control ++Directory ${CVSROOT_DIRNAME}/second-dir put under version control ++Directory ${CVSROOT_DIRNAME}/third-dir put under version control" + cd third-dir + touch file3 + dotest modules2-setup-3 "${testcvs} add file3" \ +@@ -12947,7 +13056,7 @@ + dotest modules3-0 "$testcvs -q co -l ." + mkdir first-dir + dotest modules3-1 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + + cd first-dir + echo file1 >file1 +@@ -13008,11 +13117,11 @@ + cd second-dir + mkdir suba + dotest modules3-7-workaround1 "${testcvs} add suba" \ +-"Directory ${CVSROOT_DIRNAME}/second-dir/suba added to the repository" ++"Directory ${CVSROOT_DIRNAME}/second-dir/suba put under version control" + cd suba + mkdir subb + dotest modules3-7-workaround2 "${testcvs} add subb" \ +-"Directory ${CVSROOT_DIRNAME}/second-dir/suba/subb added to the repository" ++"Directory ${CVSROOT_DIRNAME}/second-dir/suba/subb put under version control" + cd ../.. + fi + +@@ -13113,13 +13222,13 @@ + dotest modules4-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest modules4-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + + cd first-dir + mkdir subdir subdir_long + dotest modules4-3 "${testcvs} add subdir subdir_long" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository +-Directory ${CVSROOT_DIRNAME}/first-dir/subdir_long added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/subdir put under version control ++Directory ${CVSROOT_DIRNAME}/first-dir/subdir_long put under version control" + + echo file1 > file1 + dotest modules4-4 "${testcvs} add file1" \ +@@ -13248,11 +13357,11 @@ + cd first-dir + mkdir subdir + dotest modules5-2 "${testcvs} add subdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/subdir put under version control" + cd subdir + mkdir ssdir + dotest modules5-3 "${testcvs} add ssdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/subdir/ssdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/subdir/ssdir put under version control" + touch a b + dotest modules5-4 "${testcvs} add a b" \ + "${SPROG} add: scheduling file .a. for addition +@@ -13291,7 +13400,7 @@ + for i in checkout export tag; do + cat >> ${CVSROOT_DIRNAME}/$i.sh <<EOF + #! $TESTSHELL +-sleep 1 ++sleep 2 + echo "$i script invoked in \`pwd\`" + echo "args: \$@" + EOF +@@ -13950,12 +14059,12 @@ + mkdir mod2-2 + mkdir mod2-2/sub2-2 + dotest cvsadm-2a "${testcvs} add mod1 mod1-2 mod2 mod2/sub2 mod2-2 mod2-2/sub2-2" \ +-"Directory ${CVSROOT_DIRNAME}/mod1 added to the repository +-Directory ${CVSROOT_DIRNAME}/mod1-2 added to the repository +-Directory ${CVSROOT_DIRNAME}/mod2 added to the repository +-Directory ${CVSROOT_DIRNAME}/mod2/sub2 added to the repository +-Directory ${CVSROOT_DIRNAME}/mod2-2 added to the repository +-Directory ${CVSROOT_DIRNAME}/mod2-2/sub2-2 added to the repository" ++"Directory ${CVSROOT_DIRNAME}/mod1 put under version control ++Directory ${CVSROOT_DIRNAME}/mod1-2 put under version control ++Directory ${CVSROOT_DIRNAME}/mod2 put under version control ++Directory ${CVSROOT_DIRNAME}/mod2/sub2 put under version control ++Directory ${CVSROOT_DIRNAME}/mod2-2 put under version control ++Directory ${CVSROOT_DIRNAME}/mod2-2/sub2-2 put under version control" + + # Populate the directories for the halibut + echo "file1" > mod1/file1 +@@ -15001,7 +15110,7 @@ + echo "file1" > mod1/file1 + mkdir moda/modasub + dotest emptydir-3b "${testcvs} add moda/modasub" \ +-"Directory ${CVSROOT_DIRNAME}/moda/modasub added to the repository" ++"Directory ${CVSROOT_DIRNAME}/moda/modasub put under version control" + echo "filea" > moda/modasub/filea + dotest emptydir-4 "${testcvs} add mod1/file1 moda/modasub/filea" \ + "${SPROG} add: scheduling file .mod1/file1. for addition +@@ -15328,8 +15437,8 @@ + dotest toplevel-1 "${testcvs} -q co -l ." '' + mkdir top-dir second-dir + dotest toplevel-2 "${testcvs} add top-dir second-dir" \ +-"Directory ${CVSROOT_DIRNAME}/top-dir added to the repository +-Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/top-dir put under version control ++Directory ${CVSROOT_DIRNAME}/second-dir put under version control" + cd top-dir + + touch file1 +@@ -15447,8 +15556,8 @@ + dotest toplevel2-1 "${testcvs} -q co -l ." '' + mkdir top-dir second-dir + dotest toplevel2-2 "${testcvs} add top-dir second-dir" \ +-"Directory ${CVSROOT_DIRNAME}/top-dir added to the repository +-Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/top-dir put under version control ++Directory ${CVSROOT_DIRNAME}/second-dir put under version control" + cd top-dir + + touch file1 +@@ -15686,7 +15795,7 @@ + # can see the "CVS:" lines. + cat >${TESTDIR}/editme <<EOF + #!${TESTSHELL} +-sleep 1 ++sleep 2 + sed <\$1 -e 's/^/x/' >${TESTDIR}/edit.new + mv ${TESTDIR}/edit.new \$1 + exit 0 +@@ -15697,7 +15806,7 @@ + dotest editor-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest editor-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch file1 file2 + dotest editor-3 "${testcvs} add file1 file2" \ +@@ -15741,6 +15850,7 @@ + revision 1\.1 + date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; + branches: 1\.1\.2; ++x + xCVS: ---------------------------------------------------------------------- + xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically + xCVS: +@@ -15752,6 +15862,7 @@ + ---------------------------- + revision 1\.1\.2\.1 + date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; ++x + xCVS: ---------------------------------------------------------------------- + xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically + xCVS: +@@ -15779,6 +15890,7 @@ + revision 1\.1 + date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; + branches: 1\.1\.2; ++x + xCVS: ---------------------------------------------------------------------- + xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically + xCVS: +@@ -15790,6 +15902,7 @@ + ---------------------------- + revision 1\.1\.2\.1 + date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; ++x + xCVS: ---------------------------------------------------------------------- + xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically + xCVS: +@@ -15811,6 +15924,7 @@ + revision 1\.1 + date: ${ISO8601DATE}; author: ${username}; state: Exp; commitid: ${commitid}; + branches: 1\.1\.2; ++x + xCVS: ---------------------------------------------------------------------- + xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically + xCVS: +@@ -15822,6 +15936,7 @@ + ---------------------------- + revision 1\.1\.2\.1 + date: ${ISO8601DATE}; author: ${username}; state: Exp; lines: ${PLUS}1 -0; commitid: ${commitid}; ++x + xCVS: ---------------------------------------------------------------------- + xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically + xCVS: +@@ -15836,7 +15951,7 @@ + # Test CVS's response to an unchanged log message + cat >${TESTDIR}/editme <<EOF + #!${TESTSHELL} +-sleep 1 ++sleep 2 + exit 0 + EOF + chmod +x ${TESTDIR}/editme +@@ -15849,7 +15964,7 @@ + # Test CVS's response to an empty log message + cat >${TESTDIR}/editme <<EOF + #!${TESTSHELL} +-sleep 1 ++sleep 2 + cat /dev/null >\$1 + exit 0 + EOF +@@ -15863,7 +15978,7 @@ + # Test CVS's response to a log message with one blank line + cat >${TESTDIR}/editme <<EOF + #!${TESTSHELL} +-sleep 1 ++sleep 2 + echo >\$1 + exit 0 + EOF +@@ -15877,7 +15992,7 @@ + # Test CVS's response to a log message with only comments + cat >${TESTDIR}/editme <<EOF + #!${TESTSHELL} +-sleep 1 ++sleep 2 + cat \$1 >${TESTDIR}/edit.new + mv ${TESTDIR}/edit.new \$1 + exit 0 +@@ -15905,7 +16020,7 @@ + cd ../first-dir + cat >${TESTDIR}/editme <<EOF + #!${TESTSHELL} +-sleep 1 ++sleep 2 + cp /dev/null \$1 + exit 1 + EOF +@@ -16065,7 +16180,7 @@ + cd .. + mkdir env + dotest env-3 "${testcvs} -q add env" \ +-"Directory ${CVSROOT_DIRNAME}/env added to the repository" ++"Directory ${CVSROOT_DIRNAME}/env put under version control" + cd env + echo testing >file1 + dotest env-4 "${testcvs} add file1" \ +@@ -16159,7 +16274,7 @@ + dotest errmsg2-1 "$testcvs -q co -l ." + mkdir first-dir + dotest errmsg2-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + dotest_fail errmsg2-3 "${testcvs} add CVS" \ + "${CPROG} add: cannot add special file .CVS.; skipping" +@@ -16189,7 +16304,7 @@ + mkdir sdir + cd .. + dotest errmsg2-8 "${testcvs} add first-dir/sdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/sdir put under version control" + # while we're here... check commit with no CVS directory + dotest_fail errmsg2-8a "${testcvs} -q ci first-dir nonexistant" \ + "${CPROG} commit: nothing known about .nonexistant' +@@ -16205,7 +16320,7 @@ + mkdir sdir10 + dotest errmsg2-10 "${testcvs} add file10 sdir10" \ + "${SPROG} add: scheduling file .file10. for addition +-Directory ${CVSROOT_DIRNAME}/first-dir/sdir10 added to the repository ++Directory ${CVSROOT_DIRNAME}/first-dir/sdir10 put under version control + ${SPROG} add: use .${SPROG} commit. to add this file permanently" + dotest errmsg2-11 "${testcvs} -q ci -m add-file10" \ + "$CVSROOT_DIRNAME/first-dir/file10,v <-- file10 +@@ -16219,7 +16334,7 @@ + cd .. + mkdir first-dir/sdir10/ssdir + dotest errmsg2-13 "${testcvs} add first-dir/sdir10/ssdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/sdir10/ssdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/sdir10/ssdir put under version control" + + touch first-dir/sdir10/ssdir/ssfile + dotest errmsg2-14 \ +@@ -16360,7 +16475,7 @@ + dotest adderrmsg-init1 "${testcvs} -q co -l ." '' + mkdir adderrmsg-dir + dotest adderrmsg-init2 "${testcvs} add adderrmsg-dir" \ +-"Directory ${CVSROOT_DIRNAME}/adderrmsg-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/adderrmsg-dir put under version control" + cd adderrmsg-dir + + # try to add the admin dir +@@ -16839,7 +16954,7 @@ + dotest watch4-0a "${testcvs} -q co -l ." '' + mkdir first-dir + dotest watch4-0b "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + + cd first-dir + dotest watch4-1 "${testcvs} watch on" '' +@@ -16854,7 +16969,7 @@ + # Now test the analogous behavior for directories. + mkdir subdir + dotest watch4-4 "${testcvs} add subdir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/subdir put under version control" + cd subdir + touch sfile + dotest watch4-5 "${testcvs} add sfile" \ +@@ -16945,7 +17060,7 @@ + dotest watch5-0a "${testcvs} -q co -l ." '' + mkdir first-dir + dotest watch5-0b "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + + cd first-dir + dotest watch5-1 "${testcvs} watch on" '' +@@ -17125,7 +17240,7 @@ + dotest edit-check-0a "$testcvs -q co -l ." + mkdir first-dir + dotest edit-check-0b "$testcvs add first-dir" \ +-"Directory $CVSROOT_DIRNAME/first-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir put under version control" + + cd first-dir + dotest edit-check-1 "$testcvs watch on" +@@ -17243,7 +17358,7 @@ + + # Manually fake another editor: + +- # Try to gaurantee a seperate name for an "other" user editting ++ # Try to guarantee a seperate name for an "other" user editing + # the file. + otherUser="dummyUser" + if [ x"$USER" = x"$otherUser" ] ; then +@@ -17374,7 +17489,7 @@ + + mkdir second-dir + dotest edit-check-32c "$testcvs add second-dir" \ +-"Directory $CVSROOT_DIRNAME/first-dir/second-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir/second-dir put under version control" + cd second-dir + echo ThirdFile >file3 + +@@ -18770,7 +18885,7 @@ + dotest mwrap-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest mwrap-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch aa + dotest mwrap-3 "${testcvs} add aa" \ +@@ -19180,7 +19295,7 @@ + exit 0 + else + echo "No BugId found." +- sleep 1 ++ sleep 2 + exit 1 + fi + EOF +@@ -19747,7 +19862,7 @@ + dotest taginfo-newfmt-8 "${testcvs} -q tag tag1" "" + mkdir sdir + dotest taginfo-newfmt-8b "${testcvs} -q add sdir" \ +-"Directory ${TESTDIR}/cvsroot/first-dir/sdir added to the repository" ++"Directory ${TESTDIR}/cvsroot/first-dir/sdir put under version control" + touch sdir/file3 + dotest taginfo-newfmt-8c "${testcvs} -q add sdir/file3" \ + "${SPROG} add: use .${SPROG} commit. to add this file permanently" +@@ -20043,7 +20158,7 @@ + new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* + $SPROG commit: Rebuilding administrative file database" + +- sleep 1 ++ sleep 2 + echo '# noop' >> config + dotest config-7 "$testcvs -q ci -mlog-commit" \ + "$CVSROOT_DIRNAME/CVSROOT/config,v <-- config +@@ -21586,7 +21701,7 @@ + dotest logopt-1 "$testcvs -q co -l ." '' + mkdir first-dir + dotest logopt-2 "$testcvs add first-dir" \ +-"Directory $CVSROOT_DIRNAME/first-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir put under version control" + cd first-dir + echo hi >file1 + dotest logopt-3 "${testcvs} add file1" \ +@@ -21631,7 +21746,7 @@ + dotest ann-1 "$testcvs -q co -l ." + mkdir first-dir + dotest ann-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + cat >file1 <<EOF + this +@@ -21811,7 +21926,7 @@ + module=x + mkdir $module + dotest ann-id-2 "${testcvs} add $module" \ +-"Directory ${CVSROOT_DIRNAME}/$module added to the repository" ++"Directory ${CVSROOT_DIRNAME}/$module put under version control" + cd $module + + file=m +@@ -21946,9 +22061,10 @@ + # can look up '..' and want to ask the user about the unknown host + # key or somesuch. Which error message we get depends on whether + # false finishes running before we try to talk to it or not. ++ # We don't even get to talk to it as of 1.12.13-MirOS-0AB8.2 tho. + dotest_fail crerepos-6a "CVS_RSH=false ${testcvs} -q -d ../crerepos get ." \ +-"${SPROG} \[checkout aborted\]: end of file from server (consult above messages if any)" \ +-"${SPROG} \[checkout aborted\]: received broken pipe signal" ++"${SPROG} checkout: Missing or bad hostname in CVSROOT\. ++${SPROG} \[checkout aborted\]: Bad CVSROOT: .\.\./crerepos.\." + cd .. + rm -r 1 + +@@ -21972,7 +22088,7 @@ + dotest crerepos-8 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest crerepos-9 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch file1 + dotest crerepos-10 "${testcvs} add file1" \ +@@ -21988,7 +22104,7 @@ + dotest crerepos-12 "$testcvs -d $CREREPOS_ROOT -q co -l ." + mkdir crerepos-dir + dotest crerepos-13 "$testcvs add crerepos-dir" \ +-"Directory $TESTDIR/crerepos/crerepos-dir added to the repository" ++"Directory $TESTDIR/crerepos/crerepos-dir put under version control" + cd crerepos-dir + touch cfile + dotest crerepos-14 "${testcvs} add cfile" \ +@@ -22039,8 +22155,7 @@ + + # Save the timezone and set it to UTC for these tests to make the + # value more predicatable. +- save_TZ=$TZ +- TZ=UTC0; export TZ ++ do_save_TZ + + modify_repo mkdir $CVSROOT_DIRNAME/first-dir + +@@ -22517,7 +22632,7 @@ + revision 1\.4" + + dokeep +- TZ=$save_TZ ++ do_restore_TZ + cd .. + rm -r first-dir + modify_repo rm -rf $CVSROOT_DIRNAME/first-dir +@@ -22707,8 +22822,7 @@ + # revisions 1.1 and 1.1.1.1 differ by 1 second. + + # Need a predictable time zone. +- save_TZ=$TZ +- TZ=UTC0; export TZ ++ do_save_TZ + + mkdir rcs4 + cd rcs4 +@@ -22766,7 +22880,7 @@ + Sticky Options: (none)' + + dokeep +- TZ=$save_TZ ++ do_restore_TZ + cd ../.. + rm -r rcs4 + modify_repo rm -rf $CVSROOT_DIRNAME/rcs4-dir +@@ -23087,11 +23201,11 @@ + dotest backuprecover-1 "$testcvs -q co -l ." + mkdir first-dir + dotest backuprecover-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + mkdir dir + dotest backuprecover-3 "${testcvs} add dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir put under version control" + touch file1 dir/file2 + dotest backuprecover-4 "${testcvs} -q add file1 dir/file2" \ + "${SPROG} add: use \`${SPROG} commit' to add these files permanently" +@@ -23348,7 +23462,7 @@ + dotest sshstdio-1 "$testcvs -d $SSHSTDIO_ROOT -q co -l ." + mkdir first-dir + dotest sshstdio-2 "$testcvs add first-dir" \ +- "Directory $CVSROOT_DIRNAME/first-dir added to the repository" ++ "Directory $CVSROOT_DIRNAME/first-dir put under version control" + cd first-dir + a='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + c='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' +@@ -23497,7 +23611,7 @@ + dotest parseroot3-9 "$testcvs -Q co -ldtop ." + dotest parseroot3-10 "test -d top" + dotest parseroot3-11 "test -d top/CVS" +- dotest parseroot3-10 "cat top/CVS/Root" "$CVSROOT" ++ dotest parseroot3-12 "cat top/CVS/Root" "$CVSROOT" + + dokeep + cd .. +@@ -23526,16 +23640,17 @@ + continue + fi + ++ # times have been tweaked so leap seconds don't matter + cat <<EOF >$CVSROOT_DIRNAME/CVSROOT/history +-O3395c677|anonymous|<remote>/*0|ccvs||ccvs ++O3395c684|anonymous|<remote>/*0|ccvs||ccvs + O3396c677|anonymous|<remote>/src|ccvs||src + O3397c677|kingdon|<remote>/*0|ccvs||ccvs + M339cafae|nk|<remote>|ccvs/src|1.229|sanity.sh +-M339cafff|anonymous|<remote>|ccvs/src|1.23|Makefile ++M339cb00c|anonymous|<remote>|ccvs/src|1.23|Makefile + M339dc339|kingdon|~/work/*0|ccvs/src|1.231|sanity.sh + W33a6eada|anonymous|<remote>*4|ccvs/emx||Makefile.in + C3b235f50|kingdon|<remote>|ccvs/emx|1.3|README +-M3b23af50|kingdon|~/work/*0|ccvs/doc|1.281|cvs.texinfo ++M3b23af62|kingdon|~/work/*0|ccvs/doc|1.281|cvs.texinfo + EOF + + dotest history-1 "${testcvs} history -e -a" \ +@@ -23691,7 +23806,7 @@ + dotest modes-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest modes-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch aa + dotest modes-3 "${testcvs} add aa" \ +@@ -23817,7 +23932,7 @@ + dotest modes2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest modes2-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch aa + dotest modes2-3 "${testcvs} add aa" \ +@@ -23864,8 +23979,8 @@ + dotest modes3-1 "$testcvs -q co -l ." + mkdir first-dir second-dir + dotest modes3-2 "${testcvs} add first-dir second-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository +-Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control ++Directory ${CVSROOT_DIRNAME}/second-dir put under version control" + touch first-dir/aa second-dir/ab + dotest modes3-3 "${testcvs} add first-dir/aa second-dir/ab" \ + "${SPROG} add: scheduling file .first-dir/aa. for addition +@@ -23944,7 +24059,7 @@ + dotest stamps-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest stamps-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch aa + echo '$''Id$' >kw +@@ -24073,7 +24188,7 @@ + dotest perms-1 "$testcvs -q co -l ." + mkdir first-dir + dotest perms-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + + touch foo +@@ -24115,7 +24230,7 @@ + dotest symlinks-1 "$testcvs -q co -l ." + mkdir first-dir + dotest symlinks-2 "$testcvs add first-dir" \ +-"Directory $CVSROOT_DIRNAME/first-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir put under version control" + cd first-dir + + dotest symlinks-2.1 "ln -s $TESTDIR/fumble slink" +@@ -24158,7 +24273,7 @@ + dotest symlinks2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest symlinks2-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + echo nonsymlink > slink + dotest symlinks2-3 "${testcvs} add slink" \ +@@ -24196,7 +24311,7 @@ + dotest hardlinks-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest hardlinks-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + + # Make up some ugly filenames, to test that they get +@@ -24285,7 +24400,7 @@ + dotest sticky-1 "$testcvs -q co -l ." + mkdir first-dir + dotest sticky-2 "$testcvs add first-dir" \ +-"Directory $CVSROOT_DIRNAME/first-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir put under version control" + cd first-dir + + touch file1 +@@ -24390,7 +24505,7 @@ + dotest keyword-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest keyword-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + + echo '$''Author$' > file1 +@@ -24595,7 +24710,7 @@ + dotest keywordlog-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest keywordlog-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + echo initial >file1 + dotest keywordlog-3 "${testcvs} add file1" \ +@@ -24852,7 +24967,7 @@ + xx" + + cd ../CVSROOT +- echo "MaxCommentLeaderLength=1k" >>config ++ echo "MaxCommentLeaderLength=1K" >>config + dotest keywordlog-35 "$testcvs -Q ci -mset-MaxCommentLeaderLength" + + cd ../first-dir +@@ -24892,7 +25007,7 @@ + dotest keywordname-init-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest keywordname-init-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + + echo '$'"Name$" >file1 +@@ -25012,7 +25127,7 @@ + dotest keyword2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest keyword2-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + + echo '$''Revision$' >> file1 +@@ -25214,7 +25329,7 @@ + ${PLUS} modify on branch + ${PLUS} modify on branch after brtag" + +- # With a branch sticky tag, HEAD is the head of the trunk. ++ # Even with a branch sticky tag, HEAD is the head of the trunk. + dotest head-br1-setup "${testcvs} -q update -r br1" "[UP] file1" + dotest head-br1-update "${testcvs} -q update -r HEAD -p file1" \ + "imported contents +@@ -25222,7 +25337,26 @@ + add a line on trunk after trunktag" + # But diff thinks that HEAD is "br1". Case (b) from cvs.texinfo. + # Probably people are relying on it. +- dotest head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" "" ++ #dotest head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" "" ++ dotest head-br1-diffdot "${testcvs} -q diff -c -r .bhead -r br1" "" ++ # Always. Fuck people relying on it. ++ dotest_fail head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" \ ++"Index: file1 ++=================================================================== ++RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v ++retrieving revision 1\.3 ++retrieving revision 1\.3\.2\.2 ++diff -c -r1\.3 -r1\.3\.2\.2 ++\*\*\* file1 ${RFCDATE} 1\.3 ++--- file1 ${RFCDATE} 1\.3\.2\.2 ++\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* ++\*\*\* 1,3 \*\*\*\* ++--- 1,5 ---- ++ imported contents ++ add a line on trunk ++ add a line on trunk after trunktag ++${PLUS} modify on branch ++${PLUS} modify on branch after brtag" + + # With a nonbranch sticky tag on a branch, + # HEAD is the head of the trunk +@@ -25235,7 +25369,26 @@ + # CVS 1.9 and older thought that HEAD is "brtag" (this was + # noted as "strange, maybe accidental"). But "br1" makes a + # whole lot more sense. +- dotest head-brtag-diff "${testcvs} -q diff -c -r HEAD -r br1" "" ++ #dotest head-brtag-diff "${testcvs} -q diff -c -r HEAD -r br1" "" ++ dotest head-brtag-diffdot "${testcvs} -q diff -c -r .bhead -r br1" "" ++ # HEAD is always tip of the trunk. ++ dotest_fail head-brtag-diff "${testcvs} -q diff -c -r HEAD -r br1" \ ++"Index: file1 ++=================================================================== ++RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v ++retrieving revision 1\.3 ++retrieving revision 1\.3\.2\.2 ++diff -c -r1\.3 -r1\.3\.2\.2 ++\*\*\* file1 ${RFCDATE} 1\.3 ++--- file1 ${RFCDATE} 1\.3\.2\.2 ++\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* ++\*\*\* 1,3 \*\*\*\* ++--- 1,5 ---- ++ imported contents ++ add a line on trunk ++ add a line on trunk after trunktag ++${PLUS} modify on branch ++${PLUS} modify on branch after brtag" + + # With a nonbranch sticky tag on the trunk, HEAD is the head + # of the trunk, I think. +@@ -25319,12 +25472,11 @@ + # for checkout and update as well. + # + mkdir 1; cd 1 +- save_TZ=$TZ +- TZ=UTC0; export TZ ++ do_save_TZ + dotest tagdate-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest tagdate-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + + echo trunk-1 >file1 +@@ -25784,7 +25936,7 @@ + + unset date_T1 date_T2 date_T3 date_T4 date_T5 + unset date_T6 date_T7 date_T8 date_T9 +- TZ=$save_TZ ++ do_restore_TZ + + dokeep + rm -r 1 2 3 4 +@@ -25802,7 +25954,7 @@ + dotest multibranch2-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest multibranch2-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + + echo trunk-1 >file1 +@@ -26038,7 +26190,7 @@ + dotest admin-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest admin-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + + dotest_fail admin-3 "${testcvs} -q admin -i file1" \ +@@ -27002,7 +27154,7 @@ + dotest reserved-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest reserved-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch file1 + dotest reserved-3 "${testcvs} add file1" \ +@@ -28061,18 +28213,18 @@ + dotest release-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest release-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + mkdir dir1 + dotest release-3 "${testcvs} add dir1" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 put under version control" + mkdir dir2 + dotest release-4 "${testcvs} add dir2" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir2 added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir2 put under version control" + cd dir2 + mkdir dir3 + dotest release-5 "${testcvs} add dir3" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir2/dir3 added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir2/dir3 put under version control" + + cd ../.. + dotest release-6 "${testcvs} release -d first-dir/dir2/dir3 first-dir/dir1" \ +@@ -28093,11 +28245,11 @@ + cd first-dir + mkdir dir1 + dotest release-10 "${testcvs} add dir1" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 put under version control" + cd dir2 + mkdir dir3 + dotest release-11 "${testcvs} add dir3" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir/dir2/dir3 added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir/dir2/dir3 put under version control" + + cd ../.. + dotest release-12 "${testcvs} release first-dir/dir2/dir3 first-dir/dir1" \ +@@ -28148,7 +28300,7 @@ + cd first-dir + mkdir second-dir + dotest release-18 "$testcvs add second-dir" \ +-"Directory $CVSROOT_DIRNAME/first-dir/second-dir added to the repository" ++"Directory $CVSROOT_DIRNAME/first-dir/second-dir put under version control" + + cd second-dir + touch file1 +@@ -28756,8 +28908,34 @@ + testcvs2="$testcvs -d '$CVSROOT2'" + + dotest multiroot-setup-1 "mkdir $CVSROOT1_DIRNAME $CVSROOT2_DIRNAME" ++ + dotest multiroot-setup-2 "$testcvs1 init" ++ # remove automatically-created LogHistory to work around the fact ++ # that CVS does not track those per root (and thus warns about ++ # encountering multiple of these entries) ++ mkdir wrkarnd; cd wrkarnd ++ dotest multiroot-setup-2a "$testcvs1 -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" ++ cd CVSROOT ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config ++ dotest multiroot-setup-2b "$testcvs1 -q ci -m workaround-LogHistory" "" \ ++".*/CVSROOT/config,v <-- config ++new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* ++$SPROG commit: Rebuilding administrative file database" ++ cd ../..; rm -r wrkarnd ++ + dotest multiroot-setup-3 "$testcvs2 init" ++ # remove automatically-created LogHistory (see above) ++ mkdir wrkarnd; cd wrkarnd ++ dotest multiroot-setup-3a "$testcvs2 -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" ++ cd CVSROOT ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config ++ dotest multiroot-setup-3b "$testcvs2 -q ci -m workaround-LogHistory" "" \ ++".*/CVSROOT/config,v <-- config ++new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* ++$SPROG commit: Rebuilding administrative file database" ++ cd ../..; rm -r wrkarnd + + # + # create some directories in ${CVSROOT1_DIRNAME} +@@ -28766,8 +28944,8 @@ + dotest multiroot-setup-4 "${testcvs1} co -l ." "${SPROG} checkout: Updating ." + mkdir mod1-1 mod1-2 + dotest multiroot-setup-5 "${testcvs1} add mod1-1 mod1-2" \ +-"Directory ${CVSROOT1_DIRNAME}/mod1-1 added to the repository +-Directory ${CVSROOT1_DIRNAME}/mod1-2 added to the repository" ++"Directory ${CVSROOT1_DIRNAME}/mod1-1 put under version control ++Directory ${CVSROOT1_DIRNAME}/mod1-2 put under version control" + echo file1-1 > mod1-1/file1-1 + echo file1-2 > mod1-2/file1-2 + dotest multiroot-setup-6 "${testcvs1} add mod1-1/file1-1 mod1-2/file1-2" \ +@@ -28792,8 +28970,8 @@ + dotest multiroot-setup-8 "${testcvs2} co -l ." "${SPROG} checkout: Updating ." + mkdir mod2-1 mod2-2 + dotest multiroot-setup-9 "${testcvs2} add mod2-1 mod2-2" \ +-"Directory ${CVSROOT2_DIRNAME}/mod2-1 added to the repository +-Directory ${CVSROOT2_DIRNAME}/mod2-2 added to the repository" ++"Directory ${CVSROOT2_DIRNAME}/mod2-1 put under version control ++Directory ${CVSROOT2_DIRNAME}/mod2-2 put under version control" + echo file2-1 > mod2-1/file2-1 + echo file2-2 > mod2-2/file2-2 + dotest multiroot-setup-6 "${testcvs2} add mod2-1/file2-1 mod2-2/file2-2" \ +@@ -29861,7 +30039,29 @@ + CVSROOT2=`newroot $CVSROOT2_DIRNAME` + + dotest multiroot2-1 "${testcvs} -d ${CVSROOT1} init" "" ++ # remove automatically-created LogHistory (see above) ++ mkdir wrkarnd; cd wrkarnd ++ dotest multiroot2-1a "$testcvs -d ${CVSROOT1} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" ++ cd CVSROOT ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config ++ dotest multiroot2-1b "$testcvs -d ${CVSROOT1} -q ci -m workaround-LogHistory" "" \ ++".*/CVSROOT/config,v <-- config ++new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* ++$SPROG commit: Rebuilding administrative file database" ++ cd ../..; rm -r wrkarnd + dotest multiroot2-2 "${testcvs} -d ${CVSROOT2} init" "" ++ # remove automatically-created LogHistory (see above) ++ mkdir wrkarnd; cd wrkarnd ++ dotest multiroot2-2a "$testcvs -d ${CVSROOT2} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" ++ cd CVSROOT ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config ++ dotest multiroot2-2b "$testcvs -d ${CVSROOT2} -q ci -m workaround-LogHistory" "" \ ++".*/CVSROOT/config,v <-- config ++new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* ++$SPROG commit: Rebuilding administrative file database" ++ cd ../..; rm -r wrkarnd + + mkdir imp-dir; cd imp-dir + echo file1 >file1 +@@ -30017,12 +30217,34 @@ + + mkdir 1; cd 1 + dotest multiroot3-1 "${testcvs} -d ${CVSROOT1} init" "" ++ # remove automatically-created LogHistory (see above) ++ mkdir wrkarnd; cd wrkarnd ++ dotest multiroot3-1a "$testcvs -d ${CVSROOT1} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" ++ cd CVSROOT ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config ++ dotest multiroot3-1b "$testcvs -d ${CVSROOT1} -q ci -m workaround-LogHistory" "" \ ++".*/CVSROOT/config,v <-- config ++new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* ++$SPROG commit: Rebuilding administrative file database" ++ cd ../..; rm -r wrkarnd + dotest multiroot3-2 "${testcvs} -d ${CVSROOT1} -q co -l ." "" + mkdir dir1 + dotest multiroot3-3 "${testcvs} add dir1" \ +-"Directory ${TESTDIR}/root1/dir1 added to the repository" ++"Directory ${TESTDIR}/root1/dir1 put under version control" + dotest multiroot3-4 "${testcvs} -d ${CVSROOT2} init" "" + rm -r CVS ++ # remove automatically-created LogHistory (see above) ++ mkdir wrkarnd; cd wrkarnd ++ dotest multiroot3-4a "$testcvs -d ${CVSROOT2} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" ++ cd CVSROOT ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config ++ dotest multiroot3-4b "$testcvs -d ${CVSROOT2} -q ci -m workaround-LogHistory" "" \ ++".*/CVSROOT/config,v <-- config ++new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* ++$SPROG commit: Rebuilding administrative file database" ++ cd ../..; rm -r wrkarnd + dotest multiroot3-5 "${testcvs} -d ${CVSROOT2} -q co -l ." "" + mkdir dir2 + +@@ -30037,7 +30259,7 @@ + echo "D/dir2////" >>CVS/Entries + + dotest multiroot3-7 "${testcvs} add dir2" \ +-"Directory ${TESTDIR}/root2/dir2 added to the repository" ++"Directory ${TESTDIR}/root2/dir2 put under version control" + + touch dir1/file1 dir2/file2 + if $remote; then +@@ -30143,10 +30365,21 @@ + + mkdir 1; cd 1 + dotest multiroot4-1 "${testcvs} -d ${CVSROOT1} init" "" ++ # remove automatically-created LogHistory (see above) ++ mkdir wrkarnd; cd wrkarnd ++ dotest multiroot4-1a "$testcvs -d ${CVSROOT1} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" ++ cd CVSROOT ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config ++ dotest multiroot4-1b "$testcvs -d ${CVSROOT1} -q ci -m workaround-LogHistory" "" \ ++".*/CVSROOT/config,v <-- config ++new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* ++$SPROG commit: Rebuilding administrative file database" ++ cd ../..; rm -r wrkarnd + dotest multiroot4-2 "${testcvs} -d ${CVSROOT1} -q co -l ." "" + mkdir dircom + dotest multiroot4-3 "${testcvs} add dircom" \ +-"Directory ${TESTDIR}/root1/dircom added to the repository" ++"Directory ${TESTDIR}/root1/dircom put under version control" + cd dircom + touch file1 + dotest multiroot4-4 "${testcvs} add file1" \ +@@ -30158,10 +30391,21 @@ + cd ../.. + mkdir 2; cd 2 + dotest multiroot4-6 "${testcvs} -d ${CVSROOT2} init" "" ++ # remove automatically-created LogHistory (see above) ++ mkdir wrkarnd; cd wrkarnd ++ dotest multiroot4-6a "$testcvs -d ${CVSROOT2} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" ++ cd CVSROOT ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config ++ dotest multiroot4-6b "$testcvs -d ${CVSROOT2} -q ci -m workaround-LogHistory" "" \ ++".*/CVSROOT/config,v <-- config ++new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* ++$SPROG commit: Rebuilding administrative file database" ++ cd ../..; rm -r wrkarnd + dotest multiroot4-7 "${testcvs} -d ${CVSROOT2} -q co -l ." "" + mkdir dircom + dotest multiroot4-8 "${testcvs} add dircom" \ +-"Directory ${TESTDIR}/root2/dircom added to the repository" ++"Directory ${TESTDIR}/root2/dircom put under version control" + cd dircom + touch file2 + dotest multiroot4-9 "${testcvs} add file2" \ +@@ -30179,7 +30423,7 @@ + # repository) and so on would also look the same. + mkdir sdir2 + dotest multiroot4-11 "${testcvs} -d ${CVSROOT2} add sdir2" \ +-"Directory ${TESTDIR}/root2/dircom/sdir2 added to the repository" ++"Directory ${TESTDIR}/root2/dircom/sdir2 put under version control" + + dotest multiroot4-12 "${testcvs} -q update" "" + cd .. +@@ -30208,7 +30452,7 @@ + dotest rmroot-setup-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest rmroot-setup-2 "${testcvs} add first-dir" \ +-"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/first-dir put under version control" + cd first-dir + touch file1 file2 + dotest rmroot-setup-3 "${testcvs} add file1 file2" \ +@@ -30383,7 +30627,7 @@ + willfail: :whocares + EOF + dotest_fail pserver-3 "$servercvs pserver" \ +-"error 0 Server configuration missing --allow-root in inetd.conf" <<EOF ++"error 0 Server configuration missing --allow-root or --allow-root-regexp in inetd.conf" <<EOF + BEGIN AUTH REQUEST + $CVSROOT_DIRNAME + testme +@@ -30391,6 +30635,26 @@ + END AUTH REQUEST + EOF + ++ regexp='^'`dirname ${CVSROOT_DIRNAME}`'/[^/]+$' ++ dotest pserver-3b "${testcvs} --allow-root-regexp=$regexp pserver" \ ++"I LOVE YOU" <<EOF ++BEGIN AUTH REQUEST ++${CVSROOT_DIRNAME} ++testme ++Ay::'d ++END AUTH REQUEST ++EOF ++ ++ regexp='^'`dirname ${CVSROOT_DIRNAME}`'/[^/]+$' ++ dotest_fail pserver-3c "${testcvs} --allow-root-regexp=$regexp pserver" \ ++"$CPROG \\[pserver aborted\\]: ${CVSROOT_DIRNAME}/subdir: no such repository" <<EOF ++BEGIN AUTH REQUEST ++${CVSROOT_DIRNAME}/subdir ++testme ++Ay::'d ++END AUTH REQUEST ++EOF ++ + # Confirm that not sending a newline during auth cannot constitute + # a denial-of-service attack. This assumes that PATH_MAX is less + # than 65536 bytes. If PATH_MAX is larger than 65535 bytes, this +@@ -30925,7 +31189,7 @@ + EOF + + dotest server-9 "${servercvs} server" \ +-"E Protocol error; misformed Notify request ++"E Protocol error; malformed Notify request + error " <<EOF + Root ${TESTDIR}/crerepos + Directory . +@@ -31033,6 +31297,8 @@ + EOF + echo THIS-CONFIG-OPTION-IS-BAD=XXX >$TESTDIR/newconfig + dotest_fail server-20 "$testcvs server -c $TESTDIR/newconfig" \ ++"Usage: cvs server ++Normally invoked by a cvs client on a remote machine." \ + "E $SPROG \[server aborted\]: Invalid path to config file specified: \`$TESTDIR/newconfig'" <<EOF + Root $TESTDIR/crerepos + Directory . +@@ -31041,6 +31307,8 @@ + EOF + dotest_fail server-21 \ + "$testcvs server -c /etc/cvs/this-shouldnt-exist" \ ++"Usage: cvs server ++Normally invoked by a cvs client on a remote machine." \ + "E $SPROG \[server aborted\]: Failed to resolve path: \`/etc/cvs/this-shouldnt-exist': No such file or directory" <<EOF + Root $TESTDIR/crerepos + Directory . +@@ -31101,7 +31369,7 @@ + noop + EOF + +- dotest 2-3 "${servercvs} server" \ ++ dotest server2-3 "${servercvs} server" \ + "E protocol error: directory '${TESTDIR}' not within root '${CVSROOT_DIRNAME}' + error " <<EOF + Root ${CVSROOT_DIRNAME} +@@ -31123,6 +31391,20 @@ + Unchanged foo/bar + noop + EOF ++ ++ dotest server2-5 \ ++"${servercvs} --allow-root=${CVSROOT_DIRNAME}.bad server" \ ++"E Bad root ${CVSROOT_DIRNAME} ++error " <<EOF ++Root ${CVSROOT_DIRNAME} ++noop ++EOF ++ dotest server2-6 \ ++"${servercvs} --allow-root=${CVSROOT_DIRNAME} server" \ ++"ok" <<EOF ++Root ${CVSROOT_DIRNAME} ++noop ++EOF + servercvs=$save_servercvs + fi + ;; +@@ -31301,7 +31583,7 @@ + # + # Incidentally, I can reproduce this behavior with Linux 2.4.20 and + # Bash 2.05 or Bash 2.05b. +- sleep 1 ++ sleep 2 + dotest_fail client-10 "$testcvs update" \ + "$CPROG update: Server attempted to update a file via an invalid pathname: + $CPROG \[update aborted\]: \`$HOME/.bashrc'\." +@@ -31322,7 +31604,7 @@ + echo "ok" + cat >/dev/null + EOF +- sleep 1 ++ sleep 2 + dotest_fail client-11 "$testcvs update" \ + "$CPROG \[update aborted\]: patch original file \./\.bashrc does not exist" + +@@ -31342,7 +31624,7 @@ + echo "ok" + cat >/dev/null + EOF +- sleep 1 ++ sleep 2 + dotest_fail client-12 "$testcvs update" \ + "$CPROG update: Server attempted to update a file via an invalid pathname: + $CPROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\." +@@ -31362,7 +31644,7 @@ + echo "ok" + cat >/dev/null + EOF +- sleep 1 ++ sleep 2 + dotest_fail client-13 "$testcvs update" \ + "$CPROG update: Server attempted to update a file via an invalid pathname: + $CPROG \[update aborted\]: \`$HOME/.bashrc'\." +@@ -31382,7 +31664,7 @@ + echo "ok" + cat >/dev/null + EOF +- sleep 1 ++ sleep 2 + dotest_fail client-14 "$testcvs update" \ + "$CPROG update: Server attempted to update a file via an invalid pathname: + $CPROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\." +@@ -31402,7 +31684,7 @@ + echo "ok" + cat >/dev/null + EOF +- sleep 1 ++ sleep 2 + dotest_fail client-15 "$testcvs update" \ + "$CPROG update: Server attempted to update a file via an invalid pathname: + $CPROG \[update aborted\]: \`$HOME/.bashrc'\." +@@ -31422,7 +31704,7 @@ + echo "ok" + cat >/dev/null + EOF +- sleep 1 ++ sleep 2 + dotest_fail client-16 "$testcvs update" \ + "$CPROG update: Server attempted to update a file via an invalid pathname: + $CPROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\." +@@ -31446,7 +31728,7 @@ + echo "ok" + cat >/dev/null + EOF +- sleep 1 ++ sleep 2 + dotest_fail client-18 "$testcvs update" \ + "$CPROG \[update aborted\]: protocol error: Copy-file tried to specify directory" + +@@ -31459,7 +31741,7 @@ + # Check that the client detects redirect loops. + cat >$TESTDIR/serveme <<EOF + #!$TESTSHELL +-echo "Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set Gssapi-authenticate expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version" ++echo "Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set Gssapi-authenticate expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version suck" + echo "ok" + echo "Redirect $CVSROOT" + +@@ -31467,7 +31749,7 @@ + cat >/dev/null + EOF + echo newstuff >file1 +- sleep 1 ++ sleep 2 + dotest_fail client-20 "$testcvs ci" \ + "$CPROG commit: Examining \. + $CPROG \[commit aborted\]: \`Redirect' loop detected\. Server misconfiguration$QUESTION" +@@ -31709,7 +31991,7 @@ + cd second + mkdir otherdir + dotest template-add-1 "${testcvs} add otherdir" \ +-"Directory ${CVSROOT_DIRNAME}/second/otherdir added to the repository" ++"Directory ${CVSROOT_DIRNAME}/second/otherdir put under version control" + if $remote; then + dotest template-add-2r \ + "cmp otherdir/CVS/Template ${TESTDIR}/template/temp.def" '' +@@ -31845,6 +32127,7 @@ + SECONDARY_CVSROOT_save=$SECONDARY_CVSROOT + SECONDARY_CVSROOT_DIRNAME=$TESTDIR/writeproxy_cvsroot + SECONDARY_CVSROOT=`newroot $SECONDARY_CVSROOT_DIRNAME` ++ write_secondary_wrapper + + # Initialize the primary repository + dotest writeproxy-init-1 "$testcvs -d$PRIMARY_CVSROOT init" +@@ -31856,6 +32139,10 @@ + ALL (cat >/dev/null; echo %R) >$TESTDIR/referrer + ALL $RSYNC -gopr --delete $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME + EOF ++ # remove automatically-created LogHistory to work around the fact ++ # that we see both writeproxy and primary config here ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config + cat >>config <<EOF + PrimaryServer=$PRIMARY_CVSROOT + EOF +@@ -31868,7 +32155,7 @@ + save_CVS_SERVER=$CVS_SERVER + ln -s $PRIMARY_CVSROOT_DIRNAME $TESTDIR/primary_link + dotest writeproxy-0 "$CVS_SERVER server" \ +-"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version ++"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version suck + ok + ok + ok" \ +@@ -32021,6 +32308,7 @@ + PRIMARY_CVSROOT=$PRIMARY_CVSROOT_save + SECONDARY_CVSROOT_DIRNAME=$SECONDARY_CVSROOT_DIRNAME_save + SECONDARY_CVSROOT=$SECONDARY_CVSROOT_save ++ write_secondary_wrapper + ;; + + +@@ -32054,10 +32342,11 @@ + PRIMARY_CVSROOT=`newroot $PRIMARY_CVSROOT_DIRNAME` + SECONDARY_CVSROOT_DIRNAME_save=$SECONDARY_CVSROOT_DIRNAME + SECONDARY_CVSROOT_DIRNAME=$TESTDIR/writeproxy_cvsroot ++ write_secondary_wrapper + + # Initialize the primary repository + dotest writeproxy-noredirect-init-1 \ +-"$testcvs -d'$PRIMARY_CVSROOT' init" ++"$testcvs -d'$PRIMARY_CVSROOT_DIRNAME' init" + mkdir writeproxy-noredirect; cd writeproxy-noredirect + mkdir primary; cd primary + dotest writeproxy-noredirect-init-2 \ +@@ -32066,6 +32355,9 @@ + cat >>loginfo <<EOF + ALL $RSYNC -gopr --delete $PRIMARY_CVSROOT_DIRNAME/ $SECONDARY_CVSROOT_DIRNAME + EOF ++ # remove automatically-created LogHistory (see above) ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config + cat >>config <<EOF + PrimaryServer=$PRIMARY_CVSROOT + EOF +@@ -32088,7 +32380,7 @@ + + # No need to check the PID of the last client since we are testing with + # Redirect disabled. +-proot_arg="--allow-root $SECONDARY_CVSROOT_DIRNAME" ++proot_arg="--allow-root ${PRIMARY_CVSROOT##*:} --allow-root $SECONDARY_CVSROOT_DIRNAME" + exec $servercvs \$proot_arg "\$@" + EOF + cat <<EOF >$TESTDIR/writeproxy-primary-wrapper +@@ -32152,7 +32444,7 @@ + mv $TESTDIR/save-root $PRIMARY_CVSROOT_DIRNAME + + dotest writeproxy-noredirect-5 "$CVS_SERVER server" \ +-"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version ++"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version suck + ok + ok + ok +@@ -32184,7 +32476,7 @@ + cd firstdir + echo now you see me >file1 + dotest writeproxy-noredirect-6 "$CVS_SERVER server" \ +-"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version ++"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version suck + ok + ok + ok +@@ -32214,7 +32506,7 @@ + echo /file1/0/dummy+timestamp// >>CVS/Entries + + dotest writeproxy-noredirect-7 "$CVS_SERVER server" \ +-"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version ++"Valid-requests Root Valid-responses valid-requests Command-prep Referrer Repository Directory Relative-directory Max-dotdot Static-directory Sticky Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Hostname LocalDir Questionable Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set ${DOTSTAR}expand-modules ci co update diff log rlog list rlist global-list-quiet ls add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors edit init annotate rannotate noop version suck + ok + ok + Mode u=rw,g=rw,o=r +@@ -32287,6 +32579,7 @@ + PRIMARY_CVSROOT_DIRNAME=$PRIMARY_CVSROOT_DIRNAME_save + PRIMARY_CVSROOT=$PRIMARY_CVSROOT_save + SECONDARY_CVSROOT_DIRNAME=$SECONDARY_CVSROOT_DIRNAME_save ++ write_secondary_wrapper + ;; + + +@@ -32327,9 +32620,10 @@ + + # Set new roots. + PRIMARY_CVSROOT_DIRNAME=$TESTDIR/primary_cvsroot +- PRIMARY_CVSROOT=:ext:$host$PRIMARY_CVSROOT_DIRNAME ++ PRIMARY_CVSROOT=:ext:$host:$PRIMARY_CVSROOT_DIRNAME + SECONDARY_CVSROOT_DIRNAME=$TESTDIR/writeproxy_cvsroot +- SECONDARY_CVSROOT=":ext;Redirect=yes:$host$SECONDARY_CVSROOT_DIRNAME" ++ SECONDARY_CVSROOT=":ext;Redirect=yes:$host:$SECONDARY_CVSROOT_DIRNAME" ++ write_secondary_wrapper + + # Initialize the primary repository + dotest writeproxy-ssh-init-1 "$testcvs -d$PRIMARY_CVSROOT init" +@@ -32343,6 +32637,9 @@ + cat >>loginfo <<EOF + ALL echo Referrer=%R; cat >/dev/null + EOF ++ # remove automatically-created LogHistory (see above) ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config + cat >>config <<EOF + PrimaryServer=$PRIMARY_CVSROOT + EOF +@@ -32391,6 +32688,7 @@ + PRIMARY_CVSROOT=$PRIMARY_CVSROOT_save + SECONDARY_CVSROOT_DIRNAME=$SECONDARY_CVSROOT_DIRNAME_save + SECONDARY_CVSROOT=$SECONDARY_CVSROOT_save ++ write_secondary_wrapper + ;; + + +@@ -32426,9 +32724,10 @@ + + # Set new roots. + PRIMARY_CVSROOT_DIRNAME=$TESTDIR/primary_cvsroot +- PRIMARY_CVSROOT=:ext:$host$PRIMARY_CVSROOT_DIRNAME ++ PRIMARY_CVSROOT=:ext:$host:$PRIMARY_CVSROOT_DIRNAME + SECONDARY_CVSROOT_DIRNAME=$TESTDIR/writeproxy_cvsroot +- SECONDARY_CVSROOT=":ext;Redirect=no:$host$PRIMARY_CVSROOT_DIRNAME" ++ SECONDARY_CVSROOT=":ext;Redirect=no:$host:$PRIMARY_CVSROOT_DIRNAME" ++ write_secondary_wrapper + + # Initialize the primary repository + dotest writeproxy-ssh-noredirect-init-1 \ +@@ -32444,6 +32743,9 @@ + cat >>loginfo <<EOF + ALL echo Referrer=%R; cat >/dev/null + EOF ++ # remove automatically-created LogHistory (see above) ++ sed -e '/^LogHistory/d' <config >tmpconfig ++ mv tmpconfig config + cat >>config <<EOF + PrimaryServer=$PRIMARY_CVSROOT + EOF +@@ -32463,8 +32765,8 @@ + + # No need to check the PID of the last client since we are testing with + # Redirect disabled. +-proot_arg="--allow-root=$SECONDARY_CVSROOT_DIRNAME" +-exec $CVS_SERVER \$proot_arg "\$@" ++proot_arg="--allow-root ${PRIMARY_CVSROOT##*:} --allow-root=$SECONDARY_CVSROOT_DIRNAME" ++exec $CVS_SERVER_secondary_wrapper_orig \$proot_arg "\$@" + EOF + cat <<EOF >$TESTDIR/writeproxy-primary-wrapper + #! $TESTSHELL +@@ -32517,6 +32819,7 @@ + PRIMARY_CVSROOT=$PRIMARY_CVSROOT_save + SECONDARY_CVSROOT_DIRNAME=$SECONDARY_CVSROOT_DIRNAME_save + SECONDARY_CVSROOT=$SECONDARY_CVSROOT_save ++ write_secondary_wrapper + rm $TESTDIR/writeproxy-secondary-wrapper \ + $TESTDIR/writeproxy-primary-wrapper + CVS_SERVER=$CVS_SERVER_save +@@ -32836,7 +33139,7 @@ + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +-Directory ${CVSROOT_DIRNAME}/trace/subdir added to the repository" \ ++Directory ${CVSROOT_DIRNAME}/trace/subdir put under version control" \ + " + *callerdat=${PFMT}, argc=1, argv=${PFMT}, + *direntproc=${PFMT}, dirleavproc=${PFMT}, +@@ -32868,7 +33171,7 @@ + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) + *-> walklist ( list=${PFMT}, proc=${PFMT}, closure=${PFMT} ) +-${DOTSTAR}Directory ${CVSROOT_DIRNAME}/trace/subdir added to the repository ++${DOTSTAR}Directory ${CVSROOT_DIRNAME}/trace/subdir put under version control + S -> CVS_SERVER_SLEEP not set\. + S -> Lock_Cleanup() + S -> Lock_Cleanup() +@@ -35508,6 +35811,35 @@ + + + ++ suck) ++ modify_repo mkdir $CVSROOT_DIRNAME/first-dir ++ dotest suck-init-1 "$testcvs -Q co first-dir" ++ ++ cd first-dir ++ ${AWK} 'BEGIN { for (i = 64; i < 96; i++) printf "%02x %c\n", i-64, i }' \ ++ </dev/null | ${TR} '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_' \ ++ '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037' \ ++ | ${TR} 'abcdef' 'ABCDEF' >alloctet.dat ++ ${AWK} 'BEGIN { for (i = 32; i < 256; i++) printf "%02X %c\n", i, i }' \ ++ </dev/null >>alloctet.dat ++ ++ dotest suck-1 "$testcvs -Q add alloctet.dat" ++ dotest suck-2 "$testcvs -Q ci -m added" ++ ++ cd .. ++ ++ dotest suck-3 "$testcvs -Q suck first-dir/alloctet.dat >commavs" ++ echo "first-dir/alloctet.dat,v" >commavl ++ cat $CVSROOT_DIRNAME/first-dir/alloctet.dat,v >>commavl ++ dotest suck-eq "diff commavs commavl" ++ ++ dokeep ++ rm -r first-dir commavs commavl ++ modify_repo rm -rf $CVSROOT_DIRNAME/first-dir ++ ;; ++ ++ ++ + *) + echo $what is not the name of a test -- ignored + ;; +@@ -35545,7 +35877,7 @@ + if cmp $file $TESTDIR/`basename $file`-clean >/dev/null 2>&1; then + :; + else +- echo "\`$file' and \`$TESTDIR/`basename $file`-clean' differ." \ ++ echo "'$file' and '$TESTDIR/`basename $file`-clean' differ." \ + >>$LOGFILE + problem=: + fi +@@ -35599,7 +35931,7 @@ + extendedinfo="$extendedinfo)" + fi + +-echo "OK, all $passed tests passed$extendedinfo." ++echo "OK, all $passed tests passed$extendedinfo." | tee -a $LOGFILE + + # TODO: + # * Test `cvs update -d foo' (where foo does not exist). +--- cvs-1.12.13+real.orig/src/server.c ++++ cvs-1.12.13+real/src/server.c +@@ -1,12 +1,18 @@ +-/* This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2, or (at your option) +- any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. */ ++/* ++ * Copyright (C) 1986-2005 The Free Software Foundation, Inc. ++ * Copyright (c) 2005, 2010, 2011, 2013, 2016, 2017, 2021 ++ * mirabilos <m@mirbsd.org> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ + + #include "cvs.h" + +@@ -80,6 +86,13 @@ + /* for select */ + # include "xselect.h" + ++/* for TCP_NODELAY */ ++# include <netinet/tcp.h> ++ ++# ifndef S_ISSOCK ++# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) ++# endif ++ + # ifndef O_NONBLOCK + # define O_NONBLOCK O_NDELAY + # endif +@@ -497,6 +510,7 @@ + + /* Allocate SIZE bytes for pending_error_text and return nonzero + if we could do it. */ ++static size_t alloc_pending_sz; + static inline int + alloc_pending_internal (char **dest, size_t size) + { +@@ -506,6 +520,7 @@ + pending_error = ENOMEM; + return 0; + } ++ alloc_pending_sz = size; + return 1; + } + +@@ -539,8 +554,8 @@ + + + +-static int +-supported_response (char *name) ++int ++supported_response (const char *name) + { + struct response *rs; + +@@ -677,6 +692,9 @@ + */ + static pid_t command_pid; + ++static void outbuf_memory_error (struct buffer *) ++ __attribute__((__noreturn__)); ++ + static void + outbuf_memory_error (struct buffer *buf) + { +@@ -700,6 +718,8 @@ + } + + ++static void input_memory_error (struct buffer *) ++ __attribute__((__noreturn__)); + + static void + input_memory_error (struct buffer *buf) +@@ -779,7 +799,7 @@ + if (!ISABSOLUTE (arg)) + { + if (alloc_pending (80 + strlen (arg))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Root %s must be an absolute pathname", arg); + return; + } +@@ -794,7 +814,7 @@ + if (current_parsed_root != NULL) + { + if (alloc_pending (80 + strlen (arg))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Protocol error: Duplicate Root request, for %s", arg); + return; + } +@@ -815,7 +835,7 @@ + /* The explicitness is to aid people who are writing clients. + I don't see how this information could help an + attacker. */ +- sprintf (pending_error_text, "\ ++ snprintf(pending_error_text, alloc_pending_sz, "\ + E Protocol error: Root says \"%s\" but pserver says \"%s\"", + current_parsed_root->directory, Pserver_Repos); + return; +@@ -823,6 +843,14 @@ + } + # endif + ++ if (root_allow_used() && !root_allow_ok(arg)) ++ { ++ if (alloc_pending (80 + strlen (arg))) ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E Bad root %s", arg); ++ return; ++ } ++ + /* For pserver, this will already have happened, and the call will do + nothing. But for rsh, we need to do it now. */ + config = get_root_allow_config (current_parsed_root->directory, +@@ -865,7 +893,7 @@ + if (!ISABSOLUTE (get_cvs_tmp_dir ())) + { + if (alloc_pending (80 + strlen (get_cvs_tmp_dir ()))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Value of %s for TMPDIR is not absolute", + get_cvs_tmp_dir ()); + +@@ -925,7 +953,7 @@ + if (status) + { + if (alloc_pending (80 + strlen (server_temp_dir))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E can't create temporary directory %s", + server_temp_dir); + pending_error = status; +@@ -935,7 +963,7 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (server_temp_dir))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E cannot change permissions on temporary directory %s", + server_temp_dir); + pending_error = save_errno; +@@ -945,7 +973,7 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (server_temp_dir))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E cannot change to temporary directory %s", + server_temp_dir); + pending_error = save_errno; +@@ -976,7 +1004,7 @@ + + if (forced && !quiet + && alloc_pending_warning (120 + strlen (program_name))) +- sprintf (pending_warning_text, ++ snprintf(pending_warning_text, alloc_pending_sz, + "E %s server: Forcing compression level %d (allowed: %d <= z <= %d).", + program_name, gzip_level, config->MinCompressionLevel, + config->MaxCompressionLevel); +@@ -995,7 +1023,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (path))) +- sprintf (pending_error_text, "E Cannot access %s", path); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E Cannot access %s", path); + pending_error = save_errno; + } + free (path); +@@ -1060,7 +1089,7 @@ + if (!ISABSOLUTE (repos)) + { + if (alloc_pending (repos_len + 80)) +- sprintf (pending_error_text, "\ ++ snprintf(pending_error_text, alloc_pending_sz, "\ + E protocol error: %s is not absolute", repos); + return 1; + } +@@ -1072,7 +1101,7 @@ + if (alloc_pending (strlen (current_parsed_root->directory) + + strlen (repos) + + 80)) +- sprintf (pending_error_text, "\ ++ snprintf(pending_error_text, alloc_pending_sz, "\ + E protocol error: directory '%s' not within root '%s'", + repos, current_parsed_root->directory); + return 1; +@@ -1099,7 +1128,7 @@ + { + if (alloc_pending (strlen (file) + + 80)) +- sprintf (pending_error_text, "\ ++ snprintf(pending_error_text, alloc_pending_sz, "\ + E protocol error: directory '%s' not within current directory", + file); + return 1; +@@ -1168,7 +1197,7 @@ + if (ISABSOLUTE (dir)) + { + if (alloc_pending (80 + strlen (dir))) +- sprintf ( pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E absolute pathnames invalid for server (specified `%s')", + dir); + return; +@@ -1176,7 +1205,7 @@ + if (pathname_levels (dir) > max_dotdot_limit) + { + if (alloc_pending (80 + strlen (dir))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E protocol error: `%s' has too many ..", dir); + return; + } +@@ -1191,7 +1220,7 @@ + && dir[dir_len - 1] == '/') + { + if (alloc_pending (80 + dir_len)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E protocol error: invalid directory syntax in %s", dir); + return; + } +@@ -1222,7 +1251,8 @@ + && status != EEXIST) + { + if (alloc_pending (80 + strlen (gDirname))) +- sprintf (pending_error_text, "E cannot mkdir %s", gDirname); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot mkdir %s", gDirname); + pending_error = status; + return; + } +@@ -1237,7 +1267,8 @@ + if (status != 0) + { + if (alloc_pending (80 + strlen (gDirname))) +- sprintf (pending_error_text, "E cannot create_adm_p %s", gDirname); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot create_adm_p %s", gDirname); + pending_error = status; + return; + } +@@ -1246,7 +1277,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (gDirname))) +- sprintf (pending_error_text, "E cannot change to %s", gDirname); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot change to %s", gDirname); + pending_error = save_errno; + return; + } +@@ -1258,7 +1290,7 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (gDirname) + strlen (CVSADM))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E cannot mkdir %s/%s", gDirname, CVSADM); + pending_error = save_errno; + return; +@@ -1274,7 +1306,7 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (gDirname) + strlen (CVSADM_REP))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E cannot open %s/%s", gDirname, CVSADM_REP); + pending_error = save_errno; + return; +@@ -1283,7 +1315,7 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (gDirname) + strlen (CVSADM_REP))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E error writing %s/%s", gDirname, CVSADM_REP); + pending_error = save_errno; + fclose (f); +@@ -1301,7 +1333,7 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (gDirname) + strlen (CVSADM_REP))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E error writing %s/%s", gDirname, CVSADM_REP); + pending_error = save_errno; + fclose (f); +@@ -1312,7 +1344,7 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (gDirname) + strlen (CVSADM_REP))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E error writing %s/%s", gDirname, CVSADM_REP); + pending_error = save_errno; + fclose (f); +@@ -1322,7 +1354,7 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (gDirname) + strlen (CVSADM_REP))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E error closing %s/%s", gDirname, CVSADM_REP); + pending_error = save_errno; + return; +@@ -1334,7 +1366,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (CVSADM_ENT))) +- sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot open %s", CVSADM_ENT); + pending_error = save_errno; + return; + } +@@ -1342,7 +1375,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (CVSADM_ENT))) +- sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot close %s", CVSADM_ENT); + pending_error = save_errno; + return; + } +@@ -1353,13 +1387,13 @@ + static void + serve_repository (char *arg) + { ++ static const char msg[] = "E Repository request is obsolete; aborted"; + # ifdef PROXY_SUPPORT + assert (!proxy_log); + # endif /* PROXY_SUPPORT */ + + if (alloc_pending (80)) +- strcpy (pending_error_text, +- "E Repository request is obsolete; aborted"); ++ memcpy(pending_error_text, msg, sizeof(msg)); + return; + } + +@@ -1454,7 +1488,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (CVSADM_ENTSTAT))) +- sprintf (pending_error_text, "E cannot open %s", CVSADM_ENTSTAT); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot open %s", CVSADM_ENTSTAT); + pending_error = save_errno; + return; + } +@@ -1462,7 +1497,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (CVSADM_ENTSTAT))) +- sprintf (pending_error_text, "E cannot close %s", CVSADM_ENTSTAT); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot close %s", CVSADM_ENTSTAT); + pending_error = save_errno; + return; + } +@@ -1486,7 +1522,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (CVSADM_TAG))) +- sprintf (pending_error_text, "E cannot open %s", CVSADM_TAG); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot open %s", CVSADM_TAG); + pending_error = save_errno; + return; + } +@@ -1494,7 +1531,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (CVSADM_TAG))) +- sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot write to %s", CVSADM_TAG); + pending_error = save_errno; + return; + } +@@ -1502,7 +1540,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (CVSADM_TAG))) +- sprintf (pending_error_text, "E cannot close %s", CVSADM_TAG); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot close %s", CVSADM_TAG); + pending_error = save_errno; + return; + } +@@ -1565,7 +1604,8 @@ + { + int save_errno = errno; + if (alloc_pending (40)) +- strcpy (pending_error_text, "E unable to write"); ++ memcpy(pending_error_text, "E unable to write", ++ sizeof("E unable to write")); + pending_error = save_errno; + + /* Read and discard the file data. */ +@@ -1604,7 +1644,8 @@ + { + int save_errno = errno; + if (alloc_pending (40 + strlen (arg))) +- sprintf (pending_error_text, "E cannot open %s", arg); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot open %s", arg); + pending_error = save_errno; + return; + } +@@ -1675,7 +1716,7 @@ + if (gunzip_and_write (fd, file, (unsigned char *) filebuf, size)) + { + if (alloc_pending (80)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E aborting due to compression error"); + } + free (filebuf); +@@ -1700,7 +1741,8 @@ + { + int save_errno = errno; + if (alloc_pending (40 + strlen (arg))) +- sprintf (pending_error_text, "E cannot close %s", arg); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot close %s", arg); + pending_error = save_errno; + return; + } +@@ -1763,7 +1805,7 @@ + * the end of the string, so just exit. + */ + if (alloc_pending (80)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Malformed Entry encountered."); + return; + } +@@ -1807,7 +1849,7 @@ + if (kopt != NULL) + { + if (alloc_pending (strlen (name) + 80)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E protocol error: both Kopt and Entry for %s", + arg); + free (kopt); +@@ -1935,7 +1977,7 @@ + + if (read_size < 0 && alloc_pending (80)) + { +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E client sent invalid (negative) file size"); + return; + } +@@ -1999,7 +2041,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (arg))) +- sprintf (pending_error_text, "E cannot utime %s", arg); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot utime %s", arg); + pending_error = save_errno; + free (mode_text); + return; +@@ -2013,7 +2056,7 @@ + if (status) + { + if (alloc_pending (40 + strlen (arg))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E cannot change mode for %s", arg); + pending_error = status; + return; +@@ -2077,7 +2120,7 @@ + * the end of the string, so just exit. + */ + if (alloc_pending (80)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Malformed Entry encountered."); + return; + } +@@ -2175,7 +2218,7 @@ + if (!cp || *cp != '/') + { + if (alloc_pending (80)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E protocol error: Malformed Entry"); + return; + } +@@ -2217,7 +2260,7 @@ + if (kopt != NULL) + { + if (alloc_pending (80 + strlen (arg))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E protocol error: duplicate Kopt request: %s", arg); + return; + } +@@ -2230,7 +2273,7 @@ + if (strlen (arg) > 10) + { + if (alloc_pending (80 + strlen (arg))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E protocol error: invalid Kopt request: %s", arg); + return; + } +@@ -2261,7 +2304,7 @@ + if (checkin_time_valid) + { + if (alloc_pending (80 + strlen (arg))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E protocol error: duplicate Checkin-time request: %s", + arg); + return; +@@ -2270,7 +2313,8 @@ + if (!get_date (&t, arg, NULL)) + { + if (alloc_pending (80 + strlen (arg))) +- sprintf (pending_error_text, "E cannot parse date %s", arg); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot parse date %s", arg); + return; + } + +@@ -2305,7 +2349,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (CVSADM_ENT))) +- sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot open %s", CVSADM_ENT); + pending_error = save_errno; + } + } +@@ -2317,7 +2362,7 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen(CVSADM_ENT))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E cannot write to %s", CVSADM_ENT); + pending_error = save_errno; + } +@@ -2332,7 +2377,8 @@ + { + int save_errno = errno; + if (alloc_pending (80 + strlen (CVSADM_ENT))) +- sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E cannot close %s", CVSADM_ENT); + pending_error = save_errno; + } + } +@@ -2350,6 +2396,7 @@ + bool *pre = closure; + + /* %c = cvs_cmd_name ++ * %I = commit ID + * %p = shortrepos + * %r = repository + */ +@@ -2367,6 +2414,7 @@ + # endif /* SUPPORT_OLD_INFO_FMT_STRINGS */ + filter, + "c", "s", cvs_cmd_name, ++ "I", "s", global_session_id, + "R", "s", referrer ? referrer->original : "NONE", + "p", "s", ".", + "r", "s", current_parsed_root->directory, +@@ -2753,7 +2801,7 @@ + { + # endif /* PROXY_SUPPORT */ + if (alloc_pending (160) + strlen (program_name)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E This CVS server does not support disconnected `%s edit'. For now, remove all `%s' files in your workspace and try your command again.", + program_name, CVSADM_NOTIFY); + return; +@@ -2869,8 +2917,8 @@ + error: + pending_error = 0; + if (alloc_pending (80)) +- strcpy (pending_error_text, +- "E Protocol error; misformed Notify request"); ++ snprintf(pending_error_text, alloc_pending_sz, ++ "E Protocol error; malformed Notify request"); + if (data != NULL) + free (data); + if (new != NULL) +@@ -2987,7 +3035,7 @@ + if (argument_count >= 10000) + { + if (alloc_pending (80)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Protocol error: too many arguments"); + return; + } +@@ -3028,7 +3076,7 @@ + if (argument_count <= 1) + { + if (alloc_pending (80)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Protocol error: called argumentx without prior call to argument"); + return; + } +@@ -3061,7 +3109,7 @@ + { + error_return: + if (alloc_pending (strlen (arg) + 80)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Protocol error: bad global option %s", + arg); + return; +@@ -3238,7 +3286,7 @@ + if (gDirname == NULL) + { + if (alloc_pending (80)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Protocol error: `Directory' missing"); + return; + } +@@ -3519,7 +3567,7 @@ + * Therefore, we wish to avoid reprocessing the command since that would + * cause endless recursion. + */ +- if (isProxyServer()) ++ if ((command != version || current_parsed_root) && isProxyServer()) + { + # ifdef PROXY_SUPPORT + if (reprocessing) +@@ -3552,7 +3600,7 @@ + if (lookup_command_attribute (cmd_name) + & CVS_CMD_MODIFIES_REPOSITORY + && alloc_pending (120)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E You need a CVS client that supports the `Redirect' response for write requests to this server."); + return; + # endif /* PROXY_SUPPORT */ +@@ -3716,7 +3764,7 @@ + * Set this in .bashrc if you want to give yourself time to attach + * to the subprocess with a debugger. + */ +- if (getenv ("CVS_SERVER_SLEEP")) ++ if (getenv("CVS_SERVER_SLEEP") && *getenv("CVS_SERVER_SLEEP")) + { + int secs = atoi (getenv ("CVS_SERVER_SLEEP")); + TRACE (TRACE_DATA, "Sleeping CVS_SERVER_SLEEP (%d) seconds", secs); +@@ -3922,7 +3970,11 @@ + { + FD_SET (stderr_pipe[0], &readfds); + } +- if (protocol_pipe[0] >= 0) ++ if (protocol_pipe[0] >= 0 ++#ifdef SERVER_FLOWCONTROL ++ && !have_flowcontrolled ++#endif ++ ) + { + FD_SET (protocol_pipe[0], &readfds); + } +@@ -4621,6 +4673,14 @@ + + + static void ++serve_suck (char *arg) ++{ ++ do_cvs_command ("suck", suck); ++} ++ ++ ++ ++static void + serve_add (char *arg) + { + do_cvs_command ("add", add); +@@ -4808,7 +4868,7 @@ + if (!ISABSOLUTE (arg)) + { + if (alloc_pending (80 + strlen (arg))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E init %s must be an absolute pathname", arg); + } + # ifdef AUTH_SERVER_SUPPORT +@@ -4820,7 +4880,7 @@ + /* The explicitness is to aid people who are writing clients. + I don't see how this information could help an + attacker. */ +- sprintf (pending_error_text, "\ ++ snprintf(pending_error_text, alloc_pending_sz, "\ + E Protocol error: init says \"%s\" but pserver says \"%s\"", + arg, Pserver_Repos); + } +@@ -5237,6 +5297,7 @@ + { + free (vers->ts_user); + vers->ts_user = NULL; ++ vers->ts_user_ists = 0; + } + } + else if (scratched_file == NULL && entries_line == NULL) +@@ -5482,7 +5543,7 @@ + + if (forced && !quiet + && alloc_pending_warning (120 + strlen (program_name))) +- sprintf (pending_warning_text, ++ snprintf(pending_warning_text, alloc_pending_sz, + "E %s server: Forcing compression level %d (allowed: %d <= z <= %d).", + program_name, level, config->MinCompressionLevel, + config->MaxCompressionLevel); +@@ -5513,7 +5574,7 @@ + + if (forced && !quiet + && alloc_pending_warning (120 + strlen (program_name))) +- sprintf (pending_warning_text, ++ snprintf(pending_warning_text, alloc_pending_sz, + "E %s server: Forcing compression level %d (allowed: %d <= z <= %d).", + program_name, level, config->MinCompressionLevel, + config->MaxCompressionLevel); +@@ -5838,7 +5899,7 @@ + + if (!referrer + && alloc_pending (80 + strlen (arg))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Protocol error: Invalid Referrer: `%s'", + arg); + } +@@ -5856,7 +5917,7 @@ + /* + * Parts of this table are shared with the client code, + * but the client doesn't need to know about the handler +- * functions. ++ * functions. It likes to write to the flags field, though. + */ + + struct request requests[] = +@@ -5962,6 +6023,7 @@ + REQ_LINE("rannotate", serve_rannotate, 0), + REQ_LINE("noop", serve_noop, RQ_ROOTLESS), + REQ_LINE("version", serve_version, RQ_ROOTLESS), ++ REQ_LINE("suck", serve_suck, 0), + REQ_LINE(NULL, NULL, 0) + + #undef REQ_LINE +@@ -6271,8 +6333,12 @@ + + static const char *const server_usage[] = + { ++#ifdef ALLOW_CONFIG_OVERRIDE + "Usage: %s %s [-c config-file]\n", + "\t-c config-file\tPath to an alternative CVS config file.\n", ++#else ++ "Usage: %s %s\n", ++#endif + "Normally invoked by a cvs client on a remote machine.\n", + NULL + }; +@@ -6289,8 +6355,8 @@ + { + switch (c) + { +-#ifdef ALLOW_CONFIG_OVERRIDE + case 'c': ++#ifdef ALLOW_CONFIG_OVERRIDE + if (gConfigPath) free (gConfigPath); + gConfigPath = xstrdup (optarg); + break; +@@ -6319,7 +6385,7 @@ + * Set this in .bashrc if you want to give yourself time to attach + * to the subprocess with a debugger. + */ +- if (getenv ("CVS_PARENT_SERVER_SLEEP")) ++ if (getenv("CVS_PARENT_SERVER_SLEEP") && *getenv("CVS_PARENT_SERVER_SLEEP")) + { + int secs = atoi (getenv ("CVS_PARENT_SERVER_SLEEP")); + TRACE (TRACE_DATA, "Sleeping CVS_PARENT_SERVER_SLEEP (%d) seconds", +@@ -6433,7 +6499,7 @@ + && current_parsed_root == NULL) + { + if (alloc_pending (80)) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E Protocol error: Root request missing"); + } + else +@@ -6446,7 +6512,7 @@ + * been requested by the client. + */ + if (alloc_pending (80 + strlen (program_name))) +- sprintf (pending_error_text, ++ snprintf(pending_error_text, alloc_pending_sz, + "E %s [server aborted]: Compression must be used with this server.", + program_name); + } +@@ -6671,6 +6737,22 @@ + + extern char *crypt (const char *, const char *); + ++char *crypt_trad(const char *, const char *); ++ ++char * ++crypt_trad(const char *key, const char *setting) ++{ ++ char *rv; ++ static char buf[2]; ++ ++ if ((rv = crypt(key, setting)) == NULL) { ++ buf[0] = setting && (*setting == 'x') ? '*' : 'x'; ++ buf[1] = '\0'; ++ rv = buf; ++ } ++ ++ return (rv); ++} + + /* + * 0 means no entry found for this user. +@@ -6799,7 +6881,7 @@ + + /* Verify blank passwords directly, otherwise use crypt(). */ + if ((found_password == NULL) +- || ((strcmp (found_password, crypt (password, found_password)) ++ || ((strcmp (found_password, crypt_trad (password, found_password)) + == 0))) + { + /* Give host_user_ptr permanent storage. */ +@@ -6811,7 +6893,7 @@ + #ifdef LOG_AUTHPRIV + syslog (LOG_AUTHPRIV | LOG_NOTICE, + "password mismatch for %s in %s: %s vs. %s", username, +- repository, crypt(password, found_password), found_password); ++ repository, crypt_trad(password, found_password), found_password); + #endif + *host_user_ptr = NULL; + retval = 2; +@@ -6887,7 +6969,7 @@ + static int + check_pam_password (char **username, char *password) + { +- int retval, err; ++ int retval; + struct pam_conv conv = { cvs_pam_conv, 0 }; + char *pam_stage = "start"; + +@@ -6930,7 +7012,7 @@ + + return retval == PAM_SUCCESS; /* indicate success */ + } +-#endif ++#else /* !HAVE_PAM */ + + static int + check_system_password (char *username, char *password) +@@ -6976,14 +7058,14 @@ + if (*found_passwd) + { + /* user exists and has a password */ +- if (strcmp (found_passwd, crypt (password, found_passwd)) == 0) ++ if (strcmp (found_passwd, crypt_trad (password, found_passwd)) == 0) + return 1; + else + { + #ifdef LOG_AUTHPRIV + syslog (LOG_AUTHPRIV | LOG_NOTICE, + "password mismatch for %s: %s vs. %s", username, +- crypt(password, found_passwd), found_passwd); ++ crypt_trad(password, found_passwd), found_passwd); + #endif + return 0; + } +@@ -6996,6 +7078,7 @@ + #endif + return 1; + } ++#endif /* !HAVE_PAM */ + + + +@@ -7164,8 +7247,10 @@ + if the client dies while we are waiting for input. */ + { + int on = 1; ++ struct stat sb; + +- if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, ++ if (fstat (STDIN_FILENO, &sb) == 0 && S_ISSOCK(sb.st_mode) && ++ setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, + &on, sizeof on) < 0) + { + # ifdef HAVE_SYSLOG_H +@@ -7175,6 +7260,23 @@ + } + #endif + ++#ifdef TCP_NODELAY ++ /* Avoid latency due to Nagle algorithm. */ ++ { ++ int on = 1; ++ struct stat sb; ++ ++ if (fstat (STDOUT_FILENO, &sb) == 0 && S_ISSOCK(sb.st_mode) && ++ setsockopt (STDOUT_FILENO, IPPROTO_TCP, TCP_NODELAY, ++ &on, sizeof on) < 0) ++ { ++# ifdef HAVE_SYSLOG_H ++ syslog (LOG_DAEMON | LOG_ERR, "error setting TCP_NODELAY: %m"); ++# endif /* HAVE_SYSLOG_H */ ++ } ++ } ++#endif ++ + /* Make sure the protocol starts off on the right foot... */ + pserver_read_line (&tmp, NULL); + +@@ -7317,8 +7419,10 @@ + if the client dies while we are waiting for input. */ + { + int on = 1; ++ struct stat sb; + +- if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, ++ if (fstat (STDIN_FILENO, &sb) == 0 && S_ISSOCK(sb.st_mode) && ++ setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, + (char *) &on, sizeof on) < 0) + { + # ifdef HAVE_SYSLOG_H +@@ -7328,6 +7432,23 @@ + } + #endif + ++#ifdef TCP_NODELAY ++ /* Avoid latency due to Nagle algorithm. */ ++ { ++ int on = 1; ++ struct stat sb; ++ ++ if (fstat (STDOUT_FILENO, &sb) == 0 && S_ISSOCK(sb.st_mode) && ++ setsockopt (STDOUT_FILENO, IPPROTO_TCP, TCP_NODELAY, ++ (char *) &on, sizeof on) < 0) ++ { ++# ifdef HAVE_SYSLOG_H ++ syslog (LOG_DAEMON | LOG_ERR, "error setting TCP_NODELAY: %m"); ++# endif /* HAVE_SYSLOG_H */ ++ } ++ } ++#endif ++ + status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd", + instance, &peer, &laddr, &auth, "", sched, + version); +@@ -7611,6 +7732,12 @@ + void + cvs_output (const char *str, size_t len) + { ++ cvs_output_ex (str, len, 'M'); ++} ++ ++void ++cvs_output_ex (const char *str, size_t len, int buftag) ++{ + if (len == 0) + len = strlen (str); + #ifdef SERVER_SUPPORT +@@ -7619,7 +7746,7 @@ + if (buf_to_net) + { + buf_output (saved_output, str, len); +- buf_copy_lines (buf_to_net, saved_output, 'M'); ++ buf_copy_lines (buf_to_net, saved_output, buftag); + } + # if HAVE_SYSLOG_H + else +@@ -7634,7 +7761,7 @@ + if (protocol) + { + buf_output (saved_output, str, len); +- buf_copy_lines (protocol, saved_output, 'M'); ++ buf_copy_lines (protocol, saved_output, buftag); + buf_send_counted (protocol); + } + # if HAVE_SYSLOG_H +--- cvs-1.12.13+real.orig/src/server.h ++++ cvs-1.12.13+real/src/server.h +@@ -1,3 +1,5 @@ ++/* $MirOS: src/gnu/usr.bin/cvs/src/server.h,v 1.2 2017/11/18 23:04:57 tg Exp $ */ ++ + /* + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. + * +@@ -161,7 +163,7 @@ + struct request + { + /* Name of the request. */ +- char *name; ++ const char *name; + + #ifdef SERVER_SUPPORT + /* +--- cvs-1.12.13+real.orig/src/status.c ++++ cvs-1.12.13+real/src/status.c +@@ -213,8 +213,11 @@ + cvs_output (" Working revision:\t", 0); + cvs_output (vers->vn_user, 0); + +- /* Only add the UTC timezone if there is a time to use. */ +- if (!server_active && strlen (vers->ts_rcs) > 0) ++ /* Only add the UTC timezone if there is a time to use. ++ * ts_rcs sometimes contains only "=" character so we check len > 1 */ ++ if (!server_active && strlen (vers->ts_rcs) > 1 && ++ /* prevent an ugly error message */ ++ strcmp(vers->ts_rcs, "Result of merge") != 0) + { + /* Convert from the asctime() format to ISO 8601 */ + char *buf; +--- cvs-1.12.13+real.orig/src/subr.c ++++ cvs-1.12.13+real/src/subr.c +@@ -1,5 +1,6 @@ + /* + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. ++ * Copyright (c) 2006, 2007, 2011, 2017, 2021 mirabilos <m@mirbsd.org> + * + * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>, + * and others. +@@ -315,8 +316,12 @@ + char *name; + + /* super-user; try getlogin() to distinguish */ +- if (((name = getlogin ()) || (name = getenv("LOGNAME")) || +- (name = getenv("USER"))) && *name) ++ name = getlogin(); ++ if (!name || !*name) ++ name = getenv("LOGNAME"); ++ if (!name || !*name) ++ name = getenv("USER"); ++ if (name && *name) + { + cache = xstrdup (name); + return cache; +@@ -795,7 +800,21 @@ + return buf; + } + ++static time_t ++sleep_past_chk(struct timespec *ts) ++{ ++#ifdef HAVE_GETTIMEOFDAY ++ struct timeval tv; + ++ gettimeofday(&tv, NULL); ++ ts->tv_sec = tv.tv_sec; ++ ts->tv_nsec = tv.tv_usec * 1000; ++#else ++ ts->tv_sec = time(NULL); ++ ts->tv_nsec = 0; ++#endif ++ return (ts->tv_sec); ++} + + /* + * We can only travel forwards in time, not backwards. :) +@@ -803,41 +822,52 @@ + void + sleep_past (time_t desttime) + { +- time_t t; +- long s; +- long us; ++ struct timespec t; + +- while (time (&t) <= desttime) +- { ++ while (sleep_past_chk(&t) <= desttime) { ++ t.tv_sec = desttime - t.tv_sec; + #ifdef HAVE_GETTIMEOFDAY +- struct timeval tv; +- gettimeofday (&tv, NULL); +- if (tv.tv_sec > desttime) +- break; +- s = desttime - tv.tv_sec; +- if (tv.tv_usec > 0) +- us = 1000000 - tv.tv_usec; +- else +- { +- s++; +- us = 0; +- } ++ if (t.tv_nsec > 0) ++ t.tv_nsec = 1000000000L - t.tv_nsec; ++ else { ++ ++t.tv_sec; ++ t.tv_nsec = 0; ++ } + #else +- /* default to 20 ms increments */ +- s = desttime - t; +- us = 20000; ++ /* default to 20ms increments */ ++ t.tv_nsec = 20000000L; + #endif +- +- { +- struct timespec ts; +- ts.tv_sec = s; +- ts.tv_nsec = us * 1000; +- (void)nanosleep (&ts, NULL); ++ nanosleep(&t, NULL); + } +- } ++ ++ /* sleep another 20ms to avoid races (LP#12230) */ ++ /* so I’m not the only one whose clock can go backwards… */ ++ t.tv_sec = 0; ++ t.tv_nsec = 20000000L; ++ nanosleep(&t, NULL); + } + ++#ifdef HAVE_GETTIMEOFDAY ++/* ++ * Ensure time never travels backwards for us. :( ++ * This file is the only user of gettimeofday in all CVS, ++ * and everything else calls time always, so wrap it. ++ */ ++time_t ++time(time_t *tp) ++{ ++ register time_t t; ++ struct timeval tv; ++ static time_t lt = 0; + ++ gettimeofday(&tv, NULL); ++ t = tv.tv_sec < lt ? lt : tv.tv_sec; ++ lt = t; ++ if (tp) ++ *tp = t; ++ return (t); ++} ++#endif + + /* used to store callback data in a list indexed by the user format string + */ +@@ -1045,7 +1075,9 @@ + */ + Node *p; + struct cmdline_bindings *b; ++#ifdef SUPPORT_OLD_INFO_FMT_STRINGS + static int warned_of_deprecation = 0; ++#endif + char key[] = "?"; /* Used as temporary storage for a single + * character search string used to locate a + * hash key. +@@ -1285,7 +1317,7 @@ + dellist(&pflist); + free(b); + error (1, 0, +-"internal error: unknown integer arg size (%d)", ++"internal error: unknown integer arg size (%zd)", + length); + break; + } +@@ -1328,7 +1360,7 @@ + dellist(&pflist); + free(b); + error (1, 0, +-"internal error: unknown floating point arg size (%d)", ++"internal error: unknown floating point arg size (%zd)", + length); + break; + } +@@ -1704,7 +1736,7 @@ + doff = d - buf; + expand_string (&buf, &length, doff + strlen(outstr)); + d = buf + doff; +- strncpy(d, outstr, strlen(outstr)); ++ memcpy(d, outstr, strlen(outstr)); + d += strlen(outstr); + #ifdef SUPPORT_OLD_INFO_FMT_STRINGS + if (!onearg) +@@ -1735,7 +1767,7 @@ + doff = d - buf; + expand_string (&buf, &length, doff + strlen(srepos)); + d = buf + doff; +- strncpy(d, srepos, strlen(srepos)); ++ memcpy(d, srepos, strlen(srepos)); + d += strlen(srepos); + } + #endif /* SUPPORT_OLD_INFO_FMT_STRINGS */ +--- cvs-1.12.13+real.orig/src/suck.c ++++ cvs-1.12.13+real/src/suck.c +@@ -0,0 +1,140 @@ ++/*- ++ * Copyright (c) 2011 ++ * mirabilos <m@mirbsd.org> ++ * ++ * Provided that these terms and disclaimer and all copyright notices ++ * are retained or reproduced in an accompanying document, permission ++ * is granted to deal in this work without restriction, including un- ++ * limited rights to use, publicly perform, distribute, sell, modify, ++ * merge, give away, or sublicence. ++ * ++ * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to ++ * the utmost extent permitted by applicable law, neither express nor ++ * implied; without malicious intent or gross negligence. In no event ++ * may a licensor, author or contributor be held liable for indirect, ++ * direct, other damage, loss, or other issues arising in any way out ++ * of dealing in the work, even if advised of the possibility of such ++ * damage or existence of a defect, except proven that it results out ++ * of said person's immediate fault when using the work as intended. ++ *- ++ * Download a ,v file from the repository ++ */ ++ ++#include "cvs.h" ++ ++#ifdef HAVE_MMAP ++#include <sys/mman.h> ++ ++#ifndef MAP_FILE ++#define MAP_FILE 0 ++#endif ++ ++#ifndef MAP_FAILED ++#define MAP_FAILED ((void *)-1) ++#endif ++#endif ++ ++static const char * const suck_usage[] = { ++ "Usage: %s %s module/filename\n", ++ NULL ++}; ++ ++int ++suck(int argc, char *argv[]) ++{ ++ size_t m, n; ++ int fd; ++ char *buf, *cp, *fn; ++ struct stat sb; ++ FILE *fp; ++ RCSNode *rcs; ++ ++ if (argc != 2) ++ usage(suck_usage); ++ ++#ifdef CLIENT_SUPPORT ++ if (current_parsed_root->isremote) { ++ start_server(); ++ ++ if (!supported_request("suck")) ++ error(1, 0, "server does not support %s", "suck"); ++ ++ send_arg(argv[1]); ++ send_to_server("suck\012", 0); ++ ++ return (get_responses_and_close()); ++ } ++#endif ++ ++ /* check for ../ attack */ ++ if (pathname_levels(argv[1]) > 0) ++ error(1, 0, "path %s outside of repository", argv[1]); ++ ++ /* repo + / + module/file */ ++ cp = Xasprintf("%s/%s", current_parsed_root->directory, argv[1]); ++ ++ /* find the slash */ ++ if ((fn = cp + (last_component(cp) - cp)) == cp) ++ usage(suck_usage); ++ ++ /* repo/module + file */ ++ fn[-1] = '\0'; ++ ++ /* check if it's a valid RCS file, not /etc/passwd or somesuch */ ++ if ((rcs = RCS_parse(fn, cp)) == NULL) { ++ error(1, 0, "not a valid RCS file: %s/%s", cp, fn); ++ return (1); ++ } ++ ++ /* save the real pathname of the RCS file for later */ ++ fn = xstrdup(rcs->path); ++ ++ /* free up resources allocated until now */ ++ freercsnode(&rcs); ++ free(cp); ++ ++ /* attempt to open the file ourselves */ ++ if ((fp = CVS_FOPEN(fn, FOPEN_BINARY_READ)) == NULL) ++ error(1, errno, "Could not open RCS archive %s", fn); ++ if (fstat(fd = fileno(fp), &sb) < 0) ++ error(1, errno, "Could not stat RCS archive %s", fn); ++ ++ /*XXX this code will fail for large files */ ++ ++ /* attempt to slurp entire file into memory */ ++#ifdef HAVE_MMAP ++ buf = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); ++ if (buf == NULL || buf == MAP_FAILED) { ++ error(0, errno, "Could not map memory to RCS archive %s", fn); ++#endif ++ /* backup: just read */ ++ cp = buf = xmalloc(n = sb.st_size); ++ while (n) { ++ m = read(fd, cp, n); ++ if (m == (size_t)-1) ++ error(1, errno, ++ "Could not read RCS archive %s", fn); ++ cp += m; ++ n -= m; ++ } ++#ifdef HAVE_MMAP ++ } ++#endif ++ ++ /* write real pathname plus newline as text */ ++ cvs_output(fn + strlen(current_parsed_root->directory) + 1, 0); ++ cvs_output("\n", 1); ++ ++ /* write file content as binary */ ++ cvs_output_binary(buf, sb.st_size); ++ ++ /* release all resources allocated */ ++#ifdef HAVE_MMAP ++ munmap(buf, sb.st_size); ++#endif ++ fclose(fp); ++ free(fn); ++ ++ /* success */ ++ return (0); ++} +--- cvs-1.12.13+real.orig/src/tag.c ++++ cvs-1.12.13+real/src/tag.c +@@ -1,5 +1,6 @@ + /* + * Copyright (C) 1986-2005 The Free Software Foundation, Inc. ++ * Copyright (c) 2005, 2006, 2021 mirabilos <m@mirbsd.org> + * + * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>, + * and others. +@@ -310,6 +311,7 @@ + * %b = branch mode = "?" (delete ops - unknown) | "T" (branch) + * | "N" (not branch) + * %c = cvs_cmd_name ++ * %I = commit ID + * %p = path from $CVSROOT + * %r = path from root + * %{sVv} = attribute list = file name, old version tag will be deleted +@@ -333,6 +335,7 @@ + "b", "c", delete_flag + ? '?' : branch_mode ? 'T' : 'N', + "c", "s", cvs_cmd_name, ++ "I", "s", global_session_id, + #ifdef SERVER_SUPPORT + "R", "s", referrer ? referrer->original : "NONE", + #endif /* SERVER_SUPPORT */ +@@ -747,6 +750,7 @@ + * %b = branch mode = "?" (delete ops - unknown) | "T" (branch) + * | "N" (not branch) + * %c = cvs_cmd_name ++ * %I = commit ID + * %p = path from $CVSROOT + * %r = path from root + * %{sVv} = attribute list = file name, old version tag will be deleted +@@ -770,6 +774,7 @@ + "b", "c", delete_flag + ? '?' : branch_mode ? 'T' : 'N', + "c", "s", cvs_cmd_name, ++ "I", "s", global_session_id, + #ifdef SERVER_SUPPORT + "R", "s", referrer ? referrer->original : "NONE", + #endif /* SERVER_SUPPORT */ +@@ -902,7 +907,7 @@ + doff = d - *c->buf; + expand_string (c->buf, c->length, doff + strlen (arg)); + d = *c->buf + doff; +- strncpy (d, arg, strlen (arg)); ++ memcpy (d, arg, strlen (arg)); + d += strlen (arg); + + free (arg); +@@ -1235,14 +1240,14 @@ + else if (strcmp (version, "0") == 0) + { + if (!quiet) +- error (0, 0, "couldn't tag added but un-commited file `%s'", ++ error (0, 0, "couldn't tag added but un-committed file `%s'", + finfo->file); + goto free_vars_and_return; + } + else if (version[0] == '-') + { + if (!quiet) +- error (0, 0, "skipping removed but un-commited file `%s'", ++ error (0, 0, "skipping removed but un-committed file `%s'", + finfo->file); + goto free_vars_and_return; + } +@@ -1450,6 +1455,7 @@ + * 2. If IDB is non-NULL and val-tags cannot be opened for write. + * This allows callers to ignore the harmless inability to + * update the val-tags cache. ++ * 3. If CVSREADONLYFS is set (same as #2 above). + * false If the file could be opened and the tag is not present. + */ + static int is_in_val_tags (DBM **idb, const char *name) +@@ -1459,6 +1465,10 @@ + datum mytag; + int status; + ++ /* do nothing if we know we fail anyway */ ++ if (readonlyfs) ++ return 1; ++ + /* Casting out const should be safe here - input datums are not + * written to by the myndbm functions. + */ +@@ -1580,7 +1590,7 @@ + * we are already there, or "" if we should do a W_LOCAL recursion. + * Sorry for three cases, but the "" case is needed in case the + * working directories come from diverse parts of the repository, the +- * NULL case avoids an unneccesary chdir, and the non-NULL, non-"" ++ * NULL case avoids an unnecessary chdir, and the non-NULL, non-"" + * case is needed for checkout, where we don't want to chdir if the + * tag is found in CVSROOTADM_VALTAGS, but there is not (yet) any + * local directory. +--- cvs-1.12.13+real.orig/src/update.c ++++ cvs-1.12.13+real/src/update.c +@@ -58,7 +58,7 @@ + static int patch_file (struct file_info *finfo, + Vers_TS *vers_ts, + int *docheckout, struct stat *file_info, +- unsigned char *checksum); ++ md5_uint32 *checksum); + static void patch_file_write (void *, const char *, size_t); + #endif + static int merge_file (struct file_info *finfo, Vers_TS *vers); +@@ -723,7 +723,7 @@ + { + int docheckout; + struct stat file_info; +- unsigned char checksum[16]; ++ md5_uint32 checksum[4]; + + retval = patch_file (finfo, + vers, &docheckout, +@@ -735,7 +735,8 @@ + (rcs_diff_patches + ? SERVER_RCS_DIFF + : SERVER_PATCHED), +- file_info.st_mode, checksum, ++ file_info.st_mode, ++ (void *)checksum, + NULL); + break; + } +@@ -1181,6 +1182,7 @@ + { + free (vers->ts_user); + vers->ts_user = NULL; ++ vers->ts_user_ists = 0; + } + } + return 0; +@@ -1197,7 +1199,7 @@ + { + char *backup; + int set_time, retval = 0; +- int status; ++ int status = 0; + int file_is_dead; + struct buffer *revbuf; + +@@ -1366,6 +1368,7 @@ + + if (xvers_ts->ts_user != NULL) + free (xvers_ts->ts_user); ++ xvers_ts->ts_user_ists = 0; /*XXX really? */ + xvers_ts->ts_user = xstrdup (xvers_ts->ts_rcs); + } + +@@ -1511,7 +1514,7 @@ + */ + static int + patch_file (struct file_info *finfo, Vers_TS *vers_ts, int *docheckout, +- struct stat *file_info, unsigned char *checksum) ++ struct stat *file_info, md5_uint32 *checksum) + { + char *backup; + char *file1; +--- cvs-1.12.13+real.orig/src/vers_ts.c ++++ cvs-1.12.13+real/src/vers_ts.c +@@ -268,7 +268,10 @@ + time_stamp_server (finfo->file, vers_ts, entdata); + else + #endif ++ { + vers_ts->ts_user = time_stamp (finfo->file); ++ vers_ts->ts_user_ists = 1; ++ } + } + + return (vers_ts); +@@ -339,6 +342,7 @@ + { + struct tm *tm_p; + ++ vers_ts->ts_user_ists = 1; + vers_ts->ts_user = xmalloc (25); + /* We want to use the same timestamp format as is stored in the + st_mtime. For unix (and NT I think) this *must* be universal +--- cvs-1.12.13+real.orig/src/version.c ++++ cvs-1.12.13+real/src/version.c +@@ -16,6 +16,7 @@ + + #include "cvs.h" + ++static const + #ifdef CLIENT_SUPPORT + #ifdef SERVER_SUPPORT + char *config_string = " (client/server)\n"; +@@ -81,4 +82,3 @@ + #endif + return err; + } +- +--- cvs-1.12.13+real.orig/src/watch.c ++++ cvs-1.12.13+real/src/watch.c +@@ -459,7 +459,7 @@ + cvs_output (p++, 1); + if (*p == '\0') + { +- /* Only happens if attribute is misformed. */ ++ /* Only happens if attribute is malformed. */ + cvs_output ("\n", 1); + break; + } +--- cvs-1.12.13+real.orig/src/wrapper.c ++++ cvs-1.12.13+real/src/wrapper.c +@@ -86,7 +86,7 @@ + move this to a per-connection data structure, or better yet + think about a cleaner solution. */ + static int wrap_setup_already_done = 0; +- char *homedir; ++ char *homedir = NULL; + + if (wrap_setup_already_done != 0) + return; +@@ -107,6 +107,11 @@ + free (file); + } + ++#ifdef SERVER_SUPPORT ++ if (!server_active) ++#endif ++ { ++ + /* Then add entries found in home dir, (if user has one) and file + exists. */ + homedir = get_homedir (); +@@ -115,6 +120,8 @@ + hand it might be obnoxious to complain when CVS will function + just fine without .cvswrappers (and many users won't even know what + .cvswrappers is). */ ++ } ++ + if (homedir != NULL) + { + char *file = strcat_filename_onto_homedir (homedir, CVSDOTWRAPPER); +@@ -339,11 +346,19 @@ + if (!line || line[0] == '#') + return; + ++ /* Allows user to declare all wrappers null and void */ ++ if (line[0] == '!') { ++ wrap_kill (); ++ return; ++ } ++ + memset (&e, 0, sizeof(e)); + + /* Search for the wild card */ + while (*line && isspace ((unsigned char) *line)) + ++line; ++ if (!*line) ++ return; + for (temp = line; + *line && !isspace ((unsigned char) *line); + ++line) +--- cvs-1.12.13+real.orig/src/zlib.c ++++ cvs-1.12.13+real/src/zlib.c +@@ -229,7 +229,7 @@ + would fetch all the available bytes, and at least one byte. */ + + status = (*cb->buf->input) (cb->buf->closure, bd->text, +- need, BUFFER_DATA_SIZE, &nread); ++ need ? 1 : 0, BUFFER_DATA_SIZE, &nread); + + if (status == -2) + /* Don't try to recover from memory allcoation errors. */ |