diff -urP -U 5 cvs-1.11.5/src/README.RSE cvs-1.11.5.diff/src/README.RSE
--- cvs-1.11.5/src/README.RSE	Thu Jan  1 01:00:00 1970
+++ cvs-1.11.5.diff/src/README.RSE	Mon Jul 28 16:01:06 2003
@@ -0,0 +1,34 @@
+
+  CVS RSE Patches
+  ===============
+
+  This is the patched version of CVS from Ralf S. Engelschall
+  <rse@engelschall.com> - an enhanced version of the official CVS
+  version 1.12.1 (see http://www.cvshome.org/).
+
+  The following changes against the vendor CVS version are provided:
+    - support for an `importinfo' hook to ACL `cvs import' commands.
+
+  Some of my RSE functional patches are only useful for the server side,
+  others are also useful on the client side. All source patches to
+  *.[ch] files were entirely wrapped with ``#ifdef RSE_PATCH_<NAME> ...
+  #endif'' pairs. So, a particular patch is enabled by building CVS with
+  -DRSE_PATCH_<NAME>. All patches are enabled with -DRSE_PATCHES.
+
+                                       Ralf S. Engelschall
+                                       rse@engelschall.com
+                                       www.engelschall.com
+  ________________________________________________________________________
+
+  The following particular patches are available:
+
+  RSE_PATCH_IMPORTINFO:
+    This adds the feature of an extra `$CVSROOT/CVSROOT/importinfo'
+    configuration file which can be used for access controlling
+    `cvs import'. The specified filters in this info file receives
+    the following arguments: the vendor branch tag, the (absolute)
+    repository path which is the root of the import and then zero or
+    more relative file paths under this repository. If the filter
+    returns 0, the operation is allowed. If it returns not 0, the
+    operation is denied.
+    [Origin: Ralf S. Engelschall]
diff -urP -U 5 cvs-1.11.5/src/cvs.h cvs-1.11.5.diff/src/cvs.h
--- cvs-1.11.5/src/cvs.h	Sat Dec 28 19:01:30 2002
+++ cvs-1.11.5.diff/src/cvs.h	Mon Jul 28 16:01:06 2003
@@ -5,10 +5,17 @@
  * You may distribute under the terms of the GNU General Public License as
  * specified in the README file that comes with the CVS kit.
  */
 
 /*
+ * Support for compiling in various RSE extension
+ */
+#ifdef RSE_PATCHES
+#define RSE_PATCH_IMPORTINFO
+#endif
+
+/*
  * basic information used in all source files
  *
  */
 
 
@@ -191,10 +198,13 @@
 #define CVSROOTADM_USERS	"users"
 #define CVSROOTADM_READERS	"readers"
 #define CVSROOTADM_WRITERS	"writers"
 #define CVSROOTADM_PASSWD	"passwd"
 #define CVSROOTADM_CONFIG	"config"
+#ifdef RSE_PATCH_IMPORTINFO
+#define CVSROOTADM_IMPORTINFO   "importinfo"
+#endif
 
 #define CVSNULLREPOS		"Emptydir"	/* an empty directory */
 
 /* Other CVS file names */
 
diff -urP -U 5 cvs-1.11.5/src/import.c cvs-1.11.5.diff/src/import.c
--- cvs-1.11.5/src/import.c	Tue Sep 24 22:47:09 2002
+++ cvs-1.11.5.diff/src/import.c	Mon Jul 28 16:01:06 2003
@@ -55,10 +55,144 @@
     "\t-W spec\tWrappers specification line.\n",
     "(Specify the --help global option for a list of other help options)\n",
     NULL
 };
 
