blob: b8b7b3a49f5916e1ed3dbf477f701b237ceb6ef0 [file] [log] [blame]
/*
* options.c
* Copyright (C) 2002 Florin Malita <mali@go.ro>
*
* This file is part of LUFS, a free userspace filesystem implementation.
* See http://lufs.sourceforge.net/ for updates.
*
* LUFS 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 2 of the License, or
* (at your option) any later version.
*
* LUFS 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 <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lufs/fs.h>
#include "list.h"
struct option {
char *key;
char *value;
struct list_head list;
};
struct domain {
char *name;
struct list_head properties;
struct list_head list;
};
static void
trim(char *buf){
int b,e;
if(!buf[0])
return;
for(b = 0; (buf[b] == ' ') || (buf[b] == '\t'); b++);
for(e = strlen(buf) - 1; (e >= 0) && ((buf[e] == ' ') || (buf[e] == '\t')); e--);
if(e < 0)
e = strlen(buf) - 1;
buf[e + 1] = 0;
if(b)
strcpy(buf, &buf[b]);
}
static struct domain*
find_domain(struct list_head *conf, char *name){
struct list_head *p;
struct domain *cls;
list_for_each(p, conf){
cls = list_entry(p, struct domain, list);
if(!strcmp(name, cls->name)){
TRACE("domain found");
return cls;
}
}
return NULL;
}
int
lu_opt_loadcfg(struct list_head *conf, char *file){
struct domain *class;
struct option *prop;
FILE *f;
static char buf[1024];
char *i, *j;
char *cls, *key, *val;
TRACE("loading config from %s", file);
if(!(f = fopen(file, "r"))){
WARN("could not open file for reading!");
return -1;
}
while(fgets(buf, 1024, f)){
buf[strlen(buf) - 1] = 0;
if((i = strchr(buf, '#')))
*i = 0;
if((i = strchr(buf, '='))){
if((j = strstr(buf, "::"))){
cls = buf;
key = j + 2;
val = i + 1;
*i = 0;
*j = 0;
trim(cls);
trim(key);
trim(val);
TRACE("class: #%s#", cls);
TRACE("key: #%s#", key);
TRACE("val: #%s#", val);
if(!(class = find_domain(conf, cls))){
TRACE("class not found, creating...");
if(!(class = malloc(sizeof(struct domain)))){
WARN("out of mem!");
break;
}
memset(class, 0, sizeof(struct domain));
if(!(class->name = malloc(strlen(cls) + 1))){
WARN("out of mem!");
free(class);
break;
}
strcpy(class->name, cls);
INIT_LIST_HEAD(&class->properties);
list_add(&class->list, conf);
}
if(!(prop = malloc(sizeof(struct option)))){
WARN("out of mem!");
break;
}
if(!(prop->key = malloc(strlen(key) + 1))){
WARN("out of mem!");
free(prop);
break;
}
if(!(prop->value = malloc(strlen(val) + 1))){
WARN("out of mem!");
free(prop->key);
free(prop);
break;
}
strcpy(prop->key, key);
strcpy(prop->value, val);
list_add(&prop->list, &class->properties);
}
}
}
fclose(f);
return 0;
}
const char*
lu_opt_getchar(struct list_head *conf, char *cls, char *key){
struct domain *class;
struct option *prop;
struct list_head *p;
TRACE("retrieving %s::%s", cls, key);
if(!(class = find_domain(conf, cls)))
return NULL;
list_for_each(p, &class->properties){
prop = list_entry(p, struct option, list);
if(!strcmp(key, prop->key)){
TRACE("key found");
return prop->value;
}
}
TRACE("key not found");
return NULL;
}
int
lu_opt_getint(struct list_head *conf, char *domain, char *key, long int *result, int base){
char *end;
const char *val;
long int res;
if(!(val = lu_opt_getchar(conf, domain, key)))
return -1;
res = strtol(val, &end, base);
if(*end)
return -1;
*result = res;
return 0;
}
int
lu_opt_parse(struct list_head *conf, char *domain, char *opts){
struct domain *class;
struct option *prop;
char *p, *sep;
if(!(class = find_domain(conf, domain))){
TRACE("domain not found, creating...");
if(!(class = malloc(sizeof(struct domain)))){
WARN("out of mem!");
return -1;
}
memset(class, 0, sizeof(struct domain));
if(!(class->name = malloc(strlen(domain) + 1))){
WARN("out of mem!");
free(class);
return -1;
}
strcpy(class->name, domain);
INIT_LIST_HEAD(&class->properties);
list_add(&class->list, conf);
}
for(p = strtok(opts, ","); p; p = strtok(NULL, ",")){
if(!strstr(p, "password"))
TRACE("option: %s", p);
if(!(prop = malloc(sizeof(struct option)))){
WARN("out of mem!");
return -1;
}
if((sep = strchr(p, '=')))
*sep = 0;
if(!(prop->key = malloc(strlen(p) + 1))){
WARN("out of mem!");
free(prop);
return -1;
}
strcpy(prop->key, p);
if(sep){
TRACE("option with parameter");
if(!(prop->value = malloc(strlen(sep + 1) + 1))){
WARN("out of mem!");
free(prop->key);
free(prop);
return -1;
}
strcpy(prop->value, sep + 1);
if(strstr(p, "password")){
TRACE("hiding password...");
memset(sep + 1, ' ', strlen(sep + 1));
}
}else{
TRACE("flag");
if(!(prop->value = malloc(2))){
WARN("out of mem!");
free(prop->key);
free(prop);
return -1;
}
strcpy(prop->value, "");
}
list_add(&prop->list, &class->properties);
}
return 0;
}