cvs-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Cvs-cvs] ccvs/src ChangeLog gpg.c gpg.h log.c sanity.sh [signed-commits


From: Derek Robert Price
Subject: [Cvs-cvs] ccvs/src ChangeLog gpg.c gpg.h log.c sanity.sh [signed-commits3]
Date: Fri, 30 Dec 2005 23:26:33 +0000

CVSROOT:        /cvsroot/cvs
Module name:    ccvs
Branch:         signed-commits3
Changes by:     Derek Robert Price <address@hidden>     05/12/30 23:26:33

Modified files:
        src            : ChangeLog gpg.c gpg.h log.c sanity.sh 

Log message:
        * gpg.c (read_u8, read_u16, read_u32): Declare inline.
        (read_u64): New function.
        (read_signature): Expand header comment block.
        (parse_signature): Parse up to key ID.
        (struct openpgp_signature): Move decl to...
        gpg.h (struct openpgp_signature): ...here.
        (parse_signature): New proto.
        * log.c: Include "base64.h" & "gpg.h".
        (log_version): Print signature information when available.
        * sanity.sh: Accept new signature info in log messages.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/ChangeLog.diff?only_with_tag=signed-commits3&tr1=1.3328.2.6&tr2=1.3328.2.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/gpg.c.diff?only_with_tag=signed-commits3&tr1=1.1.6.6&tr2=1.1.6.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/gpg.h.diff?only_with_tag=signed-commits3&tr1=1.1.6.1&tr2=1.1.6.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/log.c.diff?only_with_tag=signed-commits3&tr1=1.103&tr2=1.103.6.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/sanity.sh.diff?only_with_tag=signed-commits3&tr1=1.1105.2.1&tr2=1.1105.2.2&r1=text&r2=text

Patches:
Index: ccvs/src/ChangeLog
diff -u ccvs/src/ChangeLog:1.3328.2.6 ccvs/src/ChangeLog:1.3328.2.7
--- ccvs/src/ChangeLog:1.3328.2.6       Fri Dec 30 16:30:28 2005
+++ ccvs/src/ChangeLog  Fri Dec 30 23:26:32 2005
@@ -1,5 +1,16 @@
 2005-12-30  Derek Price  <address@hidden>
 
+       * gpg.c (read_u8, read_u16, read_u32): Declare inline.
+       (read_u64): New function.
+       (read_signature): Expand header comment block.
+       (parse_signature): Parse up to key ID.
+       (struct openpgp_signature): Move decl to...
+       gpg.h (struct openpgp_signature): ...here.
+       (parse_signature): New proto.
+       * log.c: Include "base64.h" & "gpg.h".
+       (log_version): Print signature information when available.
+       * sanity.sh: Accept new signature info in log messages.
+
        * gpg.c (write_part, parse_header, read_signature, parse_signature):
        Use uint8_t rather than unsigned char.
 
Index: ccvs/src/gpg.c
diff -u ccvs/src/gpg.c:1.1.6.6 ccvs/src/gpg.c:1.1.6.7
--- ccvs/src/gpg.c:1.1.6.6      Fri Dec 30 16:30:29 2005
+++ ccvs/src/gpg.c      Fri Dec 30 23:26:32 2005
@@ -98,7 +98,7 @@
 
 
 
-static int
+static inline int
 read_u8 (struct buffer *bpin, uint8_t *rn)
 {
   char *tmp;
@@ -114,7 +114,7 @@
 
 
 
-static int
+static inline int
 read_u16 (struct buffer *bpin, uint16_t *rn)
 {
   uint8_t tmp;
@@ -131,7 +131,7 @@
 
 
 
-static int
+static inline int
 read_u32 (struct buffer *bpin, uint32_t *rn)
 {
   uint16_t tmp;
@@ -148,6 +148,25 @@
 
 
 
+static inline int
+read_u64 (struct buffer *bpin, uint64_t *rn)
+{
+  uint32_t tmp;
+  int rc;
+
+  if ((rc = read_u32 (bpin, &tmp)))
+    return rc;
+  /* This next is done in two steps to suppress a GCC warning.  */
+  *rn = tmp;
+  *rn <<= 32;
+  if ((rc = read_u32 (bpin, &tmp)))
+    return rc;
+  *rn |= tmp;
+  return 0;
+}
+
+
+
 /* hdr must point to a buffer large enough to hold all header bytes */
 static int
 write_part (struct buffer *bpin, struct buffer *bpout, unsigned long pktlen,
@@ -203,6 +222,17 @@
 
 /* Read a single signature packet header from BPIN.
  *
+ * INPUTS
+ *   BPIN      Pointer to the buffer to read from.
+ *
+ * OUTPUTS
+ *   *PKTTYPE  PGP Packet type read from buffer.
+ *   *PKTLEN   Length of data remaining in buffer (PKTLEN + HEADER_LEN =
+ *             Full length of OpenPGP packet).
+ *   PARTIAL   1 if this is a partial packet, 0 otherwise.
+ *   HEADER    Copy of header block from PGP packet.
+ *   HEADER_LEN        Length of HEADER.
+ *
  * RETURNS
  *   0         On success.
  *   -1                If EOF is encountered before a full packet is read.
@@ -333,11 +363,6 @@
 
 
 
-struct openpgp_signature
-{
-  uint64_t sigid;
-};
-
 /* Parse a single signature packet from BPIN, populating structure at SPOUT.
  *
  * RETURNS
@@ -359,18 +384,63 @@
   int header_len = sizeof header;
   int rc;
   uint8_t c;
+  uint32_t tmp32;
 
   if ((rc = parse_header (bpin, &pkttype, &pktlen, &partial, header,
                          &header_len)))
     return rc;
 
+  if (partial)
+    error (1, 0, "Unhandled OpenPGP packet type (partial)");
   if (pkttype != PKT_SIGNATURE)
-    error (1, 0, "Inavlid OpenPGP packet type (%s)",
+    error (1, 0, "Unhandled OpenPGP packet type (%s)",
           pkttype_to_string (pkttype));
 
+  if (pktlen < 19)
+    error (1, 0, "Malformed OpenPGP signature packet (too short)");
+
   if ((rc = read_u8 (bpin, &c)))
     return rc;
+  pktlen -= 1;
+
+  if (c != 3)
+    error (1, 0, "Unhandled OpenPGP signature version (%hhu)", c);
 
+  if ((rc = read_u8 (bpin, &c)))
+    return rc;
+  pktlen -= 1;
+
+  if (c != 5)
+    error (1, 0, "Malformed OpenPGP signature (type/time length invalid)");
+
+  if ((rc = read_u8 (bpin, &c)))
+    return rc;
+  pktlen -= 1;
+
+  if (c & 0xF0)
+    error (1, 0, "Unhandled OpenPGP signature type (%hhu)", c);
+
+  /* Read the creation time.  */
+  if ((rc = read_u32 (bpin, &tmp32)))
+    return rc;
+  spout->ctime = tmp32;
+  pktlen -= 4;
+
+  /* Read the key ID.  */
+  if ((rc = read_u64 (bpin, &spout->keyid)))
+    return rc;
+  pktlen -= 8;
+
+  /* Don't need the rest of the packet yet.  */
+  while (pktlen)
+    {
+      size_t got;
+      char *tmp;
+      if ((rc = buf_read_data (bpin, pktlen, &tmp, &got)) < 0)
+       return rc;
+      assert (got);  /* Blocking buffers cannot return 0 bytes.  */
+      pktlen -= got;
+    }
 
   return 0;
 }
Index: ccvs/src/gpg.h
diff -u ccvs/src/gpg.h:1.1.6.1 ccvs/src/gpg.h:1.1.6.2
--- ccvs/src/gpg.h:1.1.6.1      Wed Dec 21 13:25:10 2005
+++ ccvs/src/gpg.h      Fri Dec 30 23:26:32 2005
@@ -22,8 +22,23 @@
 #ifndef GPG_H
 #define GPG_H
 
+/* ANSI C Headers.  */
+#include <stdint.h>
+
+/* CVS Headers.  */
 #include "buffer.h"
 
+
+
+struct openpgp_signature
+{
+  time_t ctime;
+  uint64_t keyid;
+};
+
+
+
 int read_signature (struct buffer *bpin, struct buffer *bpout);
+int parse_signature (struct buffer *bpin, struct openpgp_signature *spout);
 
 #endif /* GPG_H */
Index: ccvs/src/log.c
diff -u /dev/null ccvs/src/log.c:1.103.6.1
--- /dev/null   Fri Dec 30 23:26:33 2005
+++ ccvs/src/log.c      Fri Dec 30 23:26:32 2005
@@ -0,0 +1,1832 @@
+/*
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ *                                  and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
+ * 
+ * You may distribute under the terms of the GNU General Public License as
+ * specified in the README file that comes with the CVS source distribution.
+ * 
+ * Print Log Information
+ * 
+ * Prints the RCS "log" (rlog) information for the specified files.  With no
+ * argument, prints the log information for all the files in the directory
+ * (recursive by default).
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h> 
+#endif
+
+/* ANSI C Headers.  */
+#include <assert.h>
+
+/* GNULIB Headers.  */
+#include "base64.h"
+
+/* CVS Headers.  */
+#include "gpg.h"
+
+#include "cvs.h"
+
+
+
+/* This structure holds information parsed from the -r option.  */
+
+struct option_revlist
+{
+    /* The next -r option.  */
+    struct option_revlist *next;
+    /* The first revision to print.  This is NULL if the range is
+       :rev, or if no revision is given.  */
+    char *first;
+    /* The last revision to print.  This is NULL if the range is rev:,
+       or if no revision is given.  If there is no colon, first and
+       last are the same.  */
+    char *last;
+    /* Nonzero if there was a trailing `.', which means to print only
+       the head revision of a branch.  */
+    int branchhead;
+    /* Nonzero if first and last are inclusive.  */
+    int inclusive;
+};
+
+/* This structure holds information derived from option_revlist given
+   a particular RCS file.  */
+
+struct revlist
+{
+    /* The next pair.  */
+    struct revlist *next;
+    /* The first numeric revision to print.  */
+    char *first;
+    /* The last numeric revision to print.  */
+    char *last;
+    /* The number of fields in these revisions (one more than
+       numdots).  */
+    int fields;
+    /* Whether first & last are to be included or excluded.  */
+    int inclusive;
+};
+
+/* This structure holds information parsed from the -d option.  */
+
+struct datelist
+{
+    /* The next date.  */
+    struct datelist *next;
+    /* The starting date.  */
+    char *start;
+    /* The ending date.  */
+    char *end;
+    /* Nonzero if the range is inclusive rather than exclusive.  */
+    int inclusive;
+};
+
+/* This structure is used to pass information through start_recursion.  */
+struct log_data
+{
+    /* Nonzero if the -R option was given, meaning that only the name
+       of the RCS file should be printed.  */
+    int nameonly;
+    /* Nonzero if the -h option was given, meaning that only header
+       information should be printed.  */
+    int header;
+    /* Nonzero if the -t option was given, meaning that only the
+       header and the descriptive text should be printed.  */
+    int long_header;
+    /* Nonzero if the -N option was seen, meaning that tag information
+       should not be printed.  */
+    int notags;
+    /* Nonzero if the -b option was seen, meaning that only revisions
+       on the default branch should be printed.  */
+    int default_branch;
+    /* Nonzero if the -S option was seen, meaning that the header/name
+       should be suppressed if no revisions are selected.  */
+    int sup_header;
+    /* If not NULL, the value given for the -r option, which lists
+       sets of revisions to be printed.  */
+    struct option_revlist *revlist;
+    /* If not NULL, the date pairs given for the -d option, which
+       select date ranges to print.  */
+    struct datelist *datelist;
+    /* If not NULL, the single dates given for the -d option, which
+       select specific revisions to print based on a date.  */
+    struct datelist *singledatelist;
+    /* If not NULL, the list of states given for the -s option, which
+       only prints revisions of given states.  */
+    List *statelist;
+    /* If not NULL, the list of login names given for the -w option,
+       which only prints revisions checked in by given users.  */
+    List *authorlist;
+};
+
+/* This structure is used to pass information through walklist.  */
+struct log_data_and_rcs
+{
+    struct log_data *log_data;
+    struct revlist *revlist;
+    RCSNode *rcs;
+};
+
+static int rlog_proc (int argc, char **argv, char *xwhere,
+                      char *mwhere, char *mfile, int shorten,
+                      int local_specified, char *mname, char *msg);
+static Dtype log_dirproc (void *callerdat, const char *dir,
+                          const char *repository, const char *update_dir,
+                          List *entries);
+static int log_fileproc (void *callerdat, struct file_info *finfo);
+static struct option_revlist *log_parse_revlist (const char *);
+static void log_parse_date (struct log_data *, const char *);
+static void log_parse_list (List **, const char *);
+static struct revlist *log_expand_revlist (RCSNode *, char *,
+                                           struct option_revlist *, int);
+static void log_free_revlist (struct revlist *);
+static int log_version_requested (struct log_data *, struct revlist *,
+                                        RCSNode *, RCSVers *);
+static int log_symbol (Node *, void *);
+static int log_count (Node *, void *);
+static int log_fix_singledate (Node *, void *);
+static int log_count_print (Node *, void *);
+static void log_tree (struct log_data *, struct revlist *,
+                            RCSNode *, const char *);
+static void log_abranch (struct log_data *, struct revlist *,
+                               RCSNode *, const char *);
+static void log_version (struct log_data *, struct revlist *,
+                               RCSNode *, RCSVers *, int);
+static int log_branch (Node *, void *);
+static int version_compare (const char *, const char *, int);
+
+static struct log_data log_data;
+static int is_rlog;
+
+static const char *const log_usage[] =
+{
+    "Usage: %s %s [-lRhtNb] [-r[revisions]] [-d dates] [-s states]\n",
+    "    [-w[logins]] [files...]\n",
+    "\t-l\tLocal directory only, no recursion.\n",
+    "\t-b\tOnly list revisions on the default branch.\n",
+    "\t-h\tOnly print header.\n",
+    "\t-R\tOnly print name of RCS file.\n",
+    "\t-t\tOnly print header and descriptive text.\n",
+    "\t-N\tDo not list tags.\n",
+    "\t-S\tDo not print name/header if no revisions selected.  -d, -r,\n",
+    "\t\t-s, & -w have little effect in conjunction with -b, -h, -R, and\n",
+    "\t\t-t without this option.\n",
+    "\t-r[revisions]\tA comma-separated list of revisions to print:\n",
+    "\t   rev1:rev2   Between rev1 and rev2, including rev1 and rev2.\n",
+    "\t   rev1::rev2  Between rev1 and rev2, excluding rev1.\n",
+    "\t   rev:        rev and following revisions on the same branch.\n",
+    "\t   rev::       After rev on the same branch.\n",
+    "\t   :rev        rev and previous revisions on the same branch.\n",
+    "\t   ::rev       rev and previous revisions on the same branch.\n",
+    "\t   rev         Just rev.\n",
+    "\t   branch      All revisions on the branch.\n",
+    "\t   branch.     The last revision on the branch.\n",
+    "\t-d dates\tA semicolon-separated list of dates\n",
+    "\t        \t(D1<D2 for range, D for latest before).\n",
+    "\t-s states\tOnly list revisions with specified states.\n",
+    "\t-w[logins]\tOnly list revisions checked in by specified logins.\n",
+    "(Specify the --help global option for a list of other help options)\n",
+    NULL
+};
+
+#ifdef CLIENT_SUPPORT
+
+
+
+/* Helper function for send_arg_list.  */
+static int
+send_one (Node *node, void *closure)
+{
+    char *option = closure;
+
+    send_to_server ("Argument ", 0);
+    send_to_server (option, 0);
+    if (strcmp (node->key, "@@MYSELF") == 0)
+       /* It is a bare -w option.  Note that we must send it as
+          -w rather than messing with getcaller() or something (which on
+          the client will return garbage).  */
+       ;
+    else
+       send_to_server (node->key, 0);
+    send_to_server ("\012", 0);
+    return 0;
+}
+
+
+
+/* For each element in ARG, send an argument consisting of OPTION
+   concatenated with that element.  */
+static void
+send_arg_list (char *option, List *arg)
+{
+    if (arg == NULL)
+       return;
+    walklist (arg, send_one, option);
+}
+
+#endif
+
+
+
+int
+cvslog (int argc, char **argv)
+{
+    int c;
+    int err = 0;
+    int local = 0;
+    struct option_revlist **prl;
+
+    is_rlog = (strcmp (cvs_cmd_name, "rlog") == 0);
+
+    if (argc == -1)
+       usage (log_usage);
+
+    memset (&log_data, 0, sizeof log_data);
+    prl = &log_data.revlist;
+
+    optind = 0;
+    while ((c = getopt (argc, argv, "+bd:hlNSRr::s:tw::")) != -1)
+    {
+       switch (c)
+       {
+           case 'b':
+               log_data.default_branch = 1;
+               break;
+           case 'd':
+               log_parse_date (&log_data, optarg);
+               break;
+           case 'h':
+               log_data.header = 1;
+               break;
+           case 'l':
+               local = 1;
+               break;
+           case 'N':
+               log_data.notags = 1;
+               break;
+           case 'S':
+               log_data.sup_header = 1;
+               break;
+           case 'R':
+               log_data.nameonly = 1;
+               break;
+           case 'r':
+               *prl = log_parse_revlist (optarg);
+               prl = &(*prl)->next;
+               break;
+           case 's':
+               log_parse_list (&log_data.statelist, optarg);
+               break;
+           case 't':
+               log_data.long_header = 1;
+               break;
+           case 'w':
+               if (optarg != NULL)
+                   log_parse_list (&log_data.authorlist, optarg);
+               else
+                   log_parse_list (&log_data.authorlist, "@@MYSELF");
+               break;
+           case '?':
+           default:
+               usage (log_usage);
+               break;
+       }
+    }
+    argc -= optind;
+    argv += optind;
+
+    wrap_setup ();
+
+#ifdef CLIENT_SUPPORT
+    if (current_parsed_root->isremote)
+    {
+       struct datelist *p;
+       struct option_revlist *rp;
+       char datetmp[MAXDATELEN];
+
+       /* We're the local client.  Fire up the remote server.  */
+       start_server ();
+
+       if (is_rlog && !supported_request ("rlog"))
+           error (1, 0, "server does not support rlog");
+
+       ign_setup ();
+
+       if (log_data.default_branch)
+           send_arg ("-b");
+
+       while (log_data.datelist != NULL)
+       {
+           p = log_data.datelist;
+           log_data.datelist = p->next;
+           send_to_server ("Argument -d\012", 0);
+           send_to_server ("Argument ", 0);
+           date_to_internet (datetmp, p->start);
+           send_to_server (datetmp, 0);
+           if (p->inclusive)
+               send_to_server ("<=", 0);
+           else
+               send_to_server ("<", 0);
+           date_to_internet (datetmp, p->end);
+           send_to_server (datetmp, 0);
+           send_to_server ("\012", 0);
+           if (p->start)
+               free (p->start);
+           if (p->end)
+               free (p->end);
+           free (p);
+       }
+       while (log_data.singledatelist != NULL)
+       {
+           p = log_data.singledatelist;
+           log_data.singledatelist = p->next;
+           send_to_server ("Argument -d\012", 0);
+           send_to_server ("Argument ", 0);
+           date_to_internet (datetmp, p->end);
+           send_to_server (datetmp, 0);
+           send_to_server ("\012", 0);
+           if (p->end)
+               free (p->end);
+           free (p);
+       }
+           
+       if (log_data.header)
+           send_arg ("-h");
+       if (local)
+           send_arg("-l");
+       if (log_data.notags)
+           send_arg("-N");
+       if (log_data.sup_header)
+           send_arg("-S");
+       if (log_data.nameonly)
+           send_arg("-R");
+       if (log_data.long_header)
+           send_arg("-t");
+
+       while (log_data.revlist != NULL)
+       {
+           rp = log_data.revlist;
+           log_data.revlist = rp->next;
+           send_to_server ("Argument -r", 0);
+           if (rp->branchhead)
+           {
+               if (rp->first != NULL)
+                   send_to_server (rp->first, 0);
+               send_to_server (".", 1);
+           }
+           else
+           {
+               if (rp->first != NULL)
+                   send_to_server (rp->first, 0);
+               send_to_server (":", 1);
+               if (!rp->inclusive)
+                   send_to_server (":", 1);
+               if (rp->last != NULL)
+                   send_to_server (rp->last, 0);
+           }
+           send_to_server ("\012", 0);
+           if (rp->first)
+               free (rp->first);
+           if (rp->last)
+               free (rp->last);
+           free (rp);
+       }
+       send_arg_list ("-s", log_data.statelist);
+       dellist (&log_data.statelist);
+       send_arg_list ("-w", log_data.authorlist);
+       dellist (&log_data.authorlist);
+       send_arg ("--");
+
+       if (is_rlog)
+       {
+           int i;
+           for (i = 0; i < argc; i++)
+               send_arg (argv[i]);
+           send_to_server ("rlog\012", 0);
+       }
+       else
+       {
+           send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
+           send_file_names (argc, argv, SEND_EXPAND_WILD);
+           send_to_server ("log\012", 0);
+       }
+        err = get_responses_and_close ();
+       return err;
+    }
+#endif
+
+    /* OK, now that we know we are local/server, we can resolve @@MYSELF
+       into our user name.  */
+    if (findnode (log_data.authorlist, "@@MYSELF") != NULL)
+       log_parse_list (&log_data.authorlist, getcaller ());
+
+    if (is_rlog)
+    {
+       DBM *db;
+       int i;
+       db = open_module ();
+       for (i = 0; i < argc; i++)
+       {
+             err += do_module (db, argv[i], MISC, "Logging", rlog_proc,
+                               NULL, 0, local, 0, 0, NULL);
+       }
+       close_module (db);
+    }
+    else
+    {
+        err = rlog_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, local, NULL,
+                         NULL);
+    }
+
+    while (log_data.revlist)
+    {
+       struct option_revlist *rl = log_data.revlist->next;
+       if (log_data.revlist->first)
+           free (log_data.revlist->first);
+       if (log_data.revlist->last)
+           free (log_data.revlist->last);
+       free (log_data.revlist);
+       log_data.revlist = rl;
+    }
+    while (log_data.datelist)
+    {
+       struct datelist *nd = log_data.datelist->next;
+       if (log_data.datelist->start)
+           free (log_data.datelist->start);
+       if (log_data.datelist->end)
+           free (log_data.datelist->end);
+       free (log_data.datelist);
+       log_data.datelist = nd;
+    }
+    while (log_data.singledatelist)
+    {
+       struct datelist *nd = log_data.singledatelist->next;
+       if (log_data.singledatelist->start)
+           free (log_data.singledatelist->start);
+       if (log_data.singledatelist->end)
+           free (log_data.singledatelist->end);
+       free (log_data.singledatelist);
+       log_data.singledatelist = nd;
+    }
+    dellist (&log_data.statelist);
+    dellist (&log_data.authorlist);
+
+    return err;
+}
+
+
+
+static int
+rlog_proc (int argc, char **argv, char *xwhere, char *mwhere, char *mfile,
+           int shorten, int local, char *mname, char *msg)
+{
+    /* Begin section which is identical to patch_proc--should this
+       be abstracted out somehow?  */
+    char *myargv[2];
+    int err = 0;
+    int which;
+    char *repository = NULL;
+    char *where;
+
+    if (is_rlog)
+    {
+       repository = xmalloc (strlen (current_parsed_root->directory)
+                              + strlen (argv[0])
+                             + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2);
+       (void)sprintf (repository, "%s/%s",
+                       current_parsed_root->directory, argv[0]);
+       where = xmalloc (strlen (argv[0])
+                         + (mfile == NULL ? 0 : strlen (mfile) + 1)
+                        + 1);
+       (void)strcpy (where, argv[0]);
+
+       /* If mfile isn't null, we need to set up to do only part of theu
+         * module.
+         */
+       if (mfile != NULL)
+       {
+           char *cp;
+           char *path;
+
+           /* If the portion of the module is a path, put the dir part on
+             * repos.
+             */
+           if ((cp = strrchr (mfile, '/')) != NULL)
+           {
+               *cp = '\0';
+               (void)strcat (repository, "/");
+               (void)strcat (repository, mfile);
+               (void)strcat (where, "/");
+               (void)strcat (where, mfile);
+               mfile = cp + 1;
+           }
+
+           /* take care of the rest */
+           path = Xasprintf ("%s/%s", repository, mfile);
+           if (isdir (path))
+           {
+               /* directory means repository gets the dir tacked on */
+               (void)strcpy (repository, path);
+               (void)strcat (where, "/");
+               (void)strcat (where, mfile);
+           }
+           else
+           {
+               myargv[0] = argv[0];
+               myargv[1] = mfile;
+               argc = 2;
+               argv = myargv;
+           }
+           free (path);
+       }
+
+       /* cd to the starting repository */
+       if (CVS_CHDIR (repository) < 0)
+       {
+           error (0, errno, "cannot chdir to %s", repository);
+           free (repository);
+           free (where);
+           return 1;
+       }
+       /* End section which is identical to patch_proc.  */
+
+       which = W_REPOS | W_ATTIC;
+    }
+    else
+    {
+        repository = NULL;
+        where = NULL;
+        which = W_LOCAL | W_REPOS | W_ATTIC;
+    }
+
+    err = start_recursion (log_fileproc, NULL, log_dirproc,
+                          NULL, &log_data,
+                          argc - 1, argv + 1, local, which, 0, CVS_LOCK_READ,
+                          where, 1, repository);
+
+    if (!(which & W_LOCAL)) free (repository);
+    if (where) free (where);
+
+    return err;
+}
+
+
+
+/*
+ * Parse a revision list specification.
+ */
+static struct option_revlist *
+log_parse_revlist (const char *argstring)
+{
+    char *orig_copy, *copy;
+    struct option_revlist *ret, **pr;
+
+    /* Unfortunately, rlog accepts -r without an argument to mean that
+       latest revision on the default branch, so we must support that
+       for compatibility.  */
+    if (argstring == NULL)
+       argstring = "";
+
+    ret = NULL;
+    pr = &ret;
+
+    /* Copy the argument into memory so that we can change it.  We
+       don't want to change the argument because, at least as of this
+       writing, we will use it if we send the arguments to the server.  */
+    orig_copy = copy = xstrdup (argstring);
+    while (copy != NULL)
+    {
+       char *comma;
+       struct option_revlist *r;
+
+       comma = strchr (copy, ',');
+       if (comma != NULL)
+           *comma++ = '\0';
+
+       r = xmalloc (sizeof *r);
+       r->next = NULL;
+       r->first = copy;
+       r->branchhead = 0;
+       r->last = strchr (copy, ':');
+       if (r->last != NULL)
+       {
+           *r->last++ = '\0';
+           r->inclusive = (*r->last != ':');
+           if (!r->inclusive)
+               r->last++;
+       }
+       else
+       {
+           r->last = r->first;
+           r->inclusive = 1;
+           if (r->first[0] != '\0' && r->first[strlen (r->first) - 1] == '.')
+           {
+               r->branchhead = 1;
+               r->first[strlen (r->first) - 1] = '\0';
+           }
+       }
+
+       if (*r->first == '\0')
+           r->first = NULL;
+       if (*r->last == '\0')
+           r->last = NULL;
+
+       if (r->first != NULL)
+           r->first = xstrdup (r->first);
+       if (r->last != NULL)
+           r->last = xstrdup (r->last);
+
+       *pr = r;
+       pr = &r->next;
+
+       copy = comma;
+    }
+
+    free (orig_copy);
+    return ret;
+}
+
+
+
+/*
+ * Parse a date specification.
+ */
+static void
+log_parse_date (struct log_data *log_data, const char *argstring)
+{
+    char *orig_copy, *copy;
+
+    /* Copy the argument into memory so that we can change it.  We
+       don't want to change the argument because, at least as of this
+       writing, we will use it if we send the arguments to the server.  */
+    orig_copy = copy = xstrdup (argstring);
+    while (copy != NULL)
+    {
+       struct datelist *nd, **pd;
+       char *cpend, *cp, *ds, *de;
+
+       nd = xmalloc (sizeof *nd);
+
+       cpend = strchr (copy, ';');
+       if (cpend != NULL)
+           *cpend++ = '\0';
+
+       pd = &log_data->datelist;
+       nd->inclusive = 0;
+
+       if ((cp = strchr (copy, '>')) != NULL)
+       {
+           *cp++ = '\0';
+           if (*cp == '=')
+           {
+               ++cp;
+               nd->inclusive = 1;
+           }
+           ds = cp;
+           de = copy;
+       }
+       else if ((cp = strchr (copy, '<')) != NULL)
+       {
+           *cp++ = '\0';
+           if (*cp == '=')
+           {
+               ++cp;
+               nd->inclusive = 1;
+           }
+           ds = copy;
+           de = cp;
+       }
+       else
+       {
+           ds = NULL;
+           de = copy;
+           pd = &log_data->singledatelist;
+       }
+
+       if (ds == NULL)
+           nd->start = NULL;
+       else if (*ds != '\0')
+           nd->start = Make_Date (ds);
+       else
+       {
+         /* 1970 was the beginning of time, as far as get_date and
+            Make_Date are concerned.  FIXME: That is true only if time_t
+            is a POSIX-style time and there is nothing in ANSI that
+            mandates that.  It would be cleaner to set a flag saying
+            whether or not there is a start date.  */
+           nd->start = Make_Date ("1/1/1970 UTC");
+       }
+
+       if (*de != '\0')
+           nd->end = Make_Date (de);
+       else
+       {
+           /* We want to set the end date to some time sufficiently far
+              in the future to pick up all revisions that have been
+              created since the specified date and the time `cvs log'
+              completes.  FIXME: The date in question only makes sense
+              if time_t is a POSIX-style time and it is 32 bits
+              and signed.  We should instead be setting a flag saying
+              whether or not there is an end date.  Note that using
+              something like "next week" would break the testsuite (and,
+              perhaps less importantly, loses if the clock is set grossly
+              wrong).  */
+           nd->end = Make_Date ("2038-01-01");
+       }
+
+       nd->next = *pd;
+       *pd = nd;
+
+       copy = cpend;
+    }
+
+    free (orig_copy);
+}
+
+
+
+/*
+ * Parse a comma separated list of items, and add each one to *PLIST.
+ */
+static void
+log_parse_list (List **plist, const char *argstring)
+{
+    while (1)
+    {
+       Node *p;
+       char *cp;
+
+       p = getnode ();
+
+       cp = strchr (argstring, ',');
+       if (cp == NULL)
+           p->key = xstrdup (argstring);
+       else
+       {
+           size_t len;
+
+           len = cp - argstring;
+           p->key = xmalloc (len + 1);
+           strncpy (p->key, argstring, len);
+           p->key[len] = '\0';
+       }
+
+       if (*plist == NULL)
+           *plist = getlist ();
+       if (addnode (*plist, p) != 0)
+           freenode (p);
+
+       if (cp == NULL)
+           break;
+
+       argstring = cp + 1;
+    }
+}
+
+
+
+static int
+printlock_proc (Node *lock, void *foo)
+{
+    cvs_output ("\n\t", 2);
+    cvs_output (lock->data, 0);
+    cvs_output (": ", 2);
+    cvs_output (lock->key, 0);
+    return 0;
+}
+
+
+
+/*
+ * Do an rlog on a file
+ */
+static int
+log_fileproc (void *callerdat, struct file_info *finfo)
+{
+    struct log_data *log_data = callerdat;
+    Node *p;
+    char *baserev;
+    int selrev = -1;
+    RCSNode *rcsfile;
+    char buf[50];
+    struct revlist *revlist = NULL;
+    struct log_data_and_rcs log_data_and_rcs;
+
+    rcsfile = finfo->rcs;
+    p = findnode (finfo->entries, finfo->file);
+    if (p != NULL)
+    {
+       Entnode *e = p->data;
+       baserev = e->version;
+       if (baserev[0] == '-') ++baserev;
+    }
+    else
+       baserev = NULL;
+
+    if (rcsfile == NULL)
+    {
+       /* no rcs file.  What *do* we know about this file? */
+       if (baserev != NULL)
+       {
+           if (baserev[0] == '0' && baserev[1] == '\0')
+           {
+               if (!really_quiet)
+                   error (0, 0, "%s has been added, but not committed",
+                          finfo->file);
+               return 0;
+           }
+       }
+       
+       if (!really_quiet)
+           error (0, 0, "nothing known about %s", finfo->file);
+       
+       return 1;
+    }
+
+    if (log_data->sup_header || !log_data->nameonly)
+    {
+
+       /* We will need all the information in the RCS file.  */
+       RCS_fully_parse (rcsfile);
+
+       /* Turn any symbolic revisions in the revision list into numeric
+          revisions.  */
+       revlist = log_expand_revlist (rcsfile, baserev, log_data->revlist,
+                                     log_data->default_branch);
+       if (log_data->sup_header
+            || (!log_data->header && !log_data->long_header))
+       {
+           log_data_and_rcs.log_data = log_data;
+           log_data_and_rcs.revlist = revlist;
+           log_data_and_rcs.rcs = rcsfile;
+
+           /* If any single dates were specified, we need to identify the
+              revisions they select.  Each one selects the single
+              revision, which is otherwise selected, of that date or
+              earlier.  The log_fix_singledate routine will fill in the
+              start date for each specific revision.  */
+           if (log_data->singledatelist != NULL)
+               walklist (rcsfile->versions, log_fix_singledate,
+                         &log_data_and_rcs);
+
+           selrev = walklist (rcsfile->versions, log_count_print,
+                              &log_data_and_rcs);
+           if (log_data->sup_header && selrev == 0)
+           {
+               log_free_revlist (revlist);
+               return 0;
+           }
+       }
+
+    }
+
+    if (log_data->nameonly)
+    {
+       cvs_output (rcsfile->print_path, 0);
+       cvs_output ("\n", 1);
+       log_free_revlist (revlist);
+       return 0;
+    }
+
+    /* The output here is intended to be exactly compatible with the
+       output of rlog.  I'm not sure whether this code should be here
+       or in rcs.c; I put it here because it is specific to the log
+       function, even though it uses information gathered by the
+       functions in rcs.c.  */
+
+    cvs_output ("\n", 1);
+
+    cvs_output ("RCS file: ", 0);
+    cvs_output (rcsfile->print_path, 0);
+
+    if (!is_rlog)
+    {
+       cvs_output ("\nWorking file: ", 0);
+       if (finfo->update_dir[0] != '\0')
+       {
+           cvs_output (finfo->update_dir, 0);
+           cvs_output ("/", 0);
+       }
+       cvs_output (finfo->file, 0);
+    }
+
+    cvs_output ("\nhead:", 0);
+    if (rcsfile->head != NULL)
+    {
+       cvs_output (" ", 1);
+       cvs_output (rcsfile->head, 0);
+    }
+
+    cvs_output ("\nbranch:", 0);
+    if (rcsfile->branch != NULL)
+    {
+       cvs_output (" ", 1);
+       cvs_output (rcsfile->branch, 0);
+    }
+
+    cvs_output ("\nlocks:", 0);
+    if (rcsfile->strict_locks)
+       cvs_output (" strict", 0);
+    walklist (RCS_getlocks (rcsfile), printlock_proc, NULL);
+
+    cvs_output ("\naccess list:", 0);
+    if (rcsfile->access != NULL)
+    {
+       const char *cp;
+
+       cp = rcsfile->access;
+       while (*cp != '\0')
+       {
+               const char *cp2;
+
+               cvs_output ("\n\t", 2);
+               cp2 = cp;
+               while (!isspace ((unsigned char)*cp2) && *cp2 != '\0')
+                   ++cp2;
+               cvs_output (cp, cp2 - cp);
+               cp = cp2;
+               while (isspace ((unsigned char)*cp) && *cp != '\0')
+                   ++cp;
+       }
+    }
+
+    if (!log_data->notags)
+    {
+       List *syms;
+
+       cvs_output ("\nsymbolic names:", 0);
+       syms = RCS_symbols (rcsfile);
+       walklist (syms, log_symbol, NULL);
+    }
+
+    cvs_output ("\nkeyword substitution: ", 0);
+    if (rcsfile->expand == NULL)
+       cvs_output ("kv", 2);
+    else
+       cvs_output (rcsfile->expand, 0);
+
+    cvs_output ("\ntotal revisions: ", 0);
+    sprintf (buf, "%d", walklist (rcsfile->versions, log_count, NULL));
+    cvs_output (buf, 0);
+
+    if (selrev >= 0)
+    {
+       cvs_output (";\tselected revisions: ", 0);
+       sprintf (buf, "%d", selrev);
+       cvs_output (buf, 0);
+    }
+
+    cvs_output ("\n", 1);
+
+    if (!log_data->header || log_data->long_header)
+    {
+       cvs_output ("description:\n", 0);
+       if (rcsfile->desc != NULL)
+           cvs_output (rcsfile->desc, 0);
+    }
+
+    if (!log_data->header && ! log_data->long_header && rcsfile->head != NULL)
+    {
+       p = findnode (rcsfile->versions, rcsfile->head);
+       if (p == NULL)
+           error (1, 0, "can not find head revision in `%s'",
+                  finfo->fullname);
+       while (p != NULL)
+       {
+           RCSVers *vers = p->data;
+
+           log_version (log_data, revlist, rcsfile, vers, 1);
+           if (vers->next == NULL)
+               p = NULL;
+           else
+           {
+               p = findnode (rcsfile->versions, vers->next);
+               if (p == NULL)
+                   error (1, 0, "can not find next revision `%s' in `%s'",
+                          vers->next, finfo->fullname);
+           }
+       }
+
+       log_tree (log_data, revlist, rcsfile, rcsfile->head);
+    }
+
+    cvs_output("\
+=============================================================================\n",
+              0);
+
+    /* Free up the new revlist and restore the old one.  */
+    log_free_revlist (revlist);
+
+    /* If singledatelist is not NULL, free up the start dates we added
+       to it.  */
+    if (log_data->singledatelist != NULL)
+    {
+       struct datelist *d;
+
+       for (d = log_data->singledatelist; d != NULL; d = d->next)
+       {
+           if (d->start != NULL)
+               free (d->start);
+           d->start = NULL;
+       }
+    }
+
+    return 0;
+}
+
+
+
+/*
+ * Fix up a revision list in order to compare it against versions.
+ * Expand any symbolic revisions.
+ */
+static struct revlist *
+log_expand_revlist (RCSNode *rcs, char *baserev,
+                    struct option_revlist *revlist, int default_branch)
+{
+    struct option_revlist *r;
+    struct revlist *ret, **pr;
+
+    ret = NULL;
+    pr = &ret;
+    for (r = revlist; r != NULL; r = r->next)
+    {
+       struct revlist *nr;
+
+       nr = xmalloc (sizeof *nr);
+       nr->inclusive = r->inclusive;
+
+       if (r->first == NULL && r->last == NULL)
+       {
+           /* If both first and last are NULL, it means that we want
+              just the head of the default branch, which is RCS_head.  */
+           nr->first = RCS_head (rcs);
+           if (!nr->first)
+           {
+               if (!really_quiet)
+                   error (0, 0, "No head revision in archive `%s'.",
+                          rcs->path);
+               nr->last = NULL;
+               nr->fields = 0;
+           }
+           else
+           {
+               nr->last = xstrdup (nr->first);
+               nr->fields = numdots (nr->first) + 1;
+           }
+       }
+       else if (r->branchhead)
+       {
+           char *branch;
+
+           /* Print just the head of the branch.  */
+           if (isdigit ((unsigned char) r->first[0]))
+               nr->first = RCS_getbranch (rcs, r->first, 1);
+           else
+           {
+               branch = RCS_whatbranch (rcs, r->first);
+               if (branch == NULL)
+                   nr->first = NULL;
+               else
+               {
+                   nr->first = RCS_getbranch (rcs, branch, 1);
+                   free (branch);
+               }
+           }
+           if (!nr->first)
+           {
+               if (!really_quiet)
+                   error (0, 0, "warning: no branch `%s' in `%s'",
+                          r->first, rcs->print_path);
+               nr->last = NULL;
+               nr->fields = 0;
+           }
+           else
+           {
+               nr->last = xstrdup (nr->first);
+               nr->fields = numdots (nr->first) + 1;
+           }
+       }
+       else
+       {
+           if (r->first == NULL || isdigit ((unsigned char) r->first[0]))
+               nr->first = xstrdup (r->first);
+           else
+           {
+               if (baserev && strcmp (r->first, TAG_BASE) == 0)
+                   nr->first = xstrdup (baserev);
+               else if (RCS_nodeisbranch (rcs, r->first))
+                   nr->first = RCS_whatbranch (rcs, r->first);
+               else
+                   nr->first = RCS_gettag (rcs, r->first, 1, NULL);
+               if (nr->first == NULL && !really_quiet)
+               {
+                   error (0, 0, "warning: no revision `%s' in `%s'",
+                          r->first, rcs->print_path);
+               }
+           }
+
+           if (r->last == r->first || (r->last != NULL && r->first != NULL &&
+                                       strcmp (r->last, r->first) == 0))
+               nr->last = xstrdup (nr->first);
+           else if (r->last == NULL || isdigit ((unsigned char) r->last[0]))
+               nr->last = xstrdup (r->last);
+           else
+           {
+               if (baserev && strcmp (r->last, TAG_BASE) == 0)
+                   nr->last = xstrdup (baserev);
+               else if (RCS_nodeisbranch (rcs, r->last))
+                   nr->last = RCS_whatbranch (rcs, r->last);
+               else
+                   nr->last = RCS_gettag (rcs, r->last, 1, NULL);
+               if (nr->last == NULL && !really_quiet)
+               {
+                   error (0, 0, "warning: no revision `%s' in `%s'",
+                          r->last, rcs->print_path);
+               }
+           }
+
+           /* Process the revision numbers the same way that rlog
+               does.  This code is a bit cryptic for my tastes, but
+               keeping the same implementation as rlog ensures a
+               certain degree of compatibility.  */
+           if (r->first == NULL && nr->last != NULL)
+           {
+               nr->fields = numdots (nr->last) + 1;
+               if (nr->fields < 2)
+                   nr->first = xstrdup (".0");
+               else
+               {
+                   char *cp;
+
+                   nr->first = xstrdup (nr->last);
+                   cp = strrchr (nr->first, '.');
+                   assert (cp);
+                   strcpy (cp + 1, "0");
+               }
+           }
+           else if (r->last == NULL && nr->first != NULL)
+           {
+               nr->fields = numdots (nr->first) + 1;
+               nr->last = xstrdup (nr->first);
+               if (nr->fields < 2)
+                   nr->last[0] = '\0';
+               else
+               {
+                   char *cp;
+
+                   cp = strrchr (nr->last, '.');
+                   assert (cp);
+                   *cp = '\0';
+               }
+           }
+           else if (nr->first == NULL || nr->last == NULL)
+               nr->fields = 0;
+           else if (strcmp (nr->first, nr->last) == 0)
+               nr->fields = numdots (nr->last) + 1;
+           else
+           {
+               int ord;
+               int dots1 = numdots (nr->first);
+               int dots2 = numdots (nr->last);
+               if (dots1 > dots2 || (dots1 == dots2 &&
+                   version_compare (nr->first, nr->last, dots1 + 1) > 0))
+               {
+                   char *tmp = nr->first;
+                   nr->first = nr->last;
+                   nr->last = tmp;
+                   nr->fields = dots2 + 1;
+                   dots2 = dots1;
+                   dots1 = nr->fields - 1;
+               }
+               else
+                   nr->fields = dots1 + 1;
+               dots1 += (nr->fields & 1);
+               ord = version_compare (nr->first, nr->last, dots1);
+               if (ord > 0 || (nr->fields > 2 && ord < 0))
+               {
+                   error (0, 0,
+                          "invalid branch or revision pair %s:%s in `%s'",
+                          r->first, r->last, rcs->print_path);
+                   free (nr->first);
+                   nr->first = NULL;
+                   free (nr->last);
+                   nr->last = NULL;
+                   nr->fields = 0;
+               }
+               else
+               {
+                   if (nr->fields <= dots2 && (nr->fields & 1))
+                   {
+                       char *p = Xasprintf ("%s.0", nr->first);
+                       free (nr->first);
+                       nr->first = p;
+                       ++nr->fields;
+                   }
+                   while (nr->fields <= dots2)
+                   {
+                       char *p;
+                       int i;
+
+                       nr->next = NULL;
+                       *pr = nr;
+                       nr = xmalloc (sizeof *nr);
+                       nr->inclusive = 1;
+                       nr->first = xstrdup ((*pr)->last);
+                       nr->last = xstrdup ((*pr)->last);
+                       nr->fields = (*pr)->fields;
+                       p = (*pr)->last;
+                       for (i = 0; i < nr->fields; i++)
+                           p = strchr (p, '.') + 1;
+                       p[-1] = '\0';
+                       p = strchr (nr->first + (p - (*pr)->last), '.');
+                       if (p != NULL)
+                       {
+                           *++p = '0';
+                           *++p = '\0';
+                           nr->fields += 2;
+                       }
+                       else
+                           ++nr->fields;
+                       pr = &(*pr)->next;
+                   }
+               }
+           }
+       }
+
+       nr->next = NULL;
+       *pr = nr;
+       pr = &nr->next;
+    }
+
+    /* If the default branch was requested, add a revlist entry for
+       it.  This is how rlog handles this option.  */
+    if (default_branch
+       && (rcs->head != NULL || rcs->branch != NULL))
+    {
+       struct revlist *nr;
+
+       nr = xmalloc (sizeof *nr);
+       if (rcs->branch != NULL)
+           nr->first = xstrdup (rcs->branch);
+       else
+       {
+           char *cp;
+
+           nr->first = xstrdup (rcs->head);
+           assert (nr->first);
+           cp = strrchr (nr->first, '.');
+           assert (cp);
+           *cp = '\0';
+       }
+       nr->last = xstrdup (nr->first);
+       nr->fields = numdots (nr->first) + 1;
+       nr->inclusive = 1;
+
+       nr->next = NULL;
+       *pr = nr;
+    }
+
+    return ret;
+}
+
+
+
+/*
+ * Free a revlist created by log_expand_revlist.
+ */
+static void
+log_free_revlist (struct revlist *revlist)
+{
+    struct revlist *r;
+
+    r = revlist;
+    while (r != NULL)
+    {
+       struct revlist *next;
+
+       if (r->first != NULL)
+           free (r->first);
+       if (r->last != NULL)
+           free (r->last);
+       next = r->next;
+       free (r);
+       r = next;
+    }
+}
+
+
+
+/*
+ * Return nonzero if a revision should be printed, based on the
+ * options provided.
+ */
+static int
+log_version_requested (struct log_data *log_data, struct revlist *revlist,
+                       RCSNode *rcs, RCSVers *vnode)
+{
+    /* Handle the list of states from the -s option.  */
+    if (log_data->statelist != NULL
+       && findnode (log_data->statelist, vnode->state) == NULL)
+    {
+       return 0;
+    }
+
+    /* Handle the list of authors from the -w option.  */
+    if (log_data->authorlist != NULL)
+    {
+       if (vnode->author != NULL
+           && findnode (log_data->authorlist, vnode->author) == NULL)
+       {
+           return 0;
+       }
+    }
+
+    /* rlog considers all the -d options together when it decides
+       whether to print a revision, so we must be compatible.  */
+    if (log_data->datelist != NULL || log_data->singledatelist != NULL)
+    {
+       struct datelist *d;
+
+       for (d = log_data->datelist; d != NULL; d = d->next)
+       {
+           int cmp;
+
+           cmp = RCS_datecmp (vnode->date, d->start);
+           if (cmp > 0 || (cmp == 0 && d->inclusive))
+           {
+               cmp = RCS_datecmp (vnode->date, d->end);
+               if (cmp < 0 || (cmp == 0 && d->inclusive))
+                   break;
+           }
+       }
+
+       if (d == NULL)
+       {
+           /* Look through the list of specific dates.  We want to
+              select the revision with the exact date found in the
+              start field.  The commit code ensures that it is
+              impossible to check in multiple revisions of a single
+              file in a single second, so checking the date this way
+              should never select more than one revision.  */
+           for (d = log_data->singledatelist; d != NULL; d = d->next)
+           {
+               if (d->start != NULL
+                   && RCS_datecmp (vnode->date, d->start) == 0)
+               {
+                   break;
+               }
+           }
+
+           if (d == NULL)
+               return 0;
+       }
+    }
+
+    /* If the -r or -b options were used, REVLIST will be non NULL,
+       and we print the union of the specified revisions.  */
+    if (revlist != NULL)
+    {
+       char *v;
+       int vfields;
+       struct revlist *r;
+
+       /* This code is taken from rlog.  */
+       v = vnode->version;
+       vfields = numdots (v) + 1;
+       for (r = revlist; r != NULL; r = r->next)
+       {
+            if (vfields == r->fields + (r->fields & 1) &&
+                (r->inclusive ? version_compare (v, r->first, r->fields) >= 0 :
+                                version_compare (v, r->first, r->fields) > 0)
+                && version_compare (v, r->last, r->fields) <= 0)
+           {
+               return 1;
+           }
+       }
+
+       /* If we get here, then the -b and/or the -r option was used,
+           but did not match this revision, so we reject it.  */
+
+       return 0;
+    }
+
+    /* By default, we print all revisions.  */
+    return 1;
+}
+
+
+
+/*
+ * Output a single symbol.  This is called via walklist.
+ */
+/*ARGSUSED*/
+static int
+log_symbol (Node *p, void *closure)
+{
+    cvs_output ("\n\t", 2);
+    cvs_output (p->key, 0);
+    cvs_output (": ", 2);
+    cvs_output (p->data, 0);
+    return 0;
+}
+
+
+
+/*
+ * Count the number of entries on a list.  This is called via walklist.
+ */
+/*ARGSUSED*/
+static int
+log_count (Node *p, void *closure)
+{
+    return 1;
+}
+
+
+
+/*
+ * Sort out a single date specification by narrowing down the date
+ * until we find the specific selected revision.
+ */
+static int
+log_fix_singledate (Node *p, void *closure)
+{
+    struct log_data_and_rcs *data = closure;
+    Node *pv;
+    RCSVers *vnode;
+    struct datelist *holdsingle, *holddate;
+    int requested;
+
+    pv = findnode (data->rcs->versions, p->key);
+    if (pv == NULL)
+       error (1, 0, "missing version `%s' in RCS file `%s'",
+              p->key, data->rcs->print_path);
+    vnode = pv->data;
+
+    /* We are only interested if this revision passes any other tests.
+       Temporarily clear log_data->singledatelist to avoid confusing
+       log_version_requested.  We also clear log_data->datelist,
+       because rlog considers all the -d options together.  We don't
+       want to reject a revision because it does not match a date pair
+       if we are going to select it on the basis of the singledate.  */
+    holdsingle = data->log_data->singledatelist;
+    data->log_data->singledatelist = NULL;
+    holddate = data->log_data->datelist;
+    data->log_data->datelist = NULL;
+    requested = log_version_requested (data->log_data, data->revlist,
+                                      data->rcs, vnode);
+    data->log_data->singledatelist = holdsingle;
+    data->log_data->datelist = holddate;
+
+    if (requested)
+    {
+       struct datelist *d;
+
+       /* For each single date, if this revision is before the
+          specified date, but is closer than the previously selected
+          revision, select it instead.  */
+       for (d = data->log_data->singledatelist; d != NULL; d = d->next)
+       {
+           if (RCS_datecmp (vnode->date, d->end) <= 0
+               && (d->start == NULL
+                   || RCS_datecmp (vnode->date, d->start) > 0))
+           {
+               if (d->start != NULL)
+                   free (d->start);
+               d->start = xstrdup (vnode->date);
+           }
+       }
+    }
+
+    return 0;
+}
+
+
+
+/*
+ * Count the number of revisions we are going to print.
+ */
+static int
+log_count_print (Node *p, void *closure)
+{
+    struct log_data_and_rcs *data = closure;
+    Node *pv;
+
+    pv = findnode (data->rcs->versions, p->key);
+    if (pv == NULL)
+       error (1, 0, "missing version `%s' in RCS file `%s'",
+              p->key, data->rcs->print_path);
+    if (log_version_requested (data->log_data, data->revlist, data->rcs,
+                              pv->data))
+       return 1;
+    else
+       return 0;
+}
+
+
+
+/*
+ * Print the list of changes, not including the trunk, in reverse
+ * order for each branch.
+ */
+static void
+log_tree (struct log_data *log_data, struct revlist *revlist, RCSNode *rcs,
+          const char *ver)
+{
+    Node *p;
+    RCSVers *vnode;
+
+    p = findnode (rcs->versions, ver);
+    if (p == NULL)
+       error (1, 0, "missing version `%s' in RCS file `%s'",
+              ver, rcs->print_path);
+    vnode = p->data;
+    if (vnode->next != NULL)
+       log_tree (log_data, revlist, rcs, vnode->next);
+    if (vnode->branches != NULL)
+    {
+       Node *head, *branch;
+
+       /* We need to do the branches in reverse order.  This breaks
+           the List abstraction, but so does most of the branch
+           manipulation in rcs.c.  */
+       head = vnode->branches->list;
+       for (branch = head->prev; branch != head; branch = branch->prev)
+       {
+           log_abranch (log_data, revlist, rcs, branch->key);
+           log_tree (log_data, revlist, rcs, branch->key);
+       }
+    }
+}
+
+
+
+/*
+ * Log the changes for a branch, in reverse order.
+ */
+static void
+log_abranch (struct log_data *log_data, struct revlist *revlist, RCSNode *rcs,
+             const char *ver)
+{
+    Node *p;
+    RCSVers *vnode;
+
+    p = findnode (rcs->versions, ver);
+    if (p == NULL)
+       error (1, 0, "missing version `%s' in RCS file `%s'",
+              ver, rcs->print_path);
+    vnode = p->data;
+    if (vnode->next != NULL)
+       log_abranch (log_data, revlist, rcs, vnode->next);
+    log_version (log_data, revlist, rcs, vnode, 0);
+}
+
+
+
+/*
+ * Print the log output for a single version.
+ */
+static void
+log_version (struct log_data *log_data, struct revlist *revlist, RCSNode *rcs, 
+             RCSVers *ver, int trunk)
+{
+    Node *p;
+    int year, mon, mday, hour, min, sec;
+    char buf[100];
+    Node *padd, *pdel;
+
+    if (! log_version_requested (log_data, revlist, rcs, ver))
+       return;
+
+    cvs_output ("----------------------------\nrevision ", 0);
+    cvs_output (ver->version, 0);
+
+    p = findnode (RCS_getlocks (rcs), ver->version);
+    if (p != NULL)
+    {
+       cvs_output ("\tlocked by: ", 0);
+       cvs_output (p->data, 0);
+       cvs_output (";", 1);
+    }
+    cvs_output ("\n", 1);
+
+    cvs_output_tagged ("text", "date: ");
+    (void)sscanf (ver->date, SDATEFORM, &year, &mon, &mday, &hour, &min,
+                 &sec);
+    if (year < 1900)
+       year += 1900;
+    sprintf (buf, "%04d-%02d-%02d %02d:%02d:%02d +0000", year, mon, mday,
+            hour, min, sec);
+    cvs_output_tagged ("date", buf);
+
+    cvs_output_tagged ("text", ";  author: ");
+    cvs_output_tagged ("text", ver->author);
+
+    cvs_output_tagged ("text", ";  state: ");
+    cvs_output_tagged ("text", ver->state);
+    cvs_output_tagged ("text", ";");
+
+    if (! trunk)
+    {
+       padd = findnode (ver->other, ";add");
+       pdel = findnode (ver->other, ";delete");
+    }
+    else if (ver->next == NULL)
+    {
+       padd = NULL;
+       pdel = NULL;
+    }
+    else
+    {
+       Node *nextp;
+       RCSVers *nextver;
+
+       nextp = findnode (rcs->versions, ver->next);
+       if (nextp == NULL)
+           error (1, 0, "missing version `%s' in `%s'", ver->next,
+                  rcs->print_path);
+       nextver = nextp->data;
+       pdel = findnode (nextver->other, ";add");
+       padd = findnode (nextver->other, ";delete");
+    }
+
+    if (padd != NULL)
+    {
+       assert (pdel);
+       cvs_output_tagged ("text", "  lines: +");
+       cvs_output_tagged ("text", padd->data);
+       cvs_output_tagged ("text", " -");
+       cvs_output_tagged ("text", pdel->data);
+        cvs_output_tagged ("text", ";");
+    }
+
+    p = findnode(ver->other_delta,"commitid");
+    if(p && p->data)
+    {
+        cvs_output_tagged ("text", "  commitid: ");
+       cvs_output_tagged ("text", p->data);
+       cvs_output_tagged ("text", ";");
+    }
+
+    cvs_output_tagged ("newline", NULL);
+
+    if (ver->branches != NULL)
+    {
+       cvs_output ("branches:", 0);
+       walklist (ver->branches, log_branch, NULL);
+       cvs_output ("\n", 1);
+    }
+
+    p = findnode (ver->other_delta, "openpgp-signatures");
+    if (p)
+    {
+       char *rawsig;
+       size_t rawsiglen;
+       struct buffer *membuf;
+       struct openpgp_signature sig;
+       int rc;
+
+       if (!base64_decode_alloc (p->data, p->len, &rawsig, &rawsiglen))
+           error (0, 0, "Unable to base64-decode OpenPGP signature.");
+       if (!rawsig)
+           xalloc_die ();
+
+       membuf = buf_nonio_initialize (NULL);
+       buf_output (membuf, rawsig, rawsiglen);
+
+       while (!(rc = parse_signature (membuf, &sig)))
+       {
+           unsigned long long printablesig = sig.keyid;
+           char *hexsig;
+           cvs_output_tagged ("openpgp-keyid-header",
+                              "OpenPGP signature using key ID 0x");
+           hexsig = Xasprintf ("%llx", printablesig);
+           cvs_output_tagged ("openpgp-keyid", hexsig);
+           free (hexsig);
+           cvs_output_tagged ("openpgp-keyid-footer", ";");
+           cvs_output_tagged ("newline", NULL);
+       }
+
+       if (rc == -2)
+           error (1, 0, "Memory allocation failure parsing signature.");
+
+       buf_free (membuf);
+    }
+
+    p = findnode (ver->other, "log");
+    /* The p->date == NULL case is the normal one for an empty log
+       message (rcs-14 in sanity.sh).  I don't think the case where
+       p->data is "" can happen (getrcskey in rcs.c checks for an
+       empty string and set the value to NULL in that case).  My guess
+       would be the p == NULL case would mean an RCS file which was
+       missing the "log" keyword (which is invalid according to
+       rcsfile.5).  */
+    if (p == NULL || p->data == NULL || *(char *)p->data == '\0')
+       cvs_output ("*** empty log message ***\n", 0);
+    else
+    {
+       /* 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);
+    }
+}
+
+
+
+/*
+ * Output a branch version.  This is called via walklist.
+ */
+/*ARGSUSED*/
+static int
+log_branch (Node *p, void *closure)
+{
+    cvs_output ("  ", 2);
+    if ((numdots (p->key) & 1) == 0)
+       cvs_output (p->key, 0);
+    else
+    {
+       char *f, *cp;
+
+       f = xstrdup (p->key);
+       cp = strrchr (f, '.');
+       *cp = '\0';
+       cvs_output (f, 0);
+       free (f);
+    }
+    cvs_output (";", 1);
+    return 0;
+}
+
+
+
+/*
+ * Print a warm fuzzy message
+ */
+/* ARGSUSED */
+static Dtype
+log_dirproc (void *callerdat, const char *dir, const char *repository,
+             const char *update_dir, List *entries)
+{
+    if (!isdir (dir))
+       return R_SKIP_ALL;
+
+    if (!quiet)
+       error (0, 0, "Logging %s", update_dir);
+    return R_PROCESS;
+}
+
+
+
+/*
+ * Compare versions.  This is taken from RCS compartial.
+ */
+static int
+version_compare (const char *v1, const char *v2, int len)
+{
+    while (1)
+    {
+       int d1, d2, r;
+
+       if (*v1 == '\0')
+           return 1;
+       if (*v2 == '\0')
+           return -1;
+
+       while (*v1 == '0')
+           ++v1;
+       for (d1 = 0; isdigit ((unsigned char) v1[d1]); ++d1)
+           ;
+
+       while (*v2 == '0')
+           ++v2;
+       for (d2 = 0; isdigit ((unsigned char) v2[d2]); ++d2)
+           ;
+
+       if (d1 != d2)
+           return d1 < d2 ? -1 : 1;
+
+       r = memcmp (v1, v2, d1);
+       if (r != 0)
+           return r;
+
+       --len;
+       if (len == 0)
+           return 0;
+
+       v1 += d1;
+       v2 += d1;
+
+       if (*v1 == '.')
+           ++v1;
+       if (*v2 == '.')
+           ++v2;
+    }
+}
Index: ccvs/src/sanity.sh
diff -u ccvs/src/sanity.sh:1.1105.2.1 ccvs/src/sanity.sh:1.1105.2.2
--- ccvs/src/sanity.sh:1.1105.2.1       Wed Dec 21 13:25:10 2005
+++ ccvs/src/sanity.sh  Fri Dec 30 23:26:32 2005
@@ -472,6 +472,9 @@
 # Regexp to match a commitid
 commitid="[a-zA-Z0-9]*"
 
+# Regexp to match an OpenPGP key id.
+keyid="0x[0-9a-f]*"
+
 # Regexp to match the name of a temporary file (from cvs_temp_name).
 # This appears in certain diff output.
 tempfile="cvs[-a-zA-Z0-9.%_]*"
@@ -1701,6 +1704,7 @@
 
 # If $GPG is set, create a key for /uu
 OPENPGP_PHRASE=
+log_keyid=
 if test x"$GPG" != xgpg; then
   $GPG --list-keys >>$LOGFILE 2>&1
   $GPG --import - <<EOF >>$LOGFILE 2>&1
@@ -1777,6 +1781,8 @@
   # The trailing EOL is important.
   OPENPGP_PHRASE='openpgp-signatures   @[a-zA-Z0-9/+]*=*@;
 '
+  log_keyid="OpenPGP signature using key ID 0x[0-9a-f]*;
+"
   gpg=:
 else # GPG not set
   echo "No working GPG was found.  This test suite will run, but OpenPGP" >&2
@@ -3290,15 +3296,15 @@
 ----------------------------
 revision 3\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}0 -0;  
commitid: ${commitid};
-bump-it
+${log_keyid}bump-it
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-modify-it
+${log_keyid}modify-it
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-add-it
+${log_keyid}add-it
 ============================================================================="
          dotest basica-o8 "${testcvs} -q update -p -r 1.1 ./ssfile" "ssfile"
          cd ../..
@@ -4301,7 +4307,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-second dive
+${log_keyid}second dive
 =============================================================================
 
 RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v
@@ -4318,7 +4324,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-second dive
+${log_keyid}second dive
 =============================================================================
 ${SPROG} log: Logging first-dir/dir1
 ${SPROG} log: file14 has been added, but not committed
@@ -4337,7 +4343,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-second dive
+${log_keyid}second dive
 =============================================================================
 
 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v
@@ -4354,7 +4360,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-second dive
+${log_keyid}second dive
 =============================================================================
 ${SPROG} log: Logging first-dir/dir1/dir2
 ${SPROG} log: file14 has been added, but not committed
@@ -4373,7 +4379,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-second dive
+${log_keyid}second dive
 =============================================================================
 
 RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v
@@ -4390,7 +4396,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-second dive
+${log_keyid}second dive
 ============================================================================="
 
                dotest basic2-14 "${testcvs} status first-dir" \
@@ -7442,29 +7448,29 @@
 ----------------------------
 revision 1\.3
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
-trunk-change-after-branch
+${log_keyid}trunk-change-after-branch
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
 branches:  1\.2\.2;
-trunk-before-branch
+${log_keyid}trunk-before-branch
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-add-it
+${log_keyid}add-it
 ----------------------------
 revision 1\.2\.2\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
-change-on-br1
+${log_keyid}change-on-br1
 ----------------------------
 revision 1\.2\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
 branches:  1\.2\.2\.1\.2;
-modify
+${log_keyid}modify
 ----------------------------
 revision 1\.2\.2\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
-modify
+${log_keyid}modify
 ============================================================================="
          dotest_fail branches-14.4 \
            "${testcvs} diff -c -r 1.1 -r 1.3 file4" \
@@ -8043,7 +8049,7 @@
 ----------------------------
 revision 1.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-add
+${log_keyid}add
 ============================================================================="
 
            dokeep
@@ -9081,15 +9087,15 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
 branches:  1\.1\.2;  1\.1\.4;
-add-it
+${log_keyid}add-it
 ----------------------------
 revision 1\.1\.4\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-modify-on-br2
+${log_keyid}modify-on-br2
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
-modify-on-br1
+${log_keyid}modify-on-br1
 ============================================================================="
 
          dokeep
@@ -9414,7 +9420,7 @@
 ----------------------------
 revision 1\.1\.3\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
-add
+${log_keyid}add
 ----------------------------
 revision 1\.1\.1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}0 -0;  
commitid: ${commitid};
@@ -9519,7 +9525,7 @@
 ----------------------------
 revision 1\.1\.1\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-modify
+${log_keyid}modify
 ============================================================================="
 
          dotest importc-9 "${testcvs} -q log bdir/subdir/file1" "
@@ -9663,7 +9669,7 @@
 ----------------------------
 revision 1\.1\.1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
-add
+${log_keyid}add
 ----------------------------
 revision 1\.1\.1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}0 -0;  
commitid: ${commitid};
@@ -9696,7 +9702,7 @@
 ----------------------------
 revision 1\.1\.1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
-add
+${log_keyid}add
 ----------------------------
 revision 1\.1\.1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}0 -0;  
commitid: ${commitid};
@@ -11365,7 +11371,7 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
 branches:  1.1.2;
-add-em
+${log_keyid}add-em
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: $username;  state: dead;  lines: ${PLUS}0 -0;  
commitid: ${commitid};
@@ -13262,7 +13268,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-add-it
+${log_keyid}add-it
 ============================================================================="
 
          dokeep
@@ -15776,7 +15782,7 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
 branches:  1\.1\.2;
-xCVS: ----------------------------------------------------------------------
+${log_keyid}xCVS: 
----------------------------------------------------------------------
 xCVS: Enter Log.  Lines beginning with .CVS:. are removed automatically
 xCVS:
 xCVS: Committing in .
@@ -15787,7 +15793,7 @@
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-xCVS: ----------------------------------------------------------------------
+${log_keyid}xCVS: 
----------------------------------------------------------------------
 xCVS: Enter Log.  Lines beginning with .CVS:. are removed automatically
 xCVS:
 xCVS: Committing in .
@@ -15814,7 +15820,7 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
 branches:  1\.1\.2;
-xCVS: ----------------------------------------------------------------------
+${log_keyid}xCVS: 
----------------------------------------------------------------------
 xCVS: Enter Log.  Lines beginning with .CVS:. are removed automatically
 xCVS:
 xCVS: Committing in .
@@ -15825,7 +15831,7 @@
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-xCVS: ----------------------------------------------------------------------
+${log_keyid}xCVS: 
----------------------------------------------------------------------
 xCVS: Enter Log.  Lines beginning with .CVS:. are removed automatically
 xCVS:
 xCVS: Modified Files:
@@ -15846,7 +15852,7 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
 branches:  1\.1\.2;
-xCVS: ----------------------------------------------------------------------
+${log_keyid}xCVS: 
----------------------------------------------------------------------
 xCVS: Enter Log.  Lines beginning with .CVS:. are removed automatically
 xCVS:
 xCVS: Committing in .
@@ -15857,7 +15863,7 @@
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-xCVS: ----------------------------------------------------------------------
+${log_keyid}xCVS: 
----------------------------------------------------------------------
 xCVS: Enter Log.  Lines beginning with .CVS:. are removed automatically
 xCVS:
 xCVS: Committing in .
@@ -16013,7 +16019,7 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: +0 -0;  
commitid: ${commitid};
-\*\*\* empty log message \*\*\*
+${log_keyid}\*\*\* empty log message \*\*\*
 ============================================================================="
 
          # clean up
@@ -18229,7 +18235,7 @@
 ----------------------------
 revision 1\.3
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-checkin
+${log_keyid}checkin
 ============================================================================="
 
          dokeep
@@ -20657,22 +20663,22 @@
          log_commitid="  commitid: ${commitid};"
          log_rev1="${log_dash} 1\.1
 ${log_date}${log_commitid}
-line 1
+${log_keyid}line 1
 
 line 2"
          log_rev2="${log_dash} 1\.2
 ${log_date}${log_lines}${log_commitid}
 branches:  1\.2\.2;
-2"
+${log_keyid}2"
          log_rev3="${log_dash} 1\.3
 ${log_date}${log_lines}${log_commitid}
-3"
+${log_keyid}3"
          log_rev1b="${log_dash} 1\.2\.2\.1
 ${log_date}${log_lines}${log_commitid}
-1b"
+${log_keyid}1b"
          log_rev2b="${log_dash} 1\.2\.2\.2
 ${log_date}${log_lines}${log_commitid}
-2b"
+${log_keyid}2b"
          
log_trailer='============================================================================='
 
          # Now, finally, test the log output.
@@ -21291,7 +21297,7 @@
 4"
          log_rev22="${log_dash} 1\.2
 ${log_date}${log_lines}${log_commitid}
-2"
+${log_keyid}2"
 
          dotest log-d3 "${testcvs} log -rbranch file1" \
 "${log_header1}
@@ -21643,7 +21649,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-1
+${log_keyid}1
 ============================================================================="
 
          fi # end of tests skipped for remote
@@ -21665,7 +21671,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-1
+${log_keyid}1
 ============================================================================="
 
          echo 'longer description' >${TESTDIR}/descrip
@@ -21690,7 +21696,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-1
+${log_keyid}1
 ============================================================================="
 
          # TODO: `cvs admin -t "my message" file1' is a request to
@@ -21713,7 +21719,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-1
+${log_keyid}1
 ============================================================================="
 
          dokeep
@@ -22610,7 +22616,7 @@
 ----------------------------
 revision 1\.2\.6\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
-mod
+${log_keyid}mod
 ----------------------------
 revision 1\.2\.6\.1
 date: 1971-01-01 08:00:05 [+-]0000;  author: joe;  state: Exp;  lines: 
${PLUS}1 -1;
@@ -26017,15 +26023,15 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
 branches:  1\.1\.2;  1\.1\.4;
-add
+${log_keyid}add
 ----------------------------
 revision 1\.1\.4\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
-modify-on-B
+${log_keyid}modify-on-B
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  lines: ${PLUS}1 -1;  
commitid: ${commitid};
-modify-on-A
+${log_keyid}modify-on-A
 ============================================================================="
 
          # This one is more concise.
@@ -26047,7 +26053,7 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
 branches:  1\.1\.2;  1\.1\.4;
-add
+${log_keyid}add
 ============================================================================="
 
          # OK, try very much the same thing except we run update -j to
@@ -26294,11 +26300,11 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
 branches:  1\.1\.2;
-add
+${log_keyid}add
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: foo;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-modify-on-branch
+${log_keyid}modify-on-branch
 ============================================================================="
          dotest admin-12 "${testcvs} -q admin -bbr file1" \
 "RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
@@ -26320,11 +26326,11 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
 branches:  1\.1\.2;
-add
+${log_keyid}add
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: foo;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-modify-on-branch
+${log_keyid}modify-on-branch
 ============================================================================="
 
          # "cvs log" doesn't print the comment leader.  RCS 5.7 will print
@@ -26405,7 +26411,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-add
+${log_keyid}add
 ============================================================================="
 
          dotest admin-14-3 "${testcvs} -q admin -aauth3 -aauth2,foo \
@@ -26431,7 +26437,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: oneone;  commitid: 
${commitid};
-changed-log-message
+${log_keyid}changed-log-message
 ============================================================================="
 
          dotest admin-16 "${testcvs} -q admin \
@@ -26459,11 +26465,11 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
 branches:  1\.1\.2;
-add
+${log_keyid}add
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: foo;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-modify-on-branch
+${log_keyid}modify-on-branch
 ============================================================================="
 
          dotest_fail admin-18 "${testcvs} -q admin -nbr:1.1.2 file1" \
@@ -26490,11 +26496,11 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
 branches:  1\.1\.2;
-add
+${log_keyid}add
 ----------------------------
 revision 1.1.2.1
 date: ${ISO8601DATE};  author: ${username};  state: foo;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-modify-on-branch
+${log_keyid}modify-on-branch
 ============================================================================="
 
          # OK, this is starting to get ridiculous, in terms of
@@ -26609,7 +26615,7 @@
 ----------------------------
 revision 1\.6  locked by: ${username};
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-sixth
+${log_keyid}sixth
 ============================================================================="
          dotest_fail admin-22-o10 "${testcvs} admin -o1.5: aaa" \
 "RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v
@@ -26638,19 +26644,19 @@
 ----------------------------
 revision 1\.4
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-fourth
+${log_keyid}fourth
 ----------------------------
 revision 1\.3
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-third
+${log_keyid}third
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-second
+${log_keyid}second
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-first
+${log_keyid}first
 ============================================================================="
 
          dotest admin-22-o14 "${testcvs} tag -b -r1.3 br1 aaa" "T aaa"
@@ -26714,24 +26720,24 @@
 ----------------------------
 revision 1\.4
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-fourth
+${log_keyid}fourth
 ----------------------------
 revision 1\.3
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
 branches:  1\.3\.2;
-third
+${log_keyid}third
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-second
+${log_keyid}second
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-first
+${log_keyid}first
 ----------------------------
 revision 1\.3\.2\.4
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}4 -0;  
commitid: ${commitid};
-branch-four
+${log_keyid}branch-four
 ============================================================================="
 
          dotest admin-22-o24 "${testcvs} -q update -p -r 1.3.2.4 aaa" \
