Some of these changes have been taken or adapted from cvs-1.11.23-35.el7.src.rpm
that is available at https://centos.pkgs.org/7/centos-x86_64/cvs-1.11.23-35.el7.x86_64.rpm.html
Following patches have been used:
	cvs-1.11.1p1-bs.patch
	cvs-1.11.19-tmp.patch
	cvs-1.11.19-comp.patch
	cvs-1.11.19-logmsg.patch
	cvs-1.11.19-abortabort.patch
	cvs-1.11.19-netbsd-tag.patch
	cvs-1.11.19-tagname.patch
	cvs-1.11.21-diff.patch
	cvs-1.11.21-diff-kk.patch
	cvs-1.11.21-sort.patch
	cvs-1.11.23-sanity.patch
	cvs-1.11.23-Back-port-KeywordExpand-configuration-keyword.patch





2019-12-09  Juan Manuel Guerrero <juan.guerrero@gmx.de>

	* src/sanity.sh:  Adjust tests to accept new style getopt
	argument quotation and SELinux label notation from ls(1).

	* doc/cvs.texinfo:  Add KeywordExpand configuration keyword.

	* src/mkmodules.c:  Add KeywordExpand configuration keyword.

	* src/parseinfo.c (parse_config):  Add KeywordExpand configuration
	keyword.

	* src/rcs.c (RCS_setexpand, expand_keywords, make_file_label
	and RCS_setincexc):  Add KeywordExpand configuration keyword.

	* src/rcs.h:  Add KeywordExpand configuration keyword.


2019-12-08  Juan Manuel Guerrero <juan.guerrero@gmx.de>

	* contrib/rcs2log.sh:  Enable obsolete sort option called by
	rcs2log.

	* src/diff.c (diff):  Fix cvs diff -kk.
	(diff_file_nodiff):  Report unknown file when calling cvs diff
	with two -r options.


2019-12-06  Juan Manuel Guerrero <juan.guerrero@gmx.de>

	* src/mkmodules.c:  Added 't' as a loginfo format specifier
	(print tag or branch name).

	* src/logmsg.c (do_editor):  Added 't' as a loginfo format
	specifier (print tag or branch name).

	* src/cvs.h [DONT_USE_SIGNALS]:  Provide SIG_deregister prototype.

	* src/server.c (server_cleanup):  Deregister SIGABRT handler
	in clean-up to prevent loop.

	* src/main.c (main_cleanup):  Deregister SIGABRT handler in
	clean-up to prevent loop.

	* src/patch.c (patch_cleanup):  Deregister SIGABRT handler
	in clean-up to prevent loop.

	* src/rcs.c:  NULL pointer derefence fixed.
	(rcs_cleanup):  Deregister SIGABRT handler in clean-up to
	prevent loop.
	(RCS_check_tag):  Disable slashes in tag name.

	* src/sanity.sh:  Disable lengthy tests at build-time.

	* src/cvsbug.in:  Fix insecure temporary file handling.




diff -aprNU5 cvs-1.11.23.orig/contrib/rcs2log.sh cvs-1.11.23/contrib/rcs2log.sh
--- cvs-1.11.23.orig/contrib/rcs2log.sh	2019-12-09 18:02:44 +0000
+++ cvs-1.11.23/contrib/rcs2log.sh	2019-12-09 18:03:14 +0000
@@ -66,10 +66,13 @@ This program comes with NO WARRANTY, to
 You may redistribute copies of this program
 under the terms of the GNU General Public License.
 For more information about these matters, see the files named COPYING.
 Author: Paul Eggert <eggert@twinsun.com>'
 
+# set old environment for sort (bug #190009)
+export _POSIX2_VERSION=199209
+
 # functions
 @MKTEMP_SH_FUNCTION@
 
 # Use the traditional C locale.
 LANG=C
diff -aprNU5 cvs-1.11.23.orig/doc/cvs.texinfo cvs-1.11.23/doc/cvs.texinfo
--- cvs-1.11.23.orig/doc/cvs.texinfo	2019-12-09 18:02:44 +0000
+++ cvs-1.11.23/doc/cvs.texinfo	2019-12-09 18:15:34 +0000
@@ -6845,15 +6845,16 @@ identifying the files.  Embedded strings
 with strings of the form
 @code{$@var{keyword}:@var{value}$} whenever you obtain
 a new revision of the file.
 
 @menu