+#ifdef RSE_PATCH_IMPORTINFO
+
+static char *importinfo_vtag;
+
+static int
+importinfo_descend(thisdir)
+    char *thisdir;
+{
+    DIR *dirp;
+    struct dirent *dp;
+    int err = 0;
+    List *dirlist = NULL;
+
+    if ((dirp = CVS_OPENDIR(thisdir)) == NULL) {
+	error(0, errno, "cannot open directory");
+	err++;
+    }
+    else {
+	errno = 0;
+	while ((dp = readdir(dirp)) != NULL) {
+	    if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
+		goto one_more_time_boys;
+	    if (strcmp(dp->d_name, CVSADM) == 0)
+		goto one_more_time_boys;
+	    if (ign_name(dp->d_name))
+		goto one_more_time_boys;
+	    if (
+#ifdef DT_DIR
+		(dp->d_type == DT_DIR || (dp->d_type == DT_UNKNOWN && isdir (dp->d_name)))
+#else
+		isdir (dp->d_name)
+#endif
+		&& !wrap_name_has(dp->d_name, WRAP_TOCVS)
+		) {
+		Node *n;
+		if (dirlist == NULL)
+		    dirlist = getlist();
+		n = getnode();
+		n->key = xstrdup(dp->d_name);
+		addnode(dirlist, n);
+	    }
+	    else if (
+#ifdef DT_DIR
+		dp->d_type == DT_LNK || (dp->d_type == DT_UNKNOWN && islink (dp->d_name))
+#else
+		islink (dp->d_name)
+#endif
+		) {
+		err++;
+	    }
+	    else {
+                if (strcmp(thisdir, ".") == 0) {
+                    run_arg(dp->d_name);
+                }
+                else {
+                    char *p;
+                    p = xmalloc(strlen(thisdir)+1+strlen(dp->d_name)+1);
+                    (void)sprintf(p, "%s/%s", thisdir, dp->d_name);
+                    run_arg(p);
+                    free(p);
+                }
+	    }
+	    one_more_time_boys:
+	    errno = 0;
+	}
+	if (errno != 0) {
+	    error(0, errno, "cannot read directory");
+	    err++;
+	}
+	(void)closedir(dirp);
+    }
+    if (dirlist != NULL) {
+	Node *head, *p;
+	head = dirlist->list;
+	for (p = head->next; p != head; p = p->next) {
+            if (strcmp(thisdir, ".") == 0) {
+                err += importinfo_descend(p->key);
+            }
+            else {
+                char *nextdir;
+                nextdir = xmalloc(strlen(thisdir)+1+strlen(p->key)+1);
+                (void)sprintf(nextdir, "%s/%s", thisdir, p->key);
+                err += importinfo_descend(nextdir);
+                free(nextdir);
+            }
+        }
+	dellist(&dirlist);
+    }
+    return err;
+}
+
+/* importinfo configuration entry callback */
+static int
+importinfo_runproc(repository, filter)
+    char *repository;
+    char *filter;
+{
+    char *s, *cp;
+    int rv;
+
+    /* if possible, do an own check to make sure that filter really exists */
+    if (filter[0] == '/') {
+        s = xstrdup(filter);
+        for (cp = s; *cp; cp++) {
+            if (isspace((unsigned char)*cp)) {
+                *cp = '\0';
+                break;
+            }
+        }
+        if (!isfile(s)) {
+            error (0, errno, "cannot find pre-admin filter '%s'", s);
+            free(s);
+            return (1);
+        }
+        free(s);
+    }
+
+    /* construct the filter command */
+    run_setup(filter);
+    run_arg(importinfo_vtag);
+    run_arg(repository);
+    ign_add_file(CVSDOTIGNORE, 1);
+    wrap_add_file(CVSDOTWRAPPER, 1);
+    rv = importinfo_descend(".");
+    if (rv > 0) 
+        return rv;
+
+    /* execute the filter command */
+    rv = run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
+
+    return rv;
+}
+#endif
+
 int
 import (argc, argv)
     int argc;
     char **argv;
 {
@@ -288,10 +422,16 @@
     if (!safe_location ( NULL ))
     {
 	error (1, 0, "attempt to import the repository");
     }
 
+#ifdef RSE_PATCH_IMPORTINFO
+    importinfo_vtag = argv[1];
+    if (Parse_Info(CVSROOTADM_IMPORTINFO, argv[0], importinfo_runproc, 1) > 0)
+        error(1, 0, "Pre-import check failed");
+#endif
+
     /*
      * Make all newly created directories writable.  Should really use a more
      * sophisticated security mechanism here.
      */
     (void) umask (cvsumask);
diff -urP -U 5 cvs-1.11.5/src/mkmodules.c cvs-1.11.5.diff/src/mkmodules.c
--- cvs-1.11.5/src/mkmodules.c	Fri Sep  7 16:22:39 2001
+++ cvs-1.11.5.diff/src/mkmodules.c	Mon Jul 28 16:01:06 2003
@@ -184,10 +184,31 @@
     "# If the name \"ALL\" appears as a regular expression it is always used\n",
     "# in addition to the first matching regex or \"DEFAULT\".\n",
     NULL
 };
 
