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 main.c parseinfo... [signed-com


From: Derek Robert Price
Subject: [Cvs-cvs] ccvs/src ChangeLog gpg.c gpg.h main.c parseinfo... [signed-commits3]
Date: Thu, 12 Jan 2006 18:42:32 +0000

CVSROOT:        /cvsroot/cvs
Module name:    ccvs
Branch:         signed-commits3
Changes by:     Derek Robert Price <address@hidden>     06/01/12 18:42:31

Modified files:
        src            : ChangeLog gpg.c gpg.h main.c parseinfo.c 
                         parseinfo.h root.c root.h sign.c sign.h 
                         verify.c verify.h 

Log message:
        * gpg.h: #include "parseinfo.h" for struct config.
        (openpgp_textmode, set_openpgp_textmode, get_openpgp_textmode): Move
        global, functions from...
        * sign.c (sign_textmode, set_sign_textmode, get_sign_textmode):
        ...here.
        * gpg.h (set_openpgp_textmode, get_openpgp_textmode): New protos...
        * sign.h (set_sign_textmode, get_sign_textmode): ...here.
        * main.c (main): Rename `textmode' to `openpgp-textmode'.
        (config): Move global to...
        * parseinfo.c (config): ...here.
        (parse_config): Handle Verify* keys.
        * parseinfo.h: Use stricter include formatting.
        (config): Declare extern.
        * root.c (new_cvsroot_t, free_cvsroot_t, parse_cvsroot), root.h
        (cvsroot_t): Rename sign_textmode as above.
        * verify.c: Stop using "cvs.h".  Add protos for a few functions and
        globals still in main.c.
        (verify_commits): New static global.
        (iget_verify_checkouts): Reformat slightly for readability.
        (iget_verify_commits, get_verify_commits): New functions.
        (get_verify_template, get_verify_args): Process config keys.
        * verify.h (verify_state): Force VERIFY_DEFAULT to 0 so that no
        initialization is necessary for structs initialized with xcalloc().

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/ChangeLog.diff?only_with_tag=signed-commits3&tr1=1.3328.2.26&tr2=1.3328.2.27&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.8&tr2=1.1.6.9&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.3&tr2=1.1.6.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/main.c.diff?only_with_tag=signed-commits3&tr1=1.262.6.6&tr2=1.262.6.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/parseinfo.c.diff?only_with_tag=signed-commits3&tr1=1.85&tr2=1.85.2.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/parseinfo.h.diff?only_with_tag=signed-commits3&tr1=1.7&tr2=1.7.6.1&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/root.c.diff?only_with_tag=signed-commits3&tr1=1.121.2.3&tr2=1.121.2.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/root.h.diff?only_with_tag=signed-commits3&tr1=1.23.2.2&tr2=1.23.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/sign.c.diff?only_with_tag=signed-commits3&tr1=1.1.6.9&tr2=1.1.6.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/sign.h.diff?only_with_tag=signed-commits3&tr1=1.1.6.3&tr2=1.1.6.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/verify.c.diff?only_with_tag=signed-commits3&tr1=1.1.2.8&tr2=1.1.2.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/verify.h.diff?only_with_tag=signed-commits3&tr1=1.1.2.3&tr2=1.1.2.4&r1=text&r2=text

Patches:
Index: ccvs/src/ChangeLog
diff -u ccvs/src/ChangeLog:1.3328.2.26 ccvs/src/ChangeLog:1.3328.2.27
--- ccvs/src/ChangeLog:1.3328.2.26      Thu Jan 12 18:34:41 2006
+++ ccvs/src/ChangeLog  Thu Jan 12 18:42:31 2006
@@ -1,5 +1,29 @@
 2006-01-12  Derek Price  <address@hidden>
 
+       * gpg.h: #include "parseinfo.h" for struct config.
+       (openpgp_textmode, set_openpgp_textmode, get_openpgp_textmode): Move
+       global, functions from...
+       * sign.c (sign_textmode, set_sign_textmode, get_sign_textmode):
+       ...here.
+       * gpg.h (set_openpgp_textmode, get_openpgp_textmode): New protos...
+       * sign.h (set_sign_textmode, get_sign_textmode): ...here.
+       * main.c (main): Rename `textmode' to `openpgp-textmode'.
+       (config): Move global to...
+       * parseinfo.c (config): ...here.
+       (parse_config): Handle Verify* keys.
+       * parseinfo.h: Use stricter include formatting.
+       (config): Declare extern.
+       * root.c (new_cvsroot_t, free_cvsroot_t, parse_cvsroot), root.h
+       (cvsroot_t): Rename sign_textmode as above.
+       * verify.c: Stop using "cvs.h".  Add protos for a few functions and
+       globals still in main.c.
+       (verify_commits): New static global.
+       (iget_verify_checkouts): Reformat slightly for readability.
+       (iget_verify_commits, get_verify_commits): New functions.
+       (get_verify_template, get_verify_args): Process config keys.
+       * verify.h (verify_state): Force VERIFY_DEFAULT to 0 so that no
+       initialization is necessary for structs initialized with xcalloc().
+
        * cvs.h: Move some protos into...
        * repos.h: ...this new file.
        * add.c, admin.c, checkout.c, client.c, commit.c, edit.c, fileattr.c,
Index: ccvs/src/gpg.c
diff -u ccvs/src/gpg.c:1.1.6.8 ccvs/src/gpg.c:1.1.6.9
--- ccvs/src/gpg.c:1.1.6.8      Wed Jan 11 04:37:08 2006
+++ ccvs/src/gpg.c      Thu Jan 12 18:42:31 2006
@@ -30,12 +30,16 @@
 /* ANSI C Headers.  */
 #include <assert.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <string.h>
 
 /* GNULIB Headers.  */
 #include "error.h"
 #include "xalloc.h"
 
+/* CVS headers.  */
+#include "parseinfo.h"
+
 
 
 typedef enum {
@@ -468,3 +472,43 @@
   spout->rawlen = raw_idx;
   return 0;
 }
+
+
+
+static char *openpgp_textmode;
+
+void
+set_openpgp_textmode (const char *textmode)
+{
+    assert (textmode);
+    if (openpgp_textmode) free (openpgp_textmode);
+    openpgp_textmode = xstrdup (textmode);
+}
+
+
+
+/* Return OPENPGP_TEXTMODE from the command line if it exists, else if
+ * CONFIG->OPENPGPTEXTMODE is set, return that, else if OPENPGP_TEXTMODE
+ * is set in the CURRENT_PARSED_ROOT return that, else return the default
+ * mode.
+ *
+ * If the value to be returned is the empty string, then return NULL so that
+ * format_cmdline will skip the argument rather than passing an empty string.
+ */
+const char *
+get_openpgp_textmode (void)
+{
+    const char *tmp = NULL;
+
+    if (openpgp_textmode)
+       tmp = openpgp_textmode;
+    else if (config && config->OpenPGPTextmode)
+       tmp = config->OpenPGPTextmode;
+    else if (current_parsed_root->openpgp_textmode)
+       tmp = current_parsed_root->openpgp_textmode;
+    else
+       tmp = DEFAULT_SIGN_TEXTMODE;
+
+    if (tmp && !strlen (tmp)) return NULL;
+    /* else */ return tmp;
+}
Index: ccvs/src/gpg.h
diff -u ccvs/src/gpg.h:1.1.6.3 ccvs/src/gpg.h:1.1.6.4
--- ccvs/src/gpg.h:1.1.6.3      Wed Jan 11 04:37:08 2006
+++ ccvs/src/gpg.h      Thu Jan 12 18:42:31 2006
@@ -1,5 +1,5 @@
 /* gpg.h - OpenPGP functions header.
- * Copyright (C) 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2005-2006 Free Software Foundation, Inc.
  *
  * This file is part of of CVS.
  *
@@ -43,4 +43,6 @@
 int read_signature (struct buffer *bpin, struct buffer *bpout);
 int parse_signature (struct buffer *bpin, struct openpgp_signature *spout);
 
+void set_openpgp_textmode (const char *textmode);
+const char *get_openpgp_textmode (void);
 #endif /* GPG_H */
Index: ccvs/src/main.c
diff -u ccvs/src/main.c:1.262.6.6 ccvs/src/main.c:1.262.6.7
--- ccvs/src/main.c:1.262.6.6   Thu Jan 12 03:15:23 2006
+++ ccvs/src/main.c     Thu Jan 12 18:42:31 2006
@@ -28,6 +28,7 @@
 #include "xgethostname.h"
 
 /* CVS includes.  */
+#include "gpg.h"
 #include "sign.h"
 #include "verify.h"
 
@@ -55,20 +56,7 @@
 int readonlyfs = 0;
 int logoff = 0;
 bool suppress_bases = false;
-
-
-
-/***
- ***
- ***   CVSROOT/config options
- ***
- ***/
-struct config *config;
-
-
-
 mode_t cvsumask = UMASK_DFLT;
-
 char *CurDir;
 
 /*
@@ -325,7 +313,7 @@
     "                 Use TEMPLATE to generate OpenPGP signatures.\n",
     "    --sign-arg ARG\n",
     "                 Pass ARG to OpenPGP TEMPLATE when sigining.\n",
-    "    --textmode ARG\n",
+    "    --openpgp-textmode ARG\n",
     "                 Pass ARG to OpenPGP TEMPLATE when verifying or\n",
     "                 generating signatures.\n",
     "    --verify[=(off | warn | fatal)] | --no-verify\n",
@@ -559,8 +547,8 @@
        {"no-sign", 0, NULL, 5},
        {"sign-template", required_argument, NULL, 'G'},
        {"sign-arg", required_argument, NULL, 6},
-       {"textmode", required_argument, NULL, 7},
-       {"no-textmode", NULL, NULL, 8},
+       {"openpgp-textmode", required_argument, NULL, 7},
+       {"no-openpgp-textmode", 0, NULL, 8},
        {"verify", optional_argument, NULL, 9},
        {"no-verify", 0, NULL, 10},
        {"verify-template", required_argument, NULL, 11},
@@ -719,12 +707,12 @@
                add_sign_arg (optarg);
                break;
            case 7:
-               /* --textmode */
-               set_sign_textmode (optarg);
+               /* --openpgp-textmode */
+               set_openpgp_textmode (optarg);
                break;
            case 8:
-               /* --no-textmode */
-               set_sign_textmode ("");
+               /* --no-openpgp-textmode */
+               set_openpgp_textmode ("");
                break;
            case 9:
                /* --verify */
Index: ccvs/src/parseinfo.c
diff -u /dev/null ccvs/src/parseinfo.c:1.85.2.1
--- /dev/null   Thu Jan 12 18:42:32 2006
+++ ccvs/src/parseinfo.c        Thu Jan 12 18:42:31 2006
@@ -0,0 +1,807 @@
+/*
+ * Copyright (C) 1986-2006 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Verify interface.  */
+#include "parseinfo.h"
+
+/* GNULIB includes.  */
+#include "getline.h"
+
+/* CVS includes.  */
+#include "history.h"
+#include "repos.h"
+
+#include "cvs.h"
+
+
+/* From admin.c.  */
+char *make_UserAdminOptions (const char *infopath, unsigned int ln,
+                            const char *s);
+
+
+
+/***
+ ***
+ ***   CVSROOT/config options
+ ***
+ ***/
+struct config *config;
+
+
+
+/*
+ * Parse the INFOFILE file for the specified REPOSITORY.  Invoke CALLPROC for
+ * the first line in the file that matches the REPOSITORY, or if ALL != 0, any
+ * lines matching "ALL", or if no lines match, the last line matching
+ * "DEFAULT".
+ *
+ * Return 0 for success, -1 if there was not an INFOFILE, and >0 for failure.
+ */
+int
+Parse_Info (const char *infofile, const char *repository, CALLPROC callproc,
+            int opt, void *closure)
+{
+    int err = 0;
+    FILE *fp_info;
+    char *infopath;
+    char *line = NULL;
+    size_t line_allocated = 0;
+    char *default_value = NULL;
+    int default_line = 0;
+    char *expanded_value;
+    bool callback_done;
+    int line_number;
+    char *cp, *exp, *value;
+    const char *srepos;
+    const char *regex_err;
+
+    assert (repository);
+
+    if (!current_parsed_root)
+    {
+       /* XXX - should be error maybe? */
+       error (0, 0, "CVSROOT variable not set");
+       return 1;
+    }
+
+    /* find the info file and open it */
+    infopath = Xasprintf ("%s/%s/%s", current_parsed_root->directory,
+                         CVSROOTADM, infofile);
+    fp_info = CVS_FOPEN (infopath, "r");
+    if (!fp_info)
+    {
+       /* If no file, don't do anything special.  */
+       if (!existence_error (errno))
+           error (0, errno, "cannot open %s", infopath);
+       free (infopath);
+       return 0;
+    }
+
+    /* strip off the CVSROOT if repository was absolute */
+    srepos = Short_Repository (repository);
+
+    TRACE (TRACE_FUNCTION, "Parse_Info (%s, %s, %s)",
+          infopath, srepos,  (opt & PIOPT_ALL) ? "ALL" : "not ALL");
+
+    /* search the info file for lines that match */
+    callback_done = false;
+    line_number = 0;
+    while (getline (&line, &line_allocated, fp_info) >= 0)
+    {
+       line_number++;
+
+       /* skip lines starting with # */
+       if (line[0] == '#')
+           continue;
+
+       /* skip whitespace at beginning of line */
+       for (cp = line; *cp && isspace ((unsigned char) *cp); cp++)
+           ;
+
+       /* if *cp is null, the whole line was blank */
+       if (*cp == '\0')
+           continue;
+
+       /* the regular expression is everything up to the first space */
+       for (exp = cp; *cp && !isspace ((unsigned char) *cp); cp++)
+           ;
+       if (*cp != '\0')
+           *cp++ = '\0';
+
+       /* skip whitespace up to the start of the matching value */
+       while (*cp && isspace ((unsigned char) *cp))
+           cp++;
+
+       /* no value to match with the regular expression is an error */
+       if (*cp == '\0')
+       {
+           error (0, 0, "syntax error at line %d file %s; ignored",
+                  line_number, infopath);
+           continue;
+       }
+       value = cp;
+
+       /* strip the newline off the end of the value */
+       cp = strrchr (value, '\n');
+       if (cp) *cp = '\0';
+
+       /*
+        * At this point, exp points to the regular expression, and value
+        * points to the value to call the callback routine with.  Evaluate
+        * the regular expression against srepos and callback with the value
+        * if it matches.
+        */
+
+       /* save the default value so we have it later if we need it */
+       if (strcmp (exp, "DEFAULT") == 0)
+       {
+           if (default_value)
+           {
+               error (0, 0, "Multiple `DEFAULT' lines (%d and %d) in %s file",
+                      default_line, line_number, infofile);
+               free (default_value);
+           }
+           default_value = xstrdup (value);
+           default_line = line_number;
+           continue;
+       }
+
+       /*
+        * For a regular expression of "ALL", do the callback always We may
+        * execute lots of ALL callbacks in addition to *one* regular matching
+        * callback or default
+        */
+       if (strcmp (exp, "ALL") == 0)
+       {
+           if (!(opt & PIOPT_ALL))
+               error (0, 0, "Keyword `ALL' is ignored at line %d in %s file",
+                      line_number, infofile);
+           else if ((expanded_value =
+                       expand_path (value, current_parsed_root->directory,
+                                    true, infofile, line_number)))
+           {
+               err += callproc (repository, expanded_value, closure);
+               free (expanded_value);
+           }
+           else
+               err++;
+           continue;
+       }
+
+       if (callback_done)
+           /* only first matching, plus "ALL"'s */
+           continue;
+
+       /* see if the repository matched this regular expression */
+       regex_err = re_comp (exp);
+       if (regex_err)
+       {
+           error (0, 0, "bad regular expression at line %d file %s: %s",
+                  line_number, infofile, regex_err);
+           continue;
+       }
+       if (re_exec (srepos) == 0)
+           continue;                           /* no match */
+
+       /* it did, so do the callback and note that we did one */
+       expanded_value = expand_path (value, current_parsed_root->directory,
+                                     true, infofile, line_number);
+       if (expanded_value)
+       {
+           err += callproc (repository, expanded_value, closure);
+           free (expanded_value);
+       }
+       else
+           err++;
+       callback_done = true;
+    }
+    if (ferror (fp_info))
+       error (0, errno, "cannot read %s", infopath);
+    if (fclose (fp_info) < 0)
+       error (0, errno, "cannot close %s", infopath);
+
+    /* if we fell through and didn't callback at all, do the default */
+    if (!callback_done && default_value)
+    {
+       expanded_value = expand_path (default_value,
+                                     current_parsed_root->directory,
+                                     true, infofile, line_number);
+       if (expanded_value)
+       {
+           err += callproc (repository, expanded_value, closure);
+           free (expanded_value);
+       }
+       else
+           err++;
+    }
+
+    /* free up space if necessary */
+    if (default_value) free (default_value);
+    free (infopath);
+    if (line) free (line);
+
+    return err;
+}
+
+
+
+/* Print a warning and return false if P doesn't look like a string specifying
+ * something that can be converted into a size_t.
+ *
+ * Sets *VAL to the parsed value when it is found to be valid.  *VAL will not
+ * be altered when false is returned.
+ */
+static bool
+readSizeT (const char *infopath, const char *option, const char *p,
+          size_t *val)
+{
+    const char *q;
+    size_t num, factor = 1;
+
+    if (!strcasecmp ("unlimited", p))
+    {
+       *val = SIZE_MAX;
+       return true;
+    }
+
+    /* Record the factor character (kilo, mega, giga, tera).  */
+    if (!isdigit (p[strlen(p) - 1]))
+    {
+       switch (p[strlen(p) - 1])
+       {
+           case 'T':
+               factor = xtimes (factor, 1024);
+           case 'G':
+               factor = xtimes (factor, 1024);
+           case 'M':
+               factor = xtimes (factor, 1024);
+           case 'k':
+               factor = xtimes (factor, 1024);
+               break;
+           default:
+               error (0, 0,
+    "%s: Unknown %s factor: `%c'",
+                      infopath, option, p[strlen(p)]);
+               return false;
+       }
+       TRACE (TRACE_DATA, "readSizeT(): Found factor %u for %s",
+              factor, option);
+    }
+
+    /* Verify that *q is a number.  */
+    q = p;
+    while (q < p + strlen(p) - 1 /* Checked last character above.  */)
+    {
+       if (!isdigit(*q))
+       {
+           error (0, 0,
+"%s: %s must be a postitive integer, not '%s'",
+                  infopath, option, p);
+           return false;
+       }
+       q++;
+    }
+
+    /* Compute final value.  */
+    num = strtoul (p, NULL, 10);
+    if (num == ULONG_MAX || num > SIZE_MAX)
+       /* Don't return an error, just max out.  */
+       num = SIZE_MAX;
+
+    TRACE (TRACE_DATA, "readSizeT(): read number %u for %s", num, option);
+    *val = xtimes (strtoul (p, NULL, 10), factor);
+    TRACE (TRACE_DATA, "readSizeT(): returnning %u for %s", *val, option);
+    return true;
+}
+
+
+
+/* Allocate and initialize a new config struct.  */
+static inline struct config *
+new_config (void)
+{
+    struct config *new = xcalloc (1, sizeof (struct config));
+
+    TRACE (TRACE_FLOW, "new_config ()");
+
+    new->logHistory = xstrdup (ALL_HISTORY_REC_TYPES);
+    new->RereadLogAfterVerify = LOGMSG_REREAD_ALWAYS;
+    new->UserAdminOptions = xstrdup ("k");
+    new->MaxCommentLeaderLength = 20;
+#ifdef SERVER_SUPPORT
+    new->MaxCompressionLevel = 9;
+#endif /* SERVER_SUPPORT */
+#ifdef PROXY_SUPPORT
+    new->MaxProxyBufferSize = (size_t)(8 * 1024 * 1024); /* 8 megabytes,
+                                                          * by default.
+                                                          */
+#endif /* PROXY_SUPPORT */
+#ifdef AUTH_SERVER_SUPPORT
+    new->system_auth = true;
+#endif /* AUTH_SERVER_SUPPORT */
+
+    return new;
+}
+
+
+
+void
+free_config (struct config *data)
+{
+    if (data->keywords) free_keywords (data->keywords);
+    free (data);
+}
+
+
+
+/* Return true if this function has already been called for line LN of file
+ * INFOPATH.
+ */
+bool
+parse_error (const char *infopath, unsigned int ln)
+{
+    static List *errors = NULL;
+    char *nodename = NULL;
+
+    if (!errors)
+       errors = getlist();
+
+    nodename = Xasprintf ("%s/%u", infopath, ln);
+    if (findnode (errors, nodename))
+    {
+       free (nodename);
+       return true;
+    }
+
+    push_string (errors, nodename);
+    return false;
+}
+
+
+
+#ifdef ALLOW_CONFIG_OVERRIDE
+const char * const allowed_config_prefixes[] = { ALLOW_CONFIG_OVERRIDE };
+#endif /* ALLOW_CONFIG_OVERRIDE */
+
+
+
+/* Parse the CVS config file.  The syntax right now is a bit ad hoc
+ * but tries to draw on the best or more common features of the other
+ * *info files and various unix (or non-unix) config file syntaxes.
+ * Lines starting with # are comments.  Settings are lines of the form
+ * KEYWORD=VALUE.  There is currently no way to have a multi-line
+ * VALUE (would be nice if there was, probably).
+ *
+ * CVSROOT is the $CVSROOT directory
+ * (current_parsed_root->directory might not be set yet, so this
+ * function takes the cvsroot as a function argument).
+ *
+ * RETURNS
+ *   Always returns a fully initialized config struct, which on error may
+ *   contain only the defaults.
+ *
+ * ERRORS
+ *   Calls error(0, ...) on errors in addition to the return value.
+ *
+ *   xmalloc() failures are fatal, per usual.
+ */
+struct config *
+parse_config (const char *cvsroot, const char *path)
+{
+    const char *infopath;
+    char *freeinfopath = NULL;
+    FILE *fp_info;
+    char *line = NULL;
+    unsigned int ln;           /* Input file line counter.  */
+    char *buf = NULL;
+    size_t buf_allocated = 0;
+    size_t len;
+    char *p;
+    struct config *retval;
+    /* PROCESSING      Whether config keys are currently being processed for
+     *                 this root.
+     * PROCESSED       Whether any keys have been processed for this root.
+     *                 This is initialized to true so that any initial keys
+     *                 may be processed as global defaults.
+     */
+    bool processing = true;
+    bool processed = true;
+
+    TRACE (TRACE_FUNCTION, "parse_config (%s)", cvsroot);
+
+#ifdef ALLOW_CONFIG_OVERRIDE
+    if (path)
+    {
+       const char * const *prefix;
+       char *npath = xcanonicalize_file_name (path);
+       bool approved = false;
+       for (prefix = allowed_config_prefixes; *prefix != NULL; prefix++)
+       {
+           char *nprefix;
+
+           if (!isreadable (*prefix)) continue;
+           nprefix = xcanonicalize_file_name (*prefix);
+           if (!strncmp (nprefix, npath, strlen (nprefix))
+               && (((*prefix)[strlen (*prefix)] != '/'
+                    && strlen (npath) == strlen (nprefix))
+                   || ((*prefix)[strlen (*prefix)] == '/'
+                       && npath[strlen (nprefix)] == '/')))
+               approved = true;
+           free (nprefix);
+           if (approved) break;
+       }
+       if (!approved)
+           error (1, 0, "Invalid path to config file specified: `%s'",
+                  path);
+       infopath = path;
+       free (npath);
+    }
+    else
+#endif
+       infopath = freeinfopath =
+           Xasprintf ("%s/%s/%s", cvsroot, CVSROOTADM, CVSROOTADM_CONFIG);
+
+    retval = new_config ();
+
+    fp_info = CVS_FOPEN (infopath, "r");
+    if (!fp_info)
+    {
+       /* If no file, don't do anything special.  */
+       if (!existence_error (errno))
+       {
+           /* Just a warning message; doesn't affect return
+              value, currently at least.  */
+           error (0, errno, "cannot open %s", infopath);
+       }
+       if (freeinfopath) free (freeinfopath);
+       return retval;
+    }
+
+    ln = 0;  /* Have not read any lines yet.  */
+    while (getline (&buf, &buf_allocated, fp_info) >= 0)
+    {
+       ln++; /* Keep track of input file line number for error messages.  */
+
+       line = buf;
+
+       /* Skip leading white space.  */
+       while (isspace (*line)) line++;
+
+       /* Skip comments.  */
+       if (line[0] == '#')
+           continue;
+
+       /* Is there any kind of written standard for the syntax of this
+          sort of config file?  Anywhere in POSIX for example (I guess
+          makefiles are sort of close)?  Red Hat Linux has a bunch of
+          these too (with some GUI tools which edit them)...
+
+          Along the same lines, we might want a table of keywords,
+          with various types (boolean, string, &c), as a mechanism
+          for making sure the syntax is consistent.  Any good examples
+          to follow there (Apache?)?  */
+
+       /* Strip the trailing newline.  There will be one unless we
+          read a partial line without a newline, and then got end of
+          file (or error?).  */
+
+       len = strlen (line) - 1;
+       if (line[len] == '\n')
+           line[len--] = '\0';
+
+       /* Skip blank lines.  */
+       if (line[0] == '\0')
+           continue;
+
+       TRACE (TRACE_DATA, "parse_info() examining line: `%s'", line);
+
+       /* Check for a root specification.  */
+       if (line[0] == '[' && line[len] == ']')
+       {
+           cvsroot_t *tmproot;
+
+           line++[len] = '\0';
+           tmproot = parse_cvsroot (line);
+
+           /* Ignoring method.  */
+           if (!tmproot
+#if defined CLIENT_SUPPORT || defined SERVER_SUPPORT
+               || (tmproot->method != local_method
+                   && (!tmproot->hostname || !isThisHost (tmproot->hostname)))
+#endif /* CLIENT_SUPPORT || SERVER_SUPPORT */
+               || !isSamePath (tmproot->directory, cvsroot))
+           {
+               if (processed) processing = false;
+           }
+           else
+           {
+               TRACE (TRACE_FLOW, "Matched root section`%s'", line);
+               processing = true;
+               processed = false;
+           }
+
+           continue;
+       }
+
+       /* There is data on this line.  */
+
+       /* Even if the data is bad or ignored, consider data processed for
+        * this root.
+        */
+       processed = true;
+
+       if (!processing)
+           /* ...but it is for a different root.  */
+            continue;
+
+       /* The first '=' separates keyword from value.  */
+       p = strchr (line, '=');
+       if (!p
+           /* The following keys have optional arguments.  */
+           && strcmp (line, "VerifyCommits"))
+       {
+           if (!parse_error (infopath, ln))
+               error (0, 0,
+"%s [%d]: syntax error: missing `=' between keyword and value",
+                      infopath, ln);
+           continue;
+       }
+
+       *p++ = '\0';
+
+       if (strcmp (line, "RCSBIN") == 0)
+       {
+           /* This option used to specify the directory for RCS
+              executables.  But since we don't run them any more,
+              this is a noop.  Silently ignore it so that a
+              repository can work with either new or old CVS.  */
+           ;
+       }
+       else if (strcmp (line, "SystemAuth") == 0)
+#ifdef AUTH_SERVER_SUPPORT
+           readBool (infopath, "SystemAuth", p, &retval->system_auth);
+#else
+       {
+           /* Still parse the syntax but ignore the option.  That way the same
+            * config file can be used for local and server.
+            */
+           bool dummy;
+           readBool (infopath, "SystemAuth", p, &dummy);
+       }
+#endif
+       else if (strcmp (line, "LocalKeyword") == 0)
+           RCS_setlocalid (infopath, ln, &retval->keywords, p);
+       else if (strcmp (line, "KeywordExpand") == 0)
+           RCS_setincexc (&retval->keywords, p);
+       else if (strcmp (line, "PreservePermissions") == 0)
+       {
+#ifdef PRESERVE_PERMISSIONS_SUPPORT
+           readBool (infopath, "PreservePermissions", p,
+                     &retval->preserve_perms);
+#else
+           if (!parse_error (infopath, ln))
+               error (0, 0, "\
+%s [%u]: warning: this CVS does not support PreservePermissions",
+                      infopath, ln);
+#endif
+       }
+       else if (strcmp (line, "TopLevelAdmin") == 0)
+           readBool (infopath, "TopLevelAdmin", p, &retval->top_level_admin);
+       else if (strcmp (line, "LockDir") == 0)
+       {
+           if (retval->lock_dir)
+               free (retval->lock_dir);
+           retval->lock_dir = expand_path (p, cvsroot, false, infopath, ln);
+           /* Could try some validity checking, like whether we can
+              opendir it or something, but I don't see any particular
+              reason to do that now rather than waiting until lock.c.  */
+       }
+       else if (strcmp (line, "HistoryLogPath") == 0)
+       {
+           if (retval->HistoryLogPath) free (retval->HistoryLogPath);
+
+           /* Expand ~ & $VARs.  */
+           retval->HistoryLogPath = expand_path (p, cvsroot, false,
+                                                 infopath, ln);
+
+           if (retval->HistoryLogPath && !ISABSOLUTE (retval->HistoryLogPath))
+           {
+               error (0, 0, "%s [%u]: HistoryLogPath must be absolute.",
+                      infopath, ln);
+               free (retval->HistoryLogPath);
+               retval->HistoryLogPath = NULL;
+           }
+       }
+       else if (strcmp (line, "HistorySearchPath") == 0)
+       {
+           if (retval->HistorySearchPath) free (retval->HistorySearchPath);
+           retval->HistorySearchPath = expand_path (p, cvsroot, false,
+                                                    infopath, ln);
+
+           if (retval->HistorySearchPath
+               && !ISABSOLUTE (retval->HistorySearchPath))
+           {
+               error (0, 0, "%s [%u]: HistorySearchPath must be absolute.",
+                      infopath, ln);
+               free (retval->HistorySearchPath);
+               retval->HistorySearchPath = NULL;
+           }
+       }
+       else if (strcmp (line, "LogHistory") == 0)
+       {
+           if (strcmp (p, "all") != 0)
+           {
+               static bool gotone = false;
+               if (gotone)
+                   error (0, 0, "\
+%s [%u]: warning: duplicate LogHistory entry found.",
+                          infopath, ln);
+               else
+                   gotone = true;
+               free (retval->logHistory);
+               retval->logHistory = xstrdup (p);
+           }
+       }
+       else if (strcmp (line, "RereadLogAfterVerify") == 0)
+       {
+           if (!strcasecmp (p, "never"))
+             retval->RereadLogAfterVerify = LOGMSG_REREAD_NEVER;
+           else if (!strcasecmp (p, "always"))
+             retval->RereadLogAfterVerify = LOGMSG_REREAD_ALWAYS;
+           else if (!strcasecmp (p, "stat"))
+             retval->RereadLogAfterVerify = LOGMSG_REREAD_STAT;
+           else
+           {
+               bool tmp;
+               if (readBool (infopath, "RereadLogAfterVerify", p, &tmp))
+               {
+                   if (tmp)
+                       retval->RereadLogAfterVerify = LOGMSG_REREAD_ALWAYS;
+                   else
+                       retval->RereadLogAfterVerify = LOGMSG_REREAD_NEVER;
+               }
+           }
+       }
+       else if (strcmp (line, "TmpDir") == 0)
+       {
+           if (retval->TmpDir) free (retval->TmpDir);
+           retval->TmpDir = expand_path (p, cvsroot, false, infopath, ln);
+           /* Could try some validity checking, like whether we can
+            * opendir it or something, but I don't see any particular
+            * reason to do that now rather than when the first function
+            * tries to create a temp file.
+            */
+       }
+       else if (strcmp (line, "UserAdminOptions") == 0)
+           retval->UserAdminOptions = make_UserAdminOptions (infopath, ln, p);
+       else if (strcmp (line, "UseNewInfoFmtStrings") == 0)
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+           readBool (infopath, "UseNewInfoFmtStrings", p,
+                     &retval->UseNewInfoFmtStrings);
+#else /* !SUPPORT_OLD_INFO_FMT_STRINGS */
+       {
+           bool dummy;
+           if (readBool (infopath, "UseNewInfoFmtStrings", p, &dummy)
+               && !dummy)
+               error (1, 0,
+"%s [%u]: Old style info format strings not supported by this executable.",
+                      infopath, ln);
+       }
+#endif /* SUPPORT_OLD_INFO_FMT_STRINGS */
+       else if (strcmp (line, "ImportNewFilesToVendorBranchOnly") == 0)
+           readBool (infopath, "ImportNewFilesToVendorBranchOnly", p,
+                     &retval->ImportNewFilesToVendorBranchOnly);
+       else if (strcmp (line, "PrimaryServer") == 0)
+           retval->PrimaryServer = parse_cvsroot (p);
+#ifdef PROXY_SUPPORT
+       else if (!strcmp (line, "MaxProxyBufferSize"))
+           readSizeT (infopath, "MaxProxyBufferSize", p,
+                      &retval->MaxProxyBufferSize);
+#endif /* PROXY_SUPPORT */
+       else if (!strcmp (line, "MaxCommentLeaderLength"))
+           readSizeT (infopath, "MaxCommentLeaderLength", p,
+                      &retval->MaxCommentLeaderLength);
+       else if (!strcmp (line, "UseArchiveCommentLeader"))
+           readBool (infopath, "UseArchiveCommentLeader", p,
+                     &retval->UseArchiveCommentLeader);
+#ifdef SERVER_SUPPORT
+       else if (!strcmp (line, "MinCompressionLevel"))
+           readSizeT (infopath, "MinCompressionLevel", p,
+                      &retval->MinCompressionLevel);
+       else if (!strcmp (line, "MaxCompressionLevel"))
+           readSizeT (infopath, "MaxCompressionLevel", p,
+                      &retval->MaxCompressionLevel);
+#endif /* SERVER_SUPPORT */
+       else if (!strcmp (line, "VerifyCommits"))
+       {
+           if (retval->VerifyCommits != VERIFY_DEFAULT)
+               error (0, 0,
+"%s [%u]: warning: duplicate VerifyCommits entry found.",
+                      infopath, ln);
+
+           if (!p)
+               retval->VerifyCommits = VERIFY_FATAL;
+           else if (!strcasecmp (p, "fatal"))
+               retval->VerifyCommits = VERIFY_FATAL;
+           else if (!strcasecmp (p, "warn"))
+               retval->VerifyCommits = VERIFY_WARN;
+           else
+           {
+               bool on;
+               if (readBool (infopath, "VerifyCommits", p, &on))
+               {
+                   if (on) retval->VerifyCommits = VERIFY_FATAL;
+                   else retval->VerifyCommits = VERIFY_OFF;
+               }
+               /* else
+                *   A warning was already printed.  Don't munge any
+                *   previous value on error.
+                */
+           }
+       }
+       else if (!strcmp (line, "VerifyTemplate"))
+       {
+           if (retval->VerifyTemplate)
+           {
+               free (retval->VerifyTemplate);
+               error (0, 0,
+"%s [%u]: warning: duplicate VerifyTemplate entry found.",
+                      infopath, ln);
+           }
+           retval->VerifyTemplate = xstrdup (p);
+       }
+       else if (!strcmp (line, "OpenPGPTextmode"))
+       {
+           if (retval->OpenPGPTextmode)
+           {
+               free (retval->OpenPGPTextmode);
+               error (0, 0,
+"%s [%u]: warning: duplicate OpenPGPTextmode entry found.",
+                      infopath, ln);
+           }
+           retval->OpenPGPTextmode = xstrdup (p);
+       }
+       else if (!strcmp (line, "VerifyArg"))
+       {
+           if (!retval->VerifyArgs) retval->VerifyArgs = getlist ();
+           push_string (retval->VerifyArgs, xstrdup (p));
+       }
+       else
+           /* We may be dealing with a keyword which was added in a
+              subsequent version of CVS.  In that case it is a good idea
+              to complain, as (1) the keyword might enable a behavior like
+              alternate locking behavior, in which it is dangerous and hard
+              to detect if some CVS's have it one way and others have it
+              the other way, (2) in general, having us not do what the user
+              had in mind when they put in the keyword violates the
+              principle of least surprise.  Note that one corollary is
+              adding new keywords to your CVSROOT/config file is not
+              particularly recommended unless you are planning on using
+              the new features.  */
+           if (!parse_error (infopath, ln))
+               error (0, 0, "%s [%u]: unrecognized keyword `%s'",
+                      infopath, ln, line);
+    }
+    if (ferror (fp_info))
+       error (0, errno, "cannot read %s", infopath);
+    if (fclose (fp_info) < 0)
+       error (0, errno, "cannot close %s", infopath);
+    if (freeinfopath) free (freeinfopath);
+    if (buf) free (buf);
+
+    return retval;
+}
Index: ccvs/src/parseinfo.h
diff -u /dev/null ccvs/src/parseinfo.h:1.7.6.1
--- /dev/null   Thu Jan 12 18:42:32 2006
+++ ccvs/src/parseinfo.h        Thu Jan 12 18:42:31 2006
@@ -0,0 +1,94 @@
+/*
+ *  Copyright (C) 2004, 2006 The Free Software Foundation, Inc.
+ *  Copyright (C) 2004  Derek Price, Ximbiot <http://ximbiot.com>
+ *
+ *  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.
+ *
+ * This is the header file for definitions and functions shared by parseinfo.c
+ * with other portions of CVS.
+ */
+#ifndef PARSEINFO_H
+# define PARSEINFO_H
+
+/* ANSI C headers.  */
+#include <stdbool.h>
+#include <stddef.h>    /* Get size_t.  */
+
+/* CVS headers.  */
+#include "root.h"
+#include "verify.h"
+
+
+
+struct config
+{
+    void *keywords;
+    bool top_level_admin;
+    char *lock_dir;
+    char *logHistory;
+    char *HistoryLogPath;
+    char *HistorySearchPath;
+    char *TmpDir;
+
+    /* Should the logmsg be re-read during the do_verify phase?
+     * RereadLogAfterVerify=no|stat|yes
+     * LOGMSG_REREAD_NEVER  - never re-read the logmsg
+     * LOGMSG_REREAD_STAT   - re-read the logmsg only if it has changed
+     * LOGMSG_REREAD_ALWAYS - always re-read the logmsg
+     */
+    int RereadLogAfterVerify;
+
+    char *UserAdminOptions;
+
+    /* Control default behavior of 'cvs import' (-X option on or off) in
+     * CVSROOT/config.  Defaults to off, for backward compatibility.
+     */
+    bool ImportNewFilesToVendorBranchOnly;
+
+    size_t MaxCommentLeaderLength;
+    bool UseArchiveCommentLeader;
+
+#ifdef AUTH_SERVER_SUPPORT
+    /* Should we check for system usernames/passwords?  */
+    bool system_auth;
+#endif /* AUTH_SERVER_SUPPORT */
+
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    bool UseNewInfoFmtStrings;
+#endif /* SUPPORT_OLD_INFO_FMT_STRINGS */
+    cvsroot_t *PrimaryServer;
+#ifdef PROXY_SUPPORT
+    size_t MaxProxyBufferSize;
+#endif /* PROXY_SUPPORT */
+#ifdef SERVER_SUPPORT
+    size_t MinCompressionLevel;
+    size_t MaxCompressionLevel;
+#endif /* SERVER_SUPPORT */
+
+    verify_state VerifyCommits;
+    char *VerifyTemplate;
+    char *OpenPGPTextmode;
+    List *VerifyArgs;
+
+#ifdef PRESERVE_PERMISSIONS_SUPPORT
+    bool preserve_perms;
+#endif /* PRESERVE_PERMISSIONS_SUPPORT */
+};
+
+
+
+/***
+ ***
+ ***   CVSROOT/config options
+ ***
+ ***/
+extern struct config *config;
+
+
+
+bool parse_error (const char *, unsigned int);
+struct config *parse_config (const char *, const char *);
+void free_config (struct config *data);
+#endif /* !PARSEINFO_H */
Index: ccvs/src/root.c
diff -u ccvs/src/root.c:1.121.2.3 ccvs/src/root.c:1.121.2.4
--- ccvs/src/root.c:1.121.2.3   Thu Jan 12 03:15:23 2006
+++ ccvs/src/root.c     Thu Jan 12 18:42:31 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2006 The Free Software Foundation, Inc.
  *
  * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
  *                                  and others.
@@ -21,12 +21,20 @@
 /* Verify interface.  */
 #include "root.h"
 
-#include "cvs.h"
+/* ANSI C headers.  */
 #include <assert.h>
+
+/* GNULIB headers.  */
 #include "getline.h"
 
+/* CVS headers.  */
+#include "repos.h"
 #include "stack.h"
 
+#include "cvs.h"
+
+
+
 /* Printable names for things in the current_parsed_root->method enum variable.
    Watch out if the enum is changed in cvs.h! */
 
@@ -400,7 +408,7 @@
     newroot->isremote = false;
     newroot->sign = SIGN_DEFAULT;
     newroot->sign_template = NULL;
-    newroot->sign_textmode = NULL;
+    newroot->openpgp_textmode = NULL;
     newroot->sign_args = getlist ();
     newroot->verify = VERIFY_DEFAULT;
     newroot->verify_template = NULL;
@@ -438,8 +446,8 @@
        free (root->directory);
     if (root->sign_template)
        free (root->sign_template);
-    if (root->sign_textmode)
-       free (root->sign_textmode);
+    if (root->openpgp_textmode)
+       free (root->openpgp_textmode);
     dellist (&root->sign_args);
     if (root->verify_template)
        free (root->verify_template);
@@ -648,17 +656,17 @@
                newroot->sign = SIGN_NEVER;
            else if (!strcasecmp (p, "sign-template"))
                newroot->sign_template = xstrdup (q);
-           else if (!strcasecmp (p, "textmode"))
+           else if (!strcasecmp (p, "openpgp-textmode"))
            {
-               if (newroot->sign_textmode)
-                   free (newroot->sign_textmode);
-               newroot->sign_textmode = xstrdup (q);
+               if (newroot->openpgp_textmode)
+                   free (newroot->openpgp_textmode);
+               newroot->openpgp_textmode = xstrdup (q);
            }
-           else if (!strcasecmp (p, "no-textmode"))
+           else if (!strcasecmp (p, "no-openpgp-textmode"))
            {
-               if (newroot->sign_textmode)
-                   free (newroot->sign_textmode);
-               newroot->sign_textmode = xstrdup ("");
+               if (newroot->openpgp_textmode)
+                   free (newroot->openpgp_textmode);
+               newroot->openpgp_textmode = xstrdup ("");
            }
            else if (!strcasecmp (p, "sign-arg"))
                push_string (newroot->sign_args, q);
Index: ccvs/src/root.h
diff -u ccvs/src/root.h:1.23.2.2 ccvs/src/root.h:1.23.2.3
--- ccvs/src/root.h:1.23.2.2    Sat Dec 31 19:51:11 2005
+++ ccvs/src/root.h     Thu Jan 12 18:42:31 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2006 The Free Software Foundation, Inc.
  *
  * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
  *                                  and others.
@@ -47,10 +47,10 @@
     char *sign_template;       /* The template to use to launch the external
                                 * program to produce GPG signatures.
                                 */
-    char *sign_textmode;       /* The arg GPG needs for text files.  */
     List *sign_args;           /* Keep track of any additional arguments for
                                 * the sign tool.
                                 */
+    char *openpgp_textmode;     /* The arg GPG needs for text files.  */
     verify_state verify;       /* Whether to verify checkouts.  */
     char *verify_template;     /* The template to use to launch the external
                                 * program to verify GPG signatures.
Index: ccvs/src/sign.c
diff -u ccvs/src/sign.c:1.1.6.9 ccvs/src/sign.c:1.1.6.10
--- ccvs/src/sign.c:1.1.6.9     Thu Jan 12 03:15:23 2006
+++ ccvs/src/sign.c     Thu Jan 12 18:42:31 2006
@@ -77,7 +77,6 @@
 #endif
 
 static char *sign_template;
-static char *sign_textmode;
 static List *sign_args;
 
 
@@ -101,16 +100,6 @@
 
 
 void
-set_sign_textmode (const char *textmode)
-{
-    assert (textmode);
-    if (sign_textmode) free (sign_textmode);
-    sign_textmode = xstrdup (textmode);
-}
-
-
-
-void
 add_sign_arg (const char *arg)
 {
     if (!sign_args) sign_args = getlist ();
@@ -157,31 +146,6 @@
 
 
 
-/* Return SIGN_TEXTMODE from the command line if it exists, else return the
- * SIGN_TEXTMODE from CURRENT_PARSED_ROOT.
- *
- * This function is not static because sign_textmode is reused for
- * verify_textmode.
- */
-const char *
-get_sign_textmode (void)
-{
-    const char *tmp = NULL;
-
-    if (sign_textmode)
-       tmp = sign_textmode;
-    else if (current_parsed_root->sign_textmode)
-       tmp = current_parsed_root->sign_textmode;
-    else
-       tmp = DEFAULT_SIGN_TEXTMODE;
-
-    if (tmp && !strlen (tmp)) return NULL;
-    /* else */
-    return tmp;
-}
-
-
-
 /* Return SIGN_ARGS from the command line if it exists, else return the
  * SIGN_ARGS from CURRENT_PARSED_ROOT.
  */
@@ -319,7 +283,7 @@
                              sign_args_list_to_args_proc, (void *) NULL,
                              "r", "s", current_parsed_root->directory,
                              "p", "s", srepos,
-                             "t", "s", bin ? NULL : get_sign_textmode (),
+                             "t", "s", bin ? NULL : get_openpgp_textmode (),
                              "s", "s", filename,
                              (char *) NULL);
 
