Apply by doing:
       cd /usr/src
       patch -p0 < 021_cvs2.patch

And then rebuild and install cvs:
       cd gnu/usr.bin/cvs
       make -f Makefile.bsd-wrapper obj
       make -f Makefile.bsd-wrapper
       make -f Makefile.bsd-wrapper install

Index: gnu/usr.bin/cvs/src/server.c
===================================================================
RCS file: /cvs/src/gnu/usr.bin/cvs/src/server.c,v
retrieving revision 1.28
retrieving revision 1.28.4.1
diff -u -p -r1.28 -r1.28.4.1
--- gnu/usr.bin/cvs/src/server.c        23 Jan 2003 20:00:20 -0000      1.28
+++ gnu/usr.bin/cvs/src/server.c        20 May 2004 19:52:30 -0000      1.28.4.1
@@ -1651,8 +1651,18 @@ serve_unchanged (arg)
           && strncmp (arg, name, cp - name) == 0)
       {
           timefield = strchr (cp + 1, '/') + 1;
-           if (*timefield != '=')
+           /* If the time field is not currently empty, then one of
+            * serve_modified, serve_is_modified, & serve_unchanged were
+            * already called for this file.  We would like to ignore the
+            * reinvocation silently or, better yet, exit with an error
+            * message, but we just avoid the copy-forward and overwrite the
+            * value from the last invocation instead.  See the comment below
+            * for more.
+            */
+           if (*timefield == '/')
           {
+               /* Copy forward one character.  Space was allocated for this
+                * already in serve_entry().  */
               cp = timefield + strlen (timefield);
               cp[1] = '\0';
               while (cp > timefield)
@@ -1660,8 +1670,17 @@ serve_unchanged (arg)
                   *cp = cp[-1];
                   --cp;
               }
-               *timefield = '=';
           }
+           /* If *TIMEFIELD wasn't "/", we assume that it was because of
+            * multiple calls to Is-Modified & Unchanged by the client and
+            * just overwrite the value from the last call.  Technically, we
+            * should probably either ignore calls after the first or send the
+            * client an error, since the client/server protocol specification
+            * specifies that only one call to either Is-Modified or Unchanged
+            * is allowed, but broken versions of WinCVS & TortoiseCVS rely on
+            * this behavior.
+            */
+           *timefield = '=';
           break;
       }
    }
@@ -1695,8 +1714,18 @@ serve_is_modified (arg)
           && strncmp (arg, name, cp - name) == 0)
       {
           timefield = strchr (cp + 1, '/') + 1;
-           if (!(timefield[0] == 'M' && timefield[1] == '/'))
+           /* If the time field is not currently empty, then one of
+            * serve_modified, serve_is_modified, & serve_unchanged were
+            * already called for this file.  We would like to ignore the
+            * reinvocation silently or, better yet, exit with an error
+            * message, but we just avoid the copy-forward and overwrite the
+            * value from the last invocation instead.  See the comment below
+            * for more.
+            */
+           if (*timefield == '/')
           {
+               /* Copy forward one character.  Space was allocated for this
+                * already in serve_entry().  */
               cp = timefield + strlen (timefield);
               cp[1] = '\0';
               while (cp > timefield)
@@ -1704,8 +1733,17 @@ serve_is_modified (arg)
                   *cp = cp[-1];
                   --cp;
               }
-               *timefield = 'M';
           }
+           /* If *TIMEFIELD wasn't "/", we assume that it was because of
+            * multiple calls to Is-Modified & Unchanged by the client and
+            * just overwrite the value from the last call.  Technically, we
+            * should probably either ignore calls after the first or send the
+            * client an error, since the client/server protocol specification
+            * specifies that only one call to either Is-Modified or Unchanged
+            * is allowed, but broken versions of WinCVS & TortoiseCVS rely on
+            * this behavior.
+            */
+           *timefield = 'M';
           if (kopt != NULL)
           {
               if (alloc_pending (strlen (name) + 80))