diff options
Diffstat (limited to 'contrib/cvs/src/parseinfo.c')
-rw-r--r-- | contrib/cvs/src/parseinfo.c | 511 |
1 files changed, 0 insertions, 511 deletions
diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c deleted file mode 100644 index bf1e095..0000000 --- a/contrib/cvs/src/parseinfo.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright (C) 1986-2008 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. - * - * $FreeBSD$ - */ - -#include "cvs.h" -#include "getline.h" -#include <assert.h> -#include "history.h" - -extern char *logHistory; - -/* - * 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 (infofile, repository, callproc, all) - const char *infofile; - const char *repository; - CALLPROC callproc; - int all; -{ - 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; - int callback_done, line_number; - char *cp, *exp, *value; - const char *srepos; - const char *regex_err; - - assert (repository); - - if (current_parsed_root == NULL) - { - /* XXX - should be error maybe? */ - error (0, 0, "CVSROOT variable not set"); - return (1); - } - - /* find the info file and open it */ - infopath = xmalloc (strlen (current_parsed_root->directory) - + strlen (infofile) - + sizeof (CVSROOTADM) - + 3); - (void) sprintf (infopath, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, infofile); - fp_info = CVS_FOPEN (infopath, "r"); - if (fp_info == NULL) - { - /* 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); - - if (trace) - (void) fprintf (stderr, "%s-> Parse_Info (%s, %s, %s)\n", -#ifdef SERVER_SUPPORT - server_active ? "S" : " ", -#else - "", -#endif - infopath, srepos, all ? "ALL" : "not ALL"); - - /* search the info file for lines that match */ - callback_done = 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, infofile); - continue; - } - value = cp; - - /* strip the newline off the end of the value */ - if ((cp = strrchr (value, '\n')) != NULL) - *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 != NULL) - { - 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 (!all) - error(0, 0, "Keyword `ALL' is ignored at line %d in %s file", - line_number, infofile); - else if ((expanded_value = expand_path (value, infofile, - line_number)) != NULL) - { - err += callproc (repository, expanded_value); - free (expanded_value); - } - else - err++; - continue; - } - - if (callback_done) - /* only first matching, plus "ALL"'s */ - continue; - - /* see if the repository matched this regular expression */ - if ((regex_err = re_comp (exp)) != NULL) - { - 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 */ - if ((expanded_value = expand_path (value, infofile, line_number)) != NULL) - { - err += callproc (repository, expanded_value); - free (expanded_value); - } - else - err++; - callback_done = 1; - } - 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 == 0 && default_value != NULL) - { - if ((expanded_value = expand_path (default_value, infofile, default_line)) != NULL) - { - err += callproc (repository, expanded_value); - free (expanded_value); - } - else - err++; - } - - /* free up space if necessary */ - if (default_value != NULL) - free (default_value); - free (infopath); - if (line != NULL) - free (line); - - 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 - (current_parsed_root->directory might not be set yet, so this - function takes the cvsroot as a function argument). - - 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; - int ignore_unknown_config_keys = 0; - - /* Authentication code and serve_root might both want to call us. - Let this happen smoothly. */ - if (parsed) - return 0; - parsed = 1; - - infopath = xmalloc (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); - } - goto set_defaults_and_return; - } - - 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 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; - - /* 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 if (strcmp (line, "tag") == 0) { - RCS_setlocalid(p); - } - else if (strcmp (line, "umask") == 0) { - cvsumask = (mode_t)(strtol(p, NULL, 8) & 0777); - } - else if (strcmp (line, "dlimit") == 0) { -#ifdef BSD -#include <sys/resource.h> - struct rlimit rl; - - if (getrlimit(RLIMIT_DATA, &rl) != -1) { - rl.rlim_cur = atoi(p); - rl.rlim_cur *= 1024; - - (void) setrlimit(RLIMIT_DATA, &rl); - } -#endif /* BSD */ - } - else if (strcmp (line, "PreservePermissions") == 0) - { - if (strcmp (p, "no") == 0) - preserve_perms = 0; - else if (strcmp (p, "yes") == 0) - { -#ifdef PRESERVE_PERMISSIONS_SUPPORT - preserve_perms = 1; -#else - error (0, 0, "\ -warning: this CVS does not support PreservePermissions"); -#endif - } - else - { - error (0, 0, "unrecognized value '%s' for PreservePermissions", - p); - goto error_return; - } - } - else if (strcmp (line, "TopLevelAdmin") == 0) - { - if (strcmp (p, "no") == 0) - top_level_admin = 0; - else if (strcmp (p, "yes") == 0) - top_level_admin = 1; - else - { - error (0, 0, "unrecognized value '%s' for TopLevelAdmin", p); - goto error_return; - } - } - else if (strcmp (line, "LockDir") == 0) - { - if (lock_dir != NULL) - free (lock_dir); - lock_dir = xstrdup (p); - /* 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, "LogHistory") == 0) - { - if (strcmp (p, "all") != 0) - { - if (logHistory) free (logHistory); - logHistory = xstrdup (p); - } - } - else if (strcmp (line, "RereadLogAfterVerify") == 0) - { - if (strcmp (p, "no") == 0 || strcmp (p, "never") == 0) - RereadLogAfterVerify = LOGMSG_REREAD_NEVER; - else if (strcmp (p, "yes") == 0 || strcmp (p, "always") == 0) - RereadLogAfterVerify = LOGMSG_REREAD_ALWAYS; - else if (strcmp (p, "stat") == 0) - RereadLogAfterVerify = LOGMSG_REREAD_STAT; - } - else if (strcmp(line, "LocalKeyword") == 0) - { - /* Recognize cvs-1.12-style keyword control rather than erroring out. */ - RCS_setlocalid(p); - } - else if (strcmp(line, "KeywordExpand") == 0) - { - /* Recognize cvs-1.12-style keyword control rather than erroring out. */ - RCS_setincexc(p); - } - else if (strcmp (line, "IgnoreUnknownConfigKeys") == 0) - { - if (strcmp (p, "no") == 0 || strcmp (p, "false") == 0 - || strcmp (p, "off") == 0 || strcmp (p, "0") == 0) - ignore_unknown_config_keys = 0; - else if (strcmp (p, "yes") == 0 || strcmp (p, "true") == 0 - || strcmp (p, "on") == 0 || strcmp (p, "1") == 0) - ignore_unknown_config_keys = 1; - else - { - error (0, 0, "%s: unrecognized value '%s' for '%s'", - infopath, p, line); - goto error_return; - } - } - else if (ignore_unknown_config_keys) - ; - 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; - } -set_defaults_and_return: - if (!logHistory) - logHistory = xstrdup (ALL_HISTORY_REC_TYPES); - free (infopath); - if (line != NULL) - free (line); - return 0; - - error_return: - if (!logHistory) - logHistory = xstrdup (ALL_HISTORY_REC_TYPES); - if (infopath != NULL) - free (infopath); - if (line != NULL) - free (line); - return -1; -} |