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))