diff -rup cvs-1.11.23.orig/src/client.c cvs-1.11.23/src/client.c --- cvs-1.11.23.orig/src/client.c Wed May 7 08:57:34 2008 +++ cvs-1.11.23/src/client.c Fri Nov 3 16:37:34 2017 @@ -3342,6 +3342,13 @@ struct response responses[] = 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), + /* + * Log message marker. + * Programs which parse rlog output need this feature so to correctly + * parse user-entered, free-form text in the commit messages. + * CVS client doesn't, so fliter it through handle_m. + */ + RSP_LINE("LOGM", handle_m, response_type_normal, rs_optional), /* Possibly should be response_type_error. */ RSP_LINE(NULL, NULL, response_type_normal, rs_essential) diff -rup cvs-1.11.23.orig/src/cvs.h cvs-1.11.23/src/cvs.h --- cvs-1.11.23.orig/src/cvs.h Fri Aug 25 08:48:55 2006 +++ cvs-1.11.23/src/cvs.h Fri Nov 3 16:38:42 2017 @@ -934,3 +934,4 @@ extern void cvs_outerr PROTO ((const char *, size_t)); extern void cvs_flusherr PROTO ((void)); extern void cvs_flushout PROTO ((void)); extern void cvs_output_tagged PROTO ((const char *, const char *)); +extern void cvs_output_logm PROTO ((const char *, size_t)); diff -rup cvs-1.11.23.orig/src/log.c cvs-1.11.23/src/log.c --- cvs-1.11.23.orig/src/log.c Mon Jan 28 06:55:45 2008 +++ cvs-1.11.23/src/log.c Fri Nov 3 16:39:41 2017 @@ -1714,9 +1714,7 @@ log_version (log_data, revlist, rcs, ver, trunk) { /* 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); + cvs_output_logm (p->data, 0); } } diff -rup cvs-1.11.23.orig/src/server.c cvs-1.11.23/src/server.c --- cvs-1.11.23.orig/src/server.c Wed May 7 08:57:34 2008 +++ cvs-1.11.23/src/server.c Fri Nov 3 16:40:47 2017 @@ -6762,4 +6762,47 @@ cvs_output_tagged (tag, text) else if (text != NULL) cvs_output (text, 0); } +} + +void +cvs_output_logm (str, len) + const char *str; + size_t len; +{ +#ifdef SERVER_SUPPORT + const char *p; + size_t n; + struct buffer *buf; + + if (!server_active || !supported_response ("LOGM")) + return cvs_output (str, len); + + if (error_use_protocol) + buf = buf_to_net; + else + buf = protocol; + + if (len == 0) + len = strlen (str); + + for (; p = strchr(str, '\n'); str = p + 1) + { + n = p - str + 1; + buf_output0 (buf, "LOGM "); + buf_output (buf, str, n); + len -= n; + } + if (len > 0) + { + buf_output0 (buf, "LOGM "); + buf_output (buf, str, len); + buf_output (buf, "\n", 1); + } + + if (!error_use_protocol) + buf_send_counted (protocol); + +#else /* !SERVER_SUPPORT */ + cvs_output (str, len); +#endif }