@@ -26766,7 +26772,7 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-modify
+${log_keyid}modify
 ============================================================================="
 
          dotest admin-25 "cat ${CVSROOT_DIRNAME}/first-dir/file1,v" \
@@ -27033,24 +27039,24 @@
 ----------------------------
 revision 1\.4
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-fourth
+${log_keyid}fourth
 ----------------------------
 revision 1\.3
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
 branches:  1\.3\.2;
-third
+${log_keyid}third
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-second
+${log_keyid}second
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-first
+${log_keyid}first
 ----------------------------
 revision 1\.3\.2\.4
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}4 -0;  
commitid: ${commitid};
-branch-four
+${log_keyid}branch-four
 =============================================================================
 
 RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
@@ -27071,11 +27077,11 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
 branches:  1\.1\.2;
-add
+${log_keyid}add
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: foo;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-modify-on-branch
+${log_keyid}modify-on-branch
 =============================================================================
 
 RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
@@ -27102,15 +27108,15 @@
 ----------------------------
 revision 1\.4
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-yet_another
+${log_keyid}yet_another
 ----------------------------
 revision 1\.3
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-nuthr_line
+${log_keyid}nuthr_line
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-modify
+${log_keyid}modify
 =============================================================================
 
 RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
@@ -27128,11 +27134,11 @@
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: dead;  commitid: 
${commitid};
 branches:  1\.1\.2;
