X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=conffile%2Fconffile.c;fp=conffile%2Fconffile.c;h=bf8b74c37a9f5a4671d28946f0aa18b1f628d8f4;hb=0be9704d6b24d09ebd55beedec52758cb88c570b;hp=0000000000000000000000000000000000000000;hpb=6747e89080a8265aa73320bd9f40a0fa6e1c161e;p=distributedratelimiting.git diff --git a/conffile/conffile.c b/conffile/conffile.c new file mode 100644 index 0000000..bf8b74c --- /dev/null +++ b/conffile/conffile.c @@ -0,0 +1,241 @@ +/* config file parser functions + * + * (C) 2000 by Harald Welte + * + * $Id: conffile.c 4946 2003-09-28 15:19:25Z laforge $ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include "conffile.h" + +#ifdef DEBUG_CONF +#define DEBUGC(format, args...) fprintf(stderr, format, ## args) +#else +#define DEBUGC(format, args...) +#endif + +/* points to config entry with error */ +config_entry_t *config_errce = NULL; + +/* Filename of the config file */ +static char *fname = NULL; + +/* get_word() - Function to parse a line into words. + * Arguments: line line to parse + * delim possible word delimiters + * buf pointer to buffer where word is returned + * Return value: pointer to first char after word + * This function can deal with "" quotes + */ +static char *get_word(char *line, char *not, char *buf) +{ + char *p, *start = NULL, *stop = NULL; + int inquote = 0; + + for (p = line; *p; p++) { + if (*p == '"') { + start = p + 1; + inquote = 1; + break; + } + if (!strchr(not, *p)) { + start = p; + break; + } + } + if (!start) + return NULL; + + /* determine pointer to one char after word */ + for (p = start; *p; p++) { + if (inquote) { + if (*p == '"') { + stop = p; + break; + } + } else { + if (strchr(not, *p)) { + stop = p; + break; + } + } + } + if (!stop) + return NULL; + + strncpy(buf, start, (size_t) (stop-start)); + *(buf + (stop-start)) = '\0'; + + /* skip quote character */ + if (inquote) + /* yes, we can return stop + 1. If " was the last + * character in string, it now points to NULL-term */ + return (stop + 1); + + return stop; +} + +#if 0 +/* do we have a config directive for this name */ +static int config_iskey(char *name) +{ + config_entry_t *ce; + + for (ce = config; ce; ce = ce->next) { + if (!strcmp(name, ce->key)) + return 0; + } + + return 1; +} +#endif + +/*********************************************************************** + * PUBLIC INTERFACE + ***********************************************************************/ + +/* register config file with us */ +int config_register_file(const char *file) +{ + /* FIXME: stat of file */ + if (fname) + return 1; + + fname = (char *) malloc(strlen(file)+1); + if (!fname) + return -ERROOM; + + strcpy(fname, file); + + return 0; +} + +/* parse config file */ +int config_parse_file(const char *section, config_entry_t *keys) +{ + FILE *cfile; + char *args; + config_entry_t *ce; + int err = 0; + int found = 0; + char linebuf[LINE_LEN+1]; + char *line = linebuf; + + cfile = fopen(fname, "r"); + if (!cfile) + return -ERROPEN; + + DEBUGC("prasing section [%s]\n", section); + + /* Search for correct section */ + while (fgets(line, LINE_LEN, cfile)) { + char wordbuf[LINE_LEN]; + char *wordend; + + if (*line == '#') + continue; + + if (!(wordend = get_word(line, " \t\n[]", (char *) wordbuf))) + continue; + DEBUGC("word: \"%s\"\n", wordbuf); + if (!strcmp(wordbuf, section)) { + found = 1; + break; + } + } + + if (!found) { + fclose(cfile); + return -ERRSECTION; + } + + /* Parse this section until next section */ + while (fgets(line, LINE_LEN, cfile)) + { + char wordbuf[LINE_LEN]; + char *wordend; + + DEBUGC("line read: %s\n", line); + if (*line == '#') + continue; + + if (!(wordend = get_word(line, " =\t\n", (char *) &wordbuf))) + continue; + + if (wordbuf[0] == '[' ) { + DEBUGC("Next section '%s' encountered\n", wordbuf); + break; + } + + DEBUGC("parse_file: entering main loop\n"); + for (ce = keys; ce; ce = ce->next) { + DEBUGC("parse main loop, key: %s\n", ce->key); + if (strcmp(ce->key, (char *) &wordbuf)) { + continue; + } + + wordend = get_word(wordend, " =\t\n", (char *) &wordbuf); + args = (char *)&wordbuf; + + if (ce->hit && !(ce->options & CONFIG_OPT_MULTI)) + { + DEBUGC("->ce-hit and option not multi!\n"); + config_errce = ce; + err = -ERRMULT; + goto cpf_error; + } + ce->hit++; + + switch (ce->type) { + case CONFIG_TYPE_STRING: + if (strlen(args) < + CONFIG_VAL_STRING_LEN ) { + strcpy(ce->u.string, args); + /* FIXME: what if not ? */ + } + break; + case CONFIG_TYPE_INT: + ce->u.value = atoi(args); + break; + case CONFIG_TYPE_CALLBACK: + (ce->u.parser)(args); + break; + } + break; + } + DEBUGC("parse_file: exiting main loop\n"); + } + + + for (ce = keys; ce; ce = ce->next) { + DEBUGC("ce post loop, ce=%s\n", ce->key); + if ((ce->options & CONFIG_OPT_MANDATORY) && (ce->hit == 0)) { + DEBUGC("Mandatory config directive \"%s\" not found\n", + ce->key); + config_errce = ce; + err = -ERRMAND; + goto cpf_error; + } + + } + +cpf_error: + fclose(cfile); + return err; +} +