/* * $Id: conf-file.c,v 1.4 1994/03/05 22:15:20 ceder Exp $ * Copyright (C) 1994 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * * LysKOM is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License * along with LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please mail bug reports to bug-lyskom@lysator.liu.se. */ /* * Read configuration files. */ static char *rcsid = "$Id: conf-file.c,v 1.4 1994/03/05 22:15:20 ceder Exp $"; #include "rcs.h" USE(rcsid); #include #include #include #include #include #include #include #include "s-string.h" #include "smalloc.h" #include "log.h" #include "misc-types.h" #include "kom-types.h" #include "conf-file.h" #include "lyskomd.h" #define MAXLINE 80 static int *assignment_count = NULL; static int npar = 0; static void init_init(const struct parameter *par) { int ix; for (npar = 0; par[npar].name != NULL; npar++) ; assert (assignment_count == NULL); assignment_count = smalloc(npar * sizeof (*assignment_count)); for (ix = 0; ix < npar; ix++) assignment_count[ix] = 0; } /* Check that each parameter is assigned at least as many times as the struct parameter says. Assign the default value if it is not assigned at all. */ static void assign_defaults(const struct parameter *par, int *err) { int ix; for (ix = 0; ix < npar; ix++) { if (assignment_count[ix] < par[ix].min_assignments) { log ("Parameter %s only assigned %d times (%d times needed)\n", par[ix].name, assignment_count[ix], par[ix].min_assignments); (*err)++; } else if (assignment_count[ix] == 0) { if ((*par[ix].assigner)(par[ix].default_val, &par[ix]) != OK) { log ("default assigner failed for %s\n", par[ix].name); (*err)++; } } } } /* Perform the assignments on one line. Returns EOF on end-of-file, 0 otherwise. A log message is printed, and (*err) is incremented, if errors are detected. */ static int configure_line(FILE *fp, const struct parameter *par, int *err) { char line[MAXLINE]; char *start; char *val; char *end; int found; int ix; if (fgets(line, MAXLINE, fp) == NULL) return EOF; /* Separate the line into its two parts. Set up start to point to the beginning of the variable name, val to point to the beginning of the value, and remove the training newline (using end). */ for (start = line; *start == ' ' || *start == '\t'; start++) ; switch (*start) { case '#': /* Comment line */ return 0; case '\0': /* Too long */ log ("line too long (max %d chars allowed): %s\n", MAXLINE-1, line); (*err)++; return 0; case '\n': /* Empty line */ return 0; } val = strchr(line, ':'); if (val == NULL) { log("missing colon: %s\n", line); (*err)++; return 0; } *val = '\0'; /* NUL-terminate key */ for (val++; *val == ' ' || *val == '\t'; val++) ; switch (*val) { case '\n': log ("empty value: %s\n", line); (*err)++; return 0; case '\0': log ("line too long (max %d chars allowed): %s\n", MAXLINE-1, line); (*err)++; return 0; } end = strchr(val, '\n'); if (end == NULL) { log ("line too long (max %d chars allowed): %s\n", MAXLINE-1, line); (*err)++; return 0; } *end = '\0'; /* Set the variable which match this line. */ found = 0; for (ix = 0; ix < npar; ix++) { if (!strcmp(start, par[ix].name)) { found++; if (assignment_count[ix] > par[ix].max_assignments && par[ix].max_assignments != -1) { (*err)++; log ("variable already assigned %d times: %s\n", assignment_count[ix], line); } else { assignment_count[ix]++; if ((*par[ix].assigner)(val, &par[ix]) != OK) { log ("assigner for %s failed\n", par[ix].name); (*err)++; } } } } if (found != 1) { log ("line matches %d times: %s\n", found, line); (*err)++; return 0; } return 0; } void read_config(const char *config_file, const struct parameter *par) { FILE *fp; int errs = 0; init_init(par); fp = fopen(config_file, "r"); if (fp == NULL) restart_kom("cannot open config file %s", config_file); while (configure_line(fp, par, &errs) != EOF) ; assign_defaults(par, &errs); if (errs) restart_kom("Please fix the above errors in %s and restart lyskomd", config_file); sfree(assignment_count); assignment_count = 0; } Success assign_text_no(const char *val, const struct parameter *par) { if (val != NULL) *(Text_no*)par->value = atol(val); return OK; } Success assign_conf_no(const char *val, const struct parameter *par) { if (val != NULL) *(Conf_no*)par->value = atol(val); return OK; } Success assign_int(const char *val, const struct parameter *par) { if (val != NULL) *(int*)par->value = atol(val); return OK; } Success assign_string(const char *val, const struct parameter *par) { if (val == NULL) *(char**)par->value = NULL; else { *(char**)par->value = smalloc(strlen(val) + 1); strcpy(*(char**)par->value, val); } return OK; } Success assign_bool(const char *val, const struct parameter *par) { if (val == NULL ||!strcmp(val, "false") || !strcmp(val, "off") || !strcmp(val, "no") || !strcmp(val, "0")) { *(Bool*)par->value = FALSE; } else if (!strcmp(val, "true") || !strcmp(val, "on") || !strcmp(val, "yes") || !strcmp(val, "1")) { *(Bool*)par->value = TRUE; } else { return FAILURE; } return OK; }