-* Keyword list::                Keywords
-* Using keywords::              Using keywords
-* Avoiding substitution::       Avoiding substitution
-* Substitution modes::          Substitution modes
-* Log keyword::                 Problems with the $@splitrcskeyword{Log}$ keyword.
+* Keyword list::                   Keywords
+* Using keywords::                 Using keywords
+* Avoiding substitution::          Avoiding substitution
+* Substitution modes::             Substitution modes
+* Configuring keyword expansion::  Configuring keyword expansion
+* Log keyword::                    Problems with the $@splitrcskeyword{Log}$ keyword.
 @end menu
 
 @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 @node Keyword list
 @section Keyword List
@@ -7030,10 +7031,16 @@ product.  For example, the source for th
 contains @samp{$@@asis@{@}Author$} whenever the text
 @samp{$@splitrcskeyword{Author}$} should appear.  In @code{nroff}
 and @code{troff} you can embed the null-character
 @code{\&} inside the keyword for a similar effect.
 
+It is also possible to specify an explicit list of
+keywords to include or exclude using the
+@code{KeywordExpand} option in the
+@file{CVSROOT/config} file--see @ref{Configuring keyword expansion}
+for more details.
+
 @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 @node Substitution modes
 @section Substitution modes
 @cindex Keyword substitution, changing modes
 @cindex -k (keyword substitution)
@@ -7122,10 +7129,78 @@ export}---@pxref{export}.  But be aware
 handle an export containing binary files correctly.
 
 @end table
 
 @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Configuring keyword expansion
+@section Configuring Keyword Expansion
+@cindex Configuring keyword expansion
+
+The @code{KeywordExpand} option in the
+@file{CVSROOT/config} file is intended to allow for the
+either the explicit exclusion of a keyword or list of
+keywords, or for the explicit inclusion of a keyword or
+a list of keywords.
+
+The @code{KeywordExpand} option is followed by
+@code{=} and the next character may either be @code{i}
+to start an inclusion list or @code{e} to start an
+exclusion list. If the following lines were added to
+the @file{CVSROOT/config} file:
+
+@example
+        # Restrict keyword expansion to "Log" only
+        KeywordExpand=iLog
+@end example
+
+then only the $@splitrcskeyword{Log}$ keyword would be expanded.
+A list may be used. The this example:
+
+@example
+        # Restrict keyword expansion to the Name and Date keywords.
+        KeywordExpand=iName,Date
+@end example
+
+would allow $@splitrcskeyword{Name}$, and $@splitrcskeyword{Date}$
+to be expanded.
+
+It is also possible to configure an exclusion list
+using the following:
+
+@example
+        # Do not expand the keyword Date
+        KeywordExpand=eDate
+@end example
+
+This allows @sc{cvs} to ignore the 
+$@splitrcskeyword{CVSHeader}$ keyword and retain all of the
+others. This could be confusing
+to users that expect RCS keywords to be expanded, so
+care should be taken to properly set user expectations
+for a repository that is configured in that manner.
+
+If there is a desire to not have any RCS keywords
+expanded and not use the @code{-ko} flags everywhere,
+an administrator may disable all keyword expansion
+using the @file{CVSROOT/config} line:
+
+@example
+    # Do not expand any RCS keywords
+    KeywordExpand=i
+@end example
+
+this could be confusing to users that expect RCS
+keywords like $@splitrcskeyword{Id}$ to be expanded properly,
+so care should be taken to properly set user
+expectations for a repository so configured.
+
+It should be noted that a patch to provide the
+@code{KeywordExpand} feature has been around a long time.
+However, that patch implemented this feature using
+@code{tagexpand=} keyword and this keyword is NOT recognized.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 @node Log keyword
 @section Problems with the $@splitrcskeyword{Log}$ keyword.
 
 The @code{$@splitrcskeyword{Log}$} keyword is somewhat
 controversial.  As long as you are working on your
@@ -13787,10 +13862,18 @@ subdirectories.  The @file{CVS} director
 will mean you don't have to specify @code{CVSROOT} for
 each command.  It also provides a place for the
 @file{CVS/Template} file (@pxref{Working directory
 storage}).
 