-file file3 was initially added on branch br\.
+${log_keyid}file file3 was initially added on branch br\.
 ----------------------------
 revision 1\.1\.2\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-another-log-message
+${log_keyid}another-log-message
 ============================================================================="
 
          # Currently, this test outputs 36 identical lines, so I am just
@@ -27196,7 +27202,7 @@
 ----------------------------
 revision 1\.1  locked by: ${username};
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-add
+${log_keyid}add
 ============================================================================="
 
          # Note that this just tests the owner of the lock giving
@@ -27219,7 +27225,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-add
+${log_keyid}add
 ============================================================================="
 
          # rcslock.pl tests.  Of course, the point isn't to test
@@ -28439,7 +28445,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-add
+${log_keyid}add
 ============================================================================="
              dotest recase-6sscs "$testcvs status FiLe" \
 "===================================================================
@@ -28466,7 +28472,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-recase
+${log_keyid}recase
 ============================================================================="
            else # server sensitive && client insensitive
              # Client finds same Entry for file & FiLe.
@@ -28495,7 +28501,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-recase
+${log_keyid}recase
 ============================================================================="
              dotest recase-6ss "$testcvs status FiLe" \
 "===================================================================
@@ -28522,7 +28528,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-recase
+${log_keyid}recase
 ============================================================================="
            fi
          else # server insensitive