+#ifdef RSE_PATCH_IMPORTINFO
+static const char *const importinfo_contents[] = {
+    "# The \"importinfo\" file is used to control pre-import checks.\n",
+    "# The filter on the right is invoked with the repository to check.\n",
+    "# A non-zero exit of the filter program will cause the import\n",
+    "# operation to be aborted.\n",
+    "#\n",
+    "# The first entry on a line is a regular expression which is tested\n",
+    "# against the directory that the change is being committed to, relative\n",
+    "# to the $CVSROOT.  For the first match that is found, then the remainder\n",
+    "# of the line is the name of the filter to run.\n",
+    "#\n",
+    "# If the repository name does not match any of the regular expressions in this\n",
+    "# file, the \"DEFAULT\" line is used, if it is specified.\n",
+    "#\n",
+    "# If the name \"ALL\" appears as a regular expression it is always used\n",
+    "# in addition to the first matching regex or \"DEFAULT\".\n",
+    NULL
+};
+#endif
+
 static const char *const checkoutlist_contents[] = {
     "# The \"checkoutlist\" file is used to support additional version controlled\n",
     "# administrative files in $CVSROOT/CVSROOT, such as template files.\n",
     "#\n",
     "# The first entry on a line is a filename which will be checked out from\n",
@@ -327,10 +348,15 @@
 	"a %s file can be used to configure 'cvs commit' checking",
 	commitinfo_contents},
     {CVSROOTADM_TAGINFO,
 	"a %s file can be used to configure 'cvs tag' checking",
 	taginfo_contents},
+#ifdef RSE_PATCH_IMPORTINFO
+    {CVSROOTADM_IMPORTINFO,
+	"a %s file can be used to configure 'cvs import' checking",
+	importinfo_contents},
+#endif
     {CVSROOTADM_IGNORE,
 	"a %s file can be used to specify files to ignore",
 	NULL},
     {CVSROOTADM_CHECKOUTLIST,
 	"a %s file can specify extra CVSROOT files to auto-checkout",
diff -urP -U 5 cvs-1.11.5/src/sanity.sh cvs-1.11.5.diff/src/sanity.sh
--- cvs-1.11.5/src/sanity.sh	Thu Dec 19 16:38:32 2002
+++ cvs-1.11.5.diff/src/sanity.sh	Mon Jul 28 16:11:05 2003
@@ -104,10 +104,11 @@
 ###
 
 # "debugger"
 #set -x
 
+echo '[THIS PROCEDURE TAKES APPROX. 25min ON A PII/400MHz, SO BE PATIENT!]'
 echo 'This test should produce no other output than this message, and a final "OK".'
 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.)'
 
@@ -8841,10 +8842,11 @@
 	  dotest modules-1 "${testcvs} -q co ." 'U CVSROOT/checkoutlist
 U CVSROOT/commitinfo
 U CVSROOT/config
 U CVSROOT/cvswrappers
 U CVSROOT/editinfo
+U CVSROOT/importinfo
 U CVSROOT/loginfo
 U CVSROOT/modules
 U CVSROOT/notify
 U CVSROOT/rcsinfo
 U CVSROOT/taginfo
@@ -8865,10 +8867,11 @@
 	  dotest modules-2 "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist
 U CVSROOT/commitinfo
 U CVSROOT/config
 U CVSROOT/cvswrappers
 U CVSROOT/editinfo
+U CVSROOT/importinfo
 U CVSROOT/loginfo
 U CVSROOT/modules
 U CVSROOT/notify
 U CVSROOT/rcsinfo
 U CVSROOT/taginfo
@@ -8892,10 +8895,11 @@
 	  dotest modules-3d "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist
 U CVSROOT/commitinfo
 U CVSROOT/config
 U CVSROOT/cvswrappers
 U CVSROOT/editinfo
+U CVSROOT/importinfo
 U CVSROOT/loginfo
 U CVSROOT/modules
 U CVSROOT/notify
 U CVSROOT/rcsinfo
 U CVSROOT/taginfo
diff -urP -U 5 cvs-1.11.5/src/version.c cvs-1.11.5.diff/src/version.c
--- cvs-1.11.5/src/version.c	Mon Apr 29 06:25:58 2002
+++ cvs-1.11.5.diff/src/version.c	Mon Jul 28 16:01:06 2003
@@ -60,10 +60,13 @@
 
     /* Having the year here is a good idea, so people have
        some idea of how long ago their version of CVS was
        released.  */
     (void) fputs (PACKAGE_STRING, stdout);
+#ifdef RSE_PATCHES
+    (void) fputs (" [RSE-importinfo]", stdout);
+#endif
     (void) fputs (config_string, stdout);
 
 #ifdef CLIENT_SUPPORT
     if (current_parsed_root && current_parsed_root->isremote)
     {
