/*-
* Copyright (c) 2001 Peter Pentchev
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "penv.h"
#include "pe_compat.h"
#include "pe_log.h"
#include "pe_var.h"
__RINGID("$Ringlet: c/misc/penv/pe_var.c,v 1.9 2004/01/06 16:38:10 roam Exp $");
pe_err_t
pe_var_readfile(struct pe_var *vars, const char *fname, int required) {
FILE *fp;
char *line;
size_t sz;
pe_err_t r;
r = PE_ERR_NONE;
pe_verbose(1, "Reading config file %s\n", fname);
if (fp = fopen(fname, "rt"), fp == NULL) {
if ((errno == ENOENT) && !required)
return (PE_ERR_NONE);
return (PE_ERR_CFG_OPEN);
}
for (;;) {
if (r = pe_getline(fp, &line, &sz), r)
return (r);
if (line == NULL)
break;
r = pe_var_parseline(vars, line, sz);
free(line);
if (r != PE_ERR_NONE)
break;
}
fclose(fp);
return (r);
}
pe_err_t
pe_var_parseline(struct pe_var *vars, const char *line, size_t sz) {
size_t n0, n1, v0, v1;
char *name, *val;
pe_err_t r;
if (sz == 0)
return (PE_ERR_NONE);
for (n0 = 0; n0 < sz; n0++)
if (!isspace(line[n0]))
break;
if ((n0 == sz) || (line[n0] == '#'))
return (PE_ERR_NONE);
for (n1 = n0 + 1; n1 < sz; n1++)
if (isspace(line[n1]) || (line[n1] == '='))
break;
if (n1 == sz)
return (PE_ERR_CFG_SYNTAX);
for (v0 = n1; v0 < sz; v0++)
if (!isspace(line[v0]))
break;
if ((v0 == sz) || (line[v0] != '='))
return (PE_ERR_CFG_SYNTAX);
for (v0++; v0 < sz; v0++)
if (!isspace(line[v0]))
break;
for (v1 = sz; v1 > v0 + 1; v1--)
if (!isspace(line[v1 - 1]))
break;
name = calloc(1, n1 - n0 + 1);
val = calloc(1, v1 - v0 + 1);
if ((name == NULL) || (val == NULL)) {
free(name);
free(val);
return (PE_ERR_NOMEM);
}
memcpy(name, line + n0, n1 - n0);
memcpy(val, line + v0, v1 - v0);
r = pe_var_set(vars, name, val);
free(name);
free(val);
return (r);
}
pe_err_t
pe_var_set(struct pe_var *vars, const char *name, const char *val) {
unsigned v;
unsigned long uval;
long lval;
char *end;
pe_verbose(2, "varset(\"%s\", \"%s\")\n", name, val);
for (v = 0; vars[v].name != NULL; v++)
if (!strcmp(vars[v].name, name))
break;
if (vars[v].name == NULL)
return (PE_ERR_CFG_NXVAR);
if (vars[v].set) {
pe_verbose(2, " - ignored.\n");
return (PE_ERR_NONE);
}
switch (vars[v].type) {
case PE_VT_INT:
lval = strtol(val, &end, 0);
if ((lval < INT_MIN) || (lval > INT_MAX) ||
(*end != '\0'))
return (PE_ERR_CFG_BADVAL);
*(unsigned *)vars[v].val = (int) lval;
break;
case PE_VT_UINT:
if (val[0] == '-')
return (PE_ERR_CFG_BADVAL);
uval = strtoul(val, &end, 0);
if ((uval > UINT_MAX) ||
(*end != '\0'))
return (PE_ERR_CFG_BADVAL);
*(unsigned *)vars[v].val = (unsigned) uval;
break;
case PE_VT_STRING:
if (strlen(val) > vars[v].size - 1)
return (PE_ERR_CFG_STRLONG);
pe_strlcpy((char *)vars[v].val, val, vars[v].size);
break;
default:
return (PE_ERR_INT);
}
vars[v].set = 1;
return (PE_ERR_NONE);
}
syntax highlighted by Code2HTML, v. 0.9.1