summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/parseinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/parseinfo.c')
-rw-r--r--contrib/cvs/src/parseinfo.c185
1 files changed, 183 insertions, 2 deletions
diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c
index 833463a..c492be0 100644
--- a/contrib/cvs/src/parseinfo.c
+++ b/contrib/cvs/src/parseinfo.c
@@ -3,11 +3,12 @@
* 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 1.4 kit.
+ * specified in the README file that comes with the CVS source distribution.
*/
#include "cvs.h"
#include "getline.h"
+#include <assert.h>
/*
* Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for
@@ -62,7 +63,7 @@ Parse_Info (infofile, repository, callproc, all)
srepos = Short_Repository (repository);
if (trace)
- (void) fprintf (stderr, "-> ParseInfo(%s, %s, %s)\n",
+ (void) fprintf (stderr, " -> ParseInfo(%s, %s, %s)\n",
infopath, srepos, all ? "ALL" : "not ALL");
/* search the info file for lines that match */
@@ -185,3 +186,183 @@ Parse_Info (infofile, repository, callproc, all)
return (err);
}
+
+
+/* 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 (CVSroot_directory might not be
+ set yet).
+
+ Returns 0 for success, negative value for failure. Call
+ error(0, ...) on errors in addition to the return value. */
+int
+parse_config (cvsroot)
+ char *cvsroot;
+{
+ char *infopath;
+ FILE *fp_info;
+ char *line = NULL;
+ size_t line_allocated = 0;
+ size_t len;
+ char *p;
+ /* FIXME-reentrancy: If we do a multi-threaded server, this would need
+ to go to the per-connection data structures. */
+ static int parsed = 0;
+
+ /* Authentication code and serve_root might both want to call us.
+ Let this happen smoothly. */
+ if (parsed)
+ return 0;
+ parsed = 1;
+
+ infopath = malloc (strlen (cvsroot)
+ + sizeof (CVSROOTADM_CONFIG)
+ + sizeof (CVSROOTADM)
+ + 10);
+ if (infopath == NULL)
+ {
+ error (0, 0, "out of memory; cannot allocate infopath");
+ goto error_return;
+ }
+
+ strcpy (infopath, cvsroot);
+ strcat (infopath, "/");
+ strcat (infopath, CVSROOTADM);
+ strcat (infopath, "/");
+ strcat (infopath, CVSROOTADM_CONFIG);
+
+ fp_info = CVS_FOPEN (infopath, "r");
+ if (fp_info == NULL)
+ {
+ /* 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);
+ }
+ free (infopath);
+ return 0;
+ }
+
+ while (getline (&line, &line_allocated, fp_info) >= 0)
+ {
+ /* Skip comments. */
+ if (line[0] == '#')
+ continue;
+
+ /* At least for the moment we don't skip whitespace at the start
+ of the line. Too picky? Maybe. But being insufficiently
+ picky leads to all sorts of confusion, and it is a lot easier
+ to start out picky and relax it than the other way around.
+
+ 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 training 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;
+
+ /* The first '=' separates keyword from value. */
+ p = strchr (line, '=');
+ if (p == NULL)
+ {
+ /* Probably should be printing line number. */
+ error (0, 0, "syntax error in %s: line '%s' is missing '='",
+ infopath, line);
+ goto error_return;
+ }
+
+ *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)
+ {
+ if (strcmp (p, "no") == 0)
+#ifdef AUTH_SERVER_SUPPORT
+ system_auth = 0;
+#else
+ /* Still parse the syntax but ignore the
+ option. That way the same config file can
+ be used for local and server. */
+ ;
+#endif
+ else if (strcmp (p, "yes") == 0)
+#ifdef AUTH_SERVER_SUPPORT
+ system_auth = 1;
+#else
+ ;
+#endif
+ else
+ {
+ error (0, 0, "unrecognized value '%s' for SystemAuth", p);
+ goto error_return;
+ }
+ }
+ 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. */
+ error (0, 0, "%s: unrecognized keyword '%s'",
+ infopath, line);
+ goto error_return;
+ }
+ }
+ if (ferror (fp_info))
+ {
+ error (0, errno, "cannot read %s", infopath);
+ goto error_return;
+ }
+ if (fclose (fp_info) < 0)
+ {
+ error (0, errno, "cannot close %s", infopath);
+ goto error_return;
+ }
+ free (infopath);
+ if (line != NULL)
+ free (line);
+ return 0;
+
+ error_return:
+ if (infopath != NULL)
+ free (infopath);
+ if (line != NULL)
+ free (line);
+ return -1;
+}
OpenPOWER on IntegriCloud