+@cindex KeywordExpand, in @file{CVSROOT/config}
+@item KeywordExpand=@var{value}
+Specify @samp{i} followed by a list of keywords to be expanded
+(for example, @samp{KeywordExpand=iName,Date}),
+or @samp{e} followed by a list of keywords not to be expanded
+(for example, @samp{KeywordExpand=eName}).
+For more on keyword expansion, see @ref{Configuring keyword expansion}.
+
 @cindex LockDir, in CVSROOT/config
 @item LockDir=@var{directory}
 Put @sc{cvs} lock files in @var{directory} rather than
 directly in the repository.  This is useful if you want
 to let users read from the repository while giving them
diff -aprNU5 cvs-1.11.23.orig/src/cvs.h cvs-1.11.23/src/cvs.h
--- cvs-1.11.23.orig/src/cvs.h	2019-12-09 18:02:44 +0000
+++ cvs-1.11.23/src/cvs.h	2019-12-09 18:03:14 +0000
@@ -487,10 +487,13 @@ typedef	int (*CALLPROC)	PROTO((const cha
 int Parse_Info PROTO((const char *infofile, const char *repository,
                       CALLPROC callproc, int all));
 extern int parse_config PROTO ((char *));
 
 typedef	RETSIGTYPE (*SIGCLEANUPPROC)	PROTO(());
+#ifndef DONT_USE_SIGNALS
+int SIG_deregister PROTO((int sig, SIGCLEANUPPROC sigcleanup));
+#endif /* !DONT_USE_SIGNALS */
 int SIG_register PROTO((int sig, SIGCLEANUPPROC sigcleanup));
 int isdir PROTO((const char *file));
 int isfile PROTO((const char *file));
 int islink PROTO((const char *file));
 int isdevice PROTO ((const char *));
diff -aprNU5 cvs-1.11.23.orig/src/cvsbug.in cvs-1.11.23/src/cvsbug.in
--- cvs-1.11.23.orig/src/cvsbug.in	2019-12-09 18:02:44 +0000
+++ cvs-1.11.23/src/cvsbug.in	2019-12-09 18:03:14 +0000
@@ -107,18 +107,18 @@ elif [ -f /bin/domainname ]; then
     # Must use temp file due to incompatibilities in quoting behavior
     # and to protect shell metacharacters in the expansion of $LOGNAME
     /usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" |
       cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
     ORIGINATOR="`cat $TEMP`"
-    rm -f $TEMP
+    > $TEMP
   fi
 fi
 
 if [ "$ORIGINATOR" = "" ]; then
   grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
   ORIGINATOR="`cat $TEMP`"
-  rm -f $TEMP
+  > $TEMP
 fi
 
 if [ -n "$ORGANIZATION" ]; then
   if [ -f "$ORGANIZATION" ]; then
     ORGANIZATION="`cat $ORGANIZATION`"
diff -aprNU5 cvs-1.11.23.orig/src/diff.c cvs-1.11.23/src/diff.c
--- cvs-1.11.23.orig/src/diff.c	2005-05-27 17:17:02 +0000
+++ cvs-1.11.23/src/diff.c	2019-12-09 18:03:14 +0000
@@ -436,11 +436,11 @@ diff (argc, argv)
 	    client_senddate (diff_date2);
 	send_arg ("--");
 
 	/* Send the current files unless diffing two revs from the archive */
 	if (diff_rev2 == NULL && diff_date2 == NULL)
-	    send_files (argc, argv, local, 0, 0);
+	    send_files (argc, argv, local, 0, options[0] == '\0' ? 0 : SEND_FORCE);
 	else
 	    send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
 
 	send_file_names (argc, argv, SEND_EXPAND_WILD);
 
@@ -953,18 +953,20 @@ diff_file_nodiff( finfo, vers, empty_fil
 	if( use_rev1 == NULL || RCS_isdead( vers->srcfile, use_rev1 ) )
 	{
 	    /* The first revision does not exist.  If EMPTY_FILES is
                true, treat this as an added file.  Otherwise, warn
                about the missing tag.  */
-	    if( use_rev2 == NULL || RCS_isdead( vers->srcfile, use_rev2 ) )
+	    if( use_rev2 == NULL || RCS_isdead( vers->srcfile, use_rev2 ) ) {
 		/* At least in the case where DIFF_REV1 and DIFF_REV2
 		 * are both numeric (and non-existant (NULL), as opposed to
 		 * dead?), we should be returning some kind of error (see
 		 * basicb-8a0 in testsuite).  The symbolic case may be more
 		 * complicated.
 		 */
-		return DIFF_SAME;
+		error (0, 0, "no revision in file %s or missing file %s", finfo->fullname, finfo->fullname);
+		return DIFF_ERROR;
+	    }
 	    if( empty_files )
 		return DIFF_ADDED;
 	    if( use_rev1 != NULL )
 	    {
 		if (diff_rev1)
diff -aprNU5 cvs-1.11.23.orig/src/logmsg.c cvs-1.11.23/src/logmsg.c
--- cvs-1.11.23.orig/src/logmsg.c	2019-12-09 18:02:44 +0000
+++ cvs-1.11.23/src/logmsg.c	2019-12-09 18:03:14 +0000
@@ -225,10 +225,12 @@ do_editor (dir, messagep, repository, ch
 	(void) fputs (*messagep, fp);
 
 	if ((*messagep)[0] == '\0' ||
 	    (*messagep)[strlen (*messagep) - 1] != '\n')
 	    (void) fprintf (fp, "\n");
+    } else {
+        (void) fprintf (fp, "\n");
     }
 
     if (repository != NULL)
 	/* tack templates on if necessary */
 	(void) Parse_Info (CVSROOTADM_RCSINFO, repository, rcsinfo_proc, 1);
@@ -267,11 +269,11 @@ do_editor (dir, messagep, repository, ch
 		error (0, errno, "cannot close %s", CVSADM_TEMPLATE);
 	}
     }
 
     (void) fprintf (fp,
-  "\n%s----------------------------------------------------------------------\n",
+  "%s----------------------------------------------------------------------\n",
 		    CVSEDITPREFIX);
     (void) fprintf (fp,
   "%sEnter Log.  Lines beginning with `%.*s' are removed automatically\n%s\n",
 		    CVSEDITPREFIX, CVSEDITPREFIXLEN, CVSEDITPREFIX,
 		    CVSEDITPREFIX);
@@ -732,10 +734,19 @@ title_proc (p, closure)
 		    str_list =
 			xrealloc (str_list,
 				  strlen (str_list) + strlen (p->key) + 5);
 		    (void) strcat (str_list, p->key);
 		    break;
+               case 't':
+                   str_list =
+                       xrealloc (str_list,
+                                 (strlen (str_list)
+                                  + (li->tag ? strlen (li->tag) : 0)
+                                  + 10)
+                                 );
+                   (void) strcat (str_list, (li->tag ? li->tag : ""));
+                   break;
 		case 'V':
 		    str_list =
 			xrealloc (str_list,
 				  (strlen (str_list)
 				   + (li->rev_old ? strlen (li->rev_old) : 0)
diff -aprNU5 cvs-1.11.23.orig/src/main.c cvs-1.11.23/src/main.c
--- cvs-1.11.23.orig/src/main.c	2019-12-09 18:02:44 +0000
+++ cvs-1.11.23/src/main.c	2019-12-09 18:03:14 +0000
@@ -348,10 +348,17 @@ main_cleanup (sig)
 {
 #ifndef DONT_USE_SIGNALS
     const char *name;
     char temp[10];
 
+#ifdef SIGABRT
+    /* Need to deregister the SIGABRT handler so that if an assertion
+       fails and calls abort while we're cleaning up, we won't
+       infinitely recurse in the cleanup function. */
+    SIG_deregister(SIGABRT, main_cleanup);
+#endif
+
     switch (sig)
     {
 #ifdef SIGABRT
     case SIGABRT:
 	name = "abort";
diff -aprNU5 cvs-1.11.23.orig/src/mkmodules.c cvs-1.11.23/src/mkmodules.c
--- cvs-1.11.23.orig/src/mkmodules.c	2019-12-09 18:02:44 +0000
+++ cvs-1.11.23/src/mkmodules.c	2019-12-09 18:15:34 +0000
@@ -77,10 +77,11 @@ static const char *const loginfo_content
     "# characters are:\n",
     "#\n",
     "#   s = file name\n",
     "#   V = old version number (pre-checkin)\n",
     "#   v = new version number (post-checkin)\n",
+    "#   t = tag or branch name\n",
     "#\n",
     "# For example:\n",
     "#DEFAULT (echo \"\"; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog\n",
     "# or\n",
     "#DEFAULT (echo \"\"; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog\n",
@@ -297,10 +298,15 @@ static const char *const config_contents
     "# This option is intended to be useful as a transition for read-only\n",
     "# mirror sites when sites may need to be updated later than the\n",
     "# primary CVS repository.\n",
     "#IgnoreUnknownConfigKeys=no\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=iName,Date\n",
+    "#KeywordExpand=eName\n",
+    "\n",
     "# Put CVS lock files in this directory rather than directly in the repository.\n",
     "#LockDir=/var/lock/cvs\n",
     "\n",
 #ifdef PRESERVE_PERMISSIONS_SUPPORT
     "# Set `PreservePermissions' to `yes' to save file status information\n",
diff -aprNU5 cvs-1.11.23.orig/src/parseinfo.c cvs-1.11.23/src/parseinfo.c
--- cvs-1.11.23.orig/src/parseinfo.c	2008-05-07 15:57:34 +0000
+++ cvs-1.11.23/src/parseinfo.c	2019-12-09 18:15:34 +0000
@@ -358,10 +358,14 @@ parse_config (cvsroot)
 	    {
 		error (0, 0, "unrecognized value '%s' for SystemAuth", p);
 		goto error_return;
 	    }
 	}
+	else if (strcmp (line, "KeywordExpand") == 0)
+	{
+	    RCS_setincexc (p);
+	}
 	else if (strcmp (line, "PreservePermissions") == 0)
 	{
 	    if (strcmp (p, "no") == 0)
 		preserve_perms = 0;
 	    else if (strcmp (p, "yes") == 0)
diff -aprNU5 cvs-1.11.23.orig/src/patch.c cvs-1.11.23/src/patch.c
--- cvs-1.11.23.orig/src/patch.c	2008-05-07 15:57:34 +0000
+++ cvs-1.11.23/src/patch.c	2019-12-09 18:03:14 +0000
@@ -820,10 +820,19 @@ patch_cleanup ()
 {
     /* Note that the checks for existence_error are because we are
        called from a signal handler, without SIG_begincrsect, so
        we don't know whether the files got created.  */
 
+#ifndef DONT_USE_SIGNALS
+#ifdef SIGABRT
+    /* Need to deregister the SIGABRT handler so that if an assertion
+       fails and calls abort while we're cleaning up, we won't
+       infinitely recurse in the cleanup function. */
+    SIG_deregister(SIGABRT, patch_cleanup);
+#endif
+#endif /* !DONT_USE_SIGNALS */
+
     if (tmpfile1 != NULL)
     {
 	if (unlink_file (tmpfile1) < 0
 	    && !existence_error (errno))
 	    error (0, errno, "cannot remove %s", tmpfile1);
diff -aprNU5 cvs-1.11.23.orig/src/rcs.c cvs-1.11.23/src/rcs.c
--- cvs-1.11.23.orig/src/rcs.c	2019-12-09 18:02:44 +0000
+++ cvs-1.11.23/src/rcs.c	2019-12-09 18:15:34 +0000
@@ -13,10 +13,11 @@
  * The routines contained in this file do all the rcs file parsing and
  * manipulation
  */
 
 #include <assert.h>
+#include <stdbool.h>
 #include "cvs.h"
 #include "edit.h"
 #include "hardlink.h"
 
 /* These need to be source after cvs.h or HAVE_MMAP won't be set... */
@@ -145,11 +146,11 @@ static char *rcs_lockfilename PROTO ((co
 
 /* The RCS file reading functions are called a lot, and they do some
    string comparisons.  This macro speeds things up a bit by skipping
    the function call when the first characters are different.  It
    evaluates its arguments multiple times.  */
-#define STREQ(a, b) (*(char *)(a) == *(char *)(b) && strcmp ((a), (b)) == 0)
+#define STREQ(a, b) ((a) != NULL && (b) != NULL && *(char *)(a) == *(char *)(b) && strcmp ((a), (b)) == 0)
 
 /*
  * We don't want to use isspace() from the C library because:
  *
  * 1. The definition of "whitespace" in RCS files includes ASCII
@@ -3391,11 +3392,11 @@ RCS_check_kflag (arg)
  */
 void
 RCS_check_tag (tag)
     const char *tag;
 {
-    char *invalid = "$,.:;@";		/* invalid RCS tag characters */
+    char *invalid = "$,.:;@/";		/* invalid RCS tag characters */
     const char *cp;
 
     /*
      * The first character must be an alphabetic letter. The remaining
      * characters cannot be non-visible graphic characters, and must not be
@@ -3507,13 +3508,14 @@ RCS_setexpand (rcs, expand)
 /* RCS keywords, and a matching enum.  */
 struct rcs_keyword
 {
     const char *string;
     size_t len;
+    bool expandit;
 };
-#define KEYWORD_INIT(s) (s), sizeof (s) - 1
-static const struct rcs_keyword keywords[] =
+#define KEYWORD_INIT(s) (s), sizeof (s) - 1, true
+static struct rcs_keyword keywords[] =
 {
     { KEYWORD_INIT ("Author") },
     { KEYWORD_INIT ("Date") },
     { KEYWORD_INIT ("Header") },
     { KEYWORD_INIT ("Id") },
@@ -3715,11 +3717,12 @@ expand_keywords (rcs, ver, name, log, lo
 
 	/* See if this is one of the keywords.  */
 	slen = s - srch;
 	for (keyword = keywords; keyword->string != NULL; keyword++)
 	{
-	    if (keyword->len == slen
+	    if (keyword->expandit
+		&& keyword->len == slen
 		&& strncmp (keyword->string, srch, slen) == 0)
 	    {
 		break;
 	    }
 	}
@@ -8597,10 +8600,19 @@ rcs_cleanup ()
 {
     /* Note that the checks for existence_error are because we are
        called from a signal handler, so we don't know whether the
        files got created.  */
 
+#ifndef DONT_USE_SIGNALS
+#ifdef SIGABRT
+    /* Need to deregister the SIGABRT handler so that if an assertion
+       fails and calls abort while we're cleaning up, we won't
+       infinitely recurse in the cleanup function. */
+    SIG_deregister(SIGABRT, rcs_cleanup);
+#endif
+#endif /* !DONT_USE_SIGNALS */
+
     /* FIXME: Do not perform buffered I/O from an interrupt handler like
        this (via error).  However, I'm leaving the error-calling code there
        in the hope that on the rare occasion the error call is actually made
        (e.g., a fluky I/O error or permissions problem prevents the deletion
        of a just-created file) reentrancy won't be an issue.  */
@@ -8949,5 +8961,47 @@ make_file_label (path, rev, rcs)
 	(void) tm_to_internet (datebuf, wm);
 	(void) sprintf (label, "-L%s\t%s", path, datebuf);
     }
     return label;
 }
+
+
+
+void
+RCS_setincexc (const char *arg)
+{
+    char *key;
+    char *copy, *next;
+    bool include = false;
+    struct rcs_keyword *keyword;
+
+    copy = xstrdup(arg);
+    next = copy;
+    switch (*next++) {
+	case 'e':
+	    include = false;
+	    break;
+	case 'i':
+	    include = true;
+	    break;
+	default:
+	    free(copy);
+	    return;
+    }
+
+    if (include)
+	for (keyword = keywords; keyword->string != NULL; keyword++)
+	{
+	    keyword->expandit = false;
+	}
+
+    key = strtok(next, ",");
+    while (key) {
+	for (keyword = keywords; keyword->string != NULL; keyword++) {
+	    if (strcmp (keyword->string, key) == 0)
+		keyword->expandit = include;
+	}
+	key = strtok(NULL, ",");
+    }
+    free(copy);
+    return;
+}
diff -aprNU5 cvs-1.11.23.orig/src/rcs.h cvs-1.11.23/src/rcs.h
--- cvs-1.11.23.orig/src/rcs.h	2005-04-04 20:46:06 +0000
+++ cvs-1.11.23/src/rcs.h	2019-12-09 18:15:34 +0000
@@ -248,10 +248,11 @@ void RCS_abandon PROTO ((RCSNode *));
 int rcs_change_text PROTO ((const char *, char *, size_t, const char *,
 			    size_t, char **, size_t *));
 void RCS_deltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, const char *,
 			enum rcs_delta_op, char **, size_t *,
 			char **, size_t *));
+void RCS_setincexc (const char *arg);
 char *make_file_label PROTO ((const char *, const char *, RCSNode *));
 
 extern int preserve_perms;
 
 /* From import.c.  */
diff -aprNU5 cvs-1.11.23.orig/src/sanity.sh cvs-1.11.23/src/sanity.sh
--- cvs-1.11.23.orig/src/sanity.sh	2019-12-09 18:02:44 +0000
+++ cvs-1.11.23/src/sanity.sh	2019-12-09 18:04:54 +0000
@@ -16,10 +16,12 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # Original Author: K. Richard Pixley
 
+exit 0
+
 # usage:
 usage ()
 {
     echo "Usage: `basename $0` --help"
     echo "Usage: `basename $0` [-eklrv] [-f FROM-TEST] [-h HOSTNAME] CVS-TO-TEST [TESTS-TO-RUN...]"
@@ -2750,11 +2752,11 @@ ${PROG} \[admin aborted\]: attempt to de
 	  # of the moon (weirdness with optind), and who knows what else.
 	  # I've been seeing "illegal"...
 	  dotest_fail basicb-21 "${testcvs} -q admin -H" \
 "admin: illegal option -- H
 ${PROG} \[admin aborted\]: specify ${PROG} -H admin for usage information" \
-"admin: invalid option -- H
+"admin: invalid option -- 'H'
 ${PROG} \[admin aborted\]: specify ${PROG} -H admin for usage information"
 	  cd ..
 	  rmdir 1
 
 	  if $keep; then
@@ -22195,11 +22197,11 @@ done"
 	  if test -n "$remotehost"; then
 	    dotest modes-5remotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \
 "-r--r--r-- .*"
 	  else
 	    dotest modes-5 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \
-"-r--r--r-- .*"
+"-r--r--r--.*"
 	  fi
 
 	  # Test for whether we can set the execute bit.
 	  chmod +x aa
 	  echo change it >>aa
@@ -22216,11 +22218,11 @@ done"
 	  if test -n "$remotehost"; then
 	    dotest modes-7remotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \
 "-r--r--r-- .*"
 	  else
 	    dotest modes-7 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \
-"-r--r--r-- .*"
+"-r--r--r--.*"
 	  fi
 
 	  # OK, now manually change the modes and see what happens.
 	  #
 	  # Cygwin, already.
@@ -22239,11 +22241,11 @@ done"
 	  if test -n "$remotehost"; then
 	    dotest modes-7bremotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \
 "-r--r----- .*"
 	  else
 	    dotest modes-7b "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \
-"-r--r----- .*"
+"-r--r-----.*"
 	  fi
 
 	  CVSUMASK=007
 	  export CVSUMASK
 	  touch ab
diff -aprNU5 cvs-1.11.23.orig/src/server.c cvs-1.11.23/src/server.c
--- cvs-1.11.23.orig/src/server.c	2019-12-09 18:02:44 +0000
+++ cvs-1.11.23/src/server.c	2019-12-09 18:03:14 +0000
@@ -4975,10 +4975,19 @@ server_cleanup (sig)
 {
     /* Do "rm -rf" on the temp directory.  */
     int status;
     int save_noexec;
 
+#ifndef DONT_USE_SIGNALS
+#ifdef SIGABRT
+    /* Need to deregister the SIGABRT handler so that if an assertion
+       fails and calls abort while we're cleaning up, we won't
+       infinitely recurse in the cleanup function. */
+    SIG_deregister(SIGABRT, server_cleanup);
+#endif
+#endif /* !DONT_USE_SIGNALS */
+
     if (buf_to_net != NULL)
     {
 	/* Since we're done, go ahead and put BUF_TO_NET back into blocking
 	 * mode and send any pending output.  In the usual case there won't
 	 * won't be any, but there might be if an error occured.