Index: ccvs/src/sign.h
diff -u ccvs/src/sign.h:1.1.6.3 ccvs/src/sign.h:1.1.6.4
--- ccvs/src/sign.h:1.1.6.3     Fri Jan  6 20:04:38 2006
+++ ccvs/src/sign.h     Thu Jan 12 18:42:31 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 The Free Software Foundation, Inc.
+ * Copyright (C) 2005-2006 The Free Software Foundation, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,12 +34,10 @@
 /* Set values to override current_parsed_root.  */
 void set_sign_commits (sign_state sign);
 void set_sign_template (const char *template);
-void set_sign_textmode (const char *textmode);
 void add_sign_arg (const char *arg);
 
 /* Get values.  */
 bool get_sign_commits (bool server_active, bool server_support);
-const char *get_sign_textmode (void);
 char *gen_signature (const char *srepos, const char *filename, bool bin,
                     size_t *len);
 char *get_signature (bool server_active, const char *srepos,
Index: ccvs/src/verify.c
diff -u ccvs/src/verify.c:1.1.2.8 ccvs/src/verify.c:1.1.2.9
--- ccvs/src/verify.c:1.1.2.8   Thu Jan 12 03:15:23 2006
+++ ccvs/src/verify.c   Thu Jan 12 18:42:31 2006
@@ -25,7 +25,9 @@
 
 /* ANSI C headers.  */
 #include <assert.h>
+#include <errno.h>
 #include <stdlib.h>
+#include <string.h>
 
 /* GNULIB headers.  */
 #include "base64.h"
@@ -34,15 +36,24 @@
 
 /* CVS headers.  */
 #include "base.h"
+#include "entries.h"
+#include "filesubr.h"
+#include "gpg.h"
+#include "parseinfo.h"
 #include "recurse.h"
+#include "repos.h"
+#include "root.h"              /* Get current_parsed_root.  */
+#include "run.h"
+#include "server.h"
 #include "stack.h"
-
-/* Get current_parsed_root.  */
-#include "cvs.h"
+#include "subr.h"
+#include "system.h"
 
 
 
 extern int noexec;
+extern int really_quiet, quiet;
+void usage (const char *const *cpp);
 
 
 
@@ -56,8 +67,10 @@
  */
 #ifdef HAVE_OPENPGP
 static verify_state verify_checkouts = VERIFY_DEFAULT;
+static verify_state verify_commits = VERIFY_DEFAULT;
 #else
 static verify_state verify_checkouts = VERIFY_NEVER;
+static verify_state verify_commits = VERIFY_OFF;
 #endif
 
 static char *verify_template;
@@ -114,10 +127,10 @@
     /* Only verify checkouts from the client (and in local mode).  */
     if (server_active) return false;
 
-    if (verify_checkouts == VERIFY_DEFAULT)
+    tmp = verify_checkouts;
+
+    if (tmp == VERIFY_DEFAULT)
        tmp = current_parsed_root->verify;
-    else
-       tmp = verify_checkouts;
 
     if (tmp == VERIFY_DEFAULT)
        tmp = VERIFY_FATAL;
@@ -148,6 +161,44 @@
 
 
 
+/* Return the current verify_state based on the command line options, current
+ * config, and compiled default.
+ *
+ * RETURNS
+ *   VERIFY_OFF, VERIFY_WARN, or VERIFY_FATAL.
+ */
+static verify_state
+iget_verify_commits (void)
+{
+    verify_state tmp;
+
+    /* Only verify checkouts from the server (and in local mode).  */
+    if (current_parsed_root->isremote) return false;
+
+    tmp = verify_commits;
+
+    if (config && tmp == VERIFY_DEFAULT)
+       tmp = config->VerifyCommits;
+
+    if (tmp == VERIFY_DEFAULT)
+       tmp = VERIFY_OFF;
+
+    return tmp;
+}
+
+
+
+/* Return true if the server should attempt to verify files sent by the client.
+ */
+bool
+get_verify_commits (void)
+{
+    verify_state tmp = iget_verify_commits ();
+    return tmp == VERIFY_WARN || tmp == VERIFY_FATAL;
+}
+
+
+
 /* Return VERIFY_TEMPLATE from the command line if it exists, else return the
  * VERIFY_TEMPLATE from CURRENT_PARSED_ROOT.
  */
@@ -155,6 +206,8 @@
 get_verify_template (void)
 {
     if (verify_template) return verify_template;
+    if (config && config->VerifyTemplate)
+       return config->VerifyTemplate;
     if (current_parsed_root->verify_template)
        return current_parsed_root->verify_template;
     return DEFAULT_VERIFY_TEMPLATE;
@@ -169,6 +222,8 @@
 get_verify_args (void)
 {
     if (verify_args && !list_isempty (verify_args)) return verify_args;
+    if (config && config->VerifyArgs && !list_isempty (config->VerifyArgs))
+       return config->VerifyArgs;
     return current_parsed_root->verify_args;
 }
 
@@ -290,7 +345,7 @@
                              verify_args_list_to_args_proc, (void *) NULL,
                              "r", "s", current_parsed_root->directory,
                              "p", "s", srepos,
-                             "t", "s", bin ? NULL : get_sign_textmode (),
+                             "t", "s", bin ? NULL : get_openpgp_textmode (),
                              "S", "s", sigfile,
                              "s", "s", filename,
                              (char *) NULL);
Index: ccvs/src/verify.h
diff -u ccvs/src/verify.h:1.1.2.3 ccvs/src/verify.h:1.1.2.4
--- ccvs/src/verify.h:1.1.2.3   Tue Jan 10 02:27:47 2006
+++ ccvs/src/verify.h   Thu Jan 12 18:42:31 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 The Free Software Foundation, Inc.
+ * Copyright (C) 2005-2006 The Free Software Foundation, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@
 
 typedef enum
 {
-  VERIFY_DEFAULT,
+  VERIFY_DEFAULT = 0,
   VERIFY_OFF,
   VERIFY_WARN,
   VERIFY_FATAL




reply via email to

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