@@ -28554,15 +28560,15 @@
 ----------------------------
 revision 1\.3
 date: ${ISO8601DATE};  author: $username;  state: Exp;  lines: +1 -1;  
commitid: ${commitid};
-recase
+${log_keyid}recase
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: $username;  state: dead;  lines: +0 -0;  
commitid: ${commitid};
-rm
+${log_keyid}rm
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-add
+${log_keyid}add
 ============================================================================="
            dotest recase-6si "$testcvs status FiLe" \
 "===================================================================
@@ -28590,15 +28596,15 @@
 ----------------------------
 revision 1\.3
 date: ${ISO8601DATE};  author: $username;  state: Exp;  lines: +1 -1;  
commitid: ${commitid};
-recase
+${log_keyid}recase
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: $username;  state: dead;  lines: +0 -0;  
commitid: ${commitid};
-rm
+${log_keyid}rm
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-add
+${log_keyid}add
 ============================================================================="
          fi
 
@@ -28707,7 +28713,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-add
+${log_keyid}add
 ============================================================================="
            dotest recase-15sscs "$testcvs status FiLe" \
 "===================================================================
@@ -28734,7 +28740,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-recase
+${log_keyid}recase
 ============================================================================="
              dotest recase-17sscs "$testcvs status FILE" \
 "===================================================================
@@ -28761,7 +28767,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-recase
+${log_keyid}recase
 ============================================================================="
            else # $server_sensitive && !$client_sensitive
              # Client finds same Entry for file & FiLe.
@@ -28790,7 +28796,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-recase
+${log_keyid}recase
 ============================================================================="
              dotest recase-17ssci "$testcvs status FILE" \
 "===================================================================
@@ -28817,7 +28823,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: $username;  state: Exp;  commitid: ${commitid};
-recase
+${log_keyid}recase
 ============================================================================="
            fi
          else # !$server_sensitive
@@ -29528,7 +29534,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v
@@ -29545,11 +29551,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-is
+${log_keyid}is
 =============================================================================
 ${SPROG} log: Logging mod1-2
 
@@ -29566,7 +29572,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
@@ -29583,11 +29589,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-is
+${log_keyid}is
 =============================================================================
 ${SPROG} log: Logging mod2-2/mod1-2
 
@@ -29604,7 +29610,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
@@ -29621,11 +29627,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-is
+${log_keyid}is
 =============================================================================
 ${SPROG} log: Logging mod1-2/mod2-2
 
@@ -29642,7 +29648,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
@@ -29659,11 +29665,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-anyone
+${log_keyid}anyone
 =============================================================================
 ${SPROG} log: Logging mod2-1
 
@@ -29680,7 +29686,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v
@@ -29697,11 +29703,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-anyone
+${log_keyid}anyone
 =============================================================================
 ${SPROG} log: Logging mod2-2
 
@@ -29718,7 +29724,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
@@ -29735,11 +29741,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-anyone
+${log_keyid}anyone
 =============================================================================" 
\
 "${SPROG} log: Logging \.
 ${SPROG} log: Logging mod1-1
@@ -29757,7 +29763,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v
@@ -29774,11 +29780,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-is
+${log_keyid}is
 =============================================================================
 ${SPROG} log: Logging mod1-2
 
@@ -29795,7 +29801,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
@@ -29812,11 +29818,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-is
+${log_keyid}is
 =============================================================================
 ${SPROG} log: Logging mod2-2
 ${SPROG} log: Logging mod2-2/mod1-2
@@ -29834,7 +29840,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v
@@ -29851,11 +29857,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-is
+${log_keyid}is
 =============================================================================
 ${SPROG} log: Logging mod1-2
 ${SPROG} log: Logging mod1-2/mod2-2
@@ -29873,7 +29879,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
@@ -29890,11 +29896,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-anyone
+${log_keyid}anyone
 =============================================================================
 ${SPROG} log: Logging mod2-1
 
@@ -29911,7 +29917,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v
@@ -29928,11 +29934,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-anyone
+${log_keyid}anyone
 =============================================================================
 ${SPROG} log: Logging mod2-2
 
@@ -29949,7 +29955,7 @@
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-reading
+${log_keyid}reading
 =============================================================================
 
 RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v
@@ -29966,11 +29972,11 @@
 ----------------------------
 revision 1\.2
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  lines: ${PLUS}1 -0;  
commitid: ${commitid};
-actually
+${log_keyid}actually
 ----------------------------
 revision 1\.1
 date: ${ISO8601DATE};  author: ${username};  state: Exp;  commitid: 
${commitid};
-anyone
+${log_keyid}anyone
 ============================================================================="
 
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]