Select Git revision
interpret.c
-
Henrik (Grubba) Grubbström authored
Rev: src/encode.c:1.276 Rev: src/interpret.c:1.403
Henrik (Grubba) Grubbström authoredRev: src/encode.c:1.276 Rev: src/interpret.c:1.403
conf-file.c 7.40 KiB
/*
* $Id: conf-file.c,v 1.16 1999/05/24 09:34:20 ceder Exp $
* Copyright (C) 1994-1995, 1998-1999 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
static const char *
rcsid = "$Id: conf-file.c,v 1.16 1999/05/24 09:34:20 ceder Exp $";
#include "rcs.h"
USE(rcsid);
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include <assert.h>
#include <ctype.h>
#ifdef HAVE_STRING_H
# include <string.h>
#else
# ifdef HAVE_STRINGS_H
# include <strings.h>
# endif
#endif
#ifndef HAVE_STRCHR
# define strchr index
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#include <stdarg.h>
#include "s-string.h"
#include "server/smalloc.h"
#include "log.h"
#include "misc-types.h"
#include "kom-types.h"
#include "conf-file.h"
#include "lyskomd.h"
#define MAXLINE 1001
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)
{
kom_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)
{
kom_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 trailing newline (using
``end''). */
for (start = line; *start == ' ' || *start == '\t'; start++)
;
switch (*start)
{
case '#': /* Comment line */
return 0;
case '\0': /* Too long */
kom_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)
{
kom_log("missing colon: %s\n", line);
(*err)++;
return 0;
}
*val = '\0'; /* NUL-terminate key */
for (val++; *val == ' ' || *val == '\t'; val++)
;
switch (*val)
{
case '\0':
kom_log ("line too long (max %d chars allowed): %s\n", MAXLINE-1, line);
(*err)++;
return 0;
}
end = strchr(val, '\n');
if (end == NULL)
{
kom_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)++;
kom_log ("variable already assigned %d times: %s\n",
assignment_count[ix], line);
}
else
{
assignment_count[ix]++;
if ((*par[ix].assigner)(val, &par[ix]) != OK)
{
kom_log ("assigner for %s failed\n", par[ix].name);
(*err)++;
}
}
}
}
if (found != 1)
{
kom_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\n", config_file);
while (configure_line(fp, par, &errs) != EOF)
;
fclose(fp);
assign_defaults(par, &errs);
if (errs)
restart_kom("Please fix the above errors in %s and restart lyskomd\n",
config_file);
sfree(assignment_count);
assignment_count = 0;
}
Success
assign_text_no(const char *val,
const struct parameter *par)
{
int c;
/* FIXME: use strtol */
if (val != NULL)
{
c = (unsigned char)*val;
if (!isascii(c) || !isdigit(c))
return FAILURE;
*(Text_no*)par->value = atol(val);
}
return OK;
}
Success
assign_conf_no(const char *val,
const struct parameter *par)
{
int c;
/* FIXME: use strtol */
if (val != NULL)
{
c = (unsigned char)*val;
if (!isascii(c) || !isdigit(c))
return FAILURE;
*(Conf_no*)par->value = atol(val);
}
return OK;
}
Success
assign_int(const char *val,
const struct parameter *par)
{
int c;
/* FIXME: use strtol */
if (val != NULL)
{
c = (unsigned char)*val;
if ((!isascii(c) || !isdigit(c)) && c != '-')
return FAILURE;
*(int*)par->value = atol(val);
}
return OK;
}
Success
assign_ulong(const char *val,
const struct parameter *par)
{
int c;
if (val != NULL)
{
c = (unsigned char)*val;
if ((!isascii(c) || !isdigit(c)) && c != '-')
return FAILURE;
*(unsigned long*)par->value = (unsigned long)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;
}
void
unassign_string(const struct parameter *par)
{
if (*(char**)par->value != NULL)
{
sfree(*(char**)par->value);
*(char**)par->value = NULL;
}
}