/*************************************************************************** * Copyright (C) 03/2005 by Olaf Rempel * * razzor@kopf-tisch.de * * * * This program 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. * * * * 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 #include "hlswmaster.h" #include "configfile.h" #include "list.h" //#define DEBUG 1 /** liste der config-sections */ static LIST_HEAD(config_list); /** * config_add_section() * allokiert eine neue section und fuegt sie der config liste hinzu * * @param *name name der section * @return pointer auf die section, oder NULL bei fehler * * @todo sectionname ist nicht eindeutig */ static struct conf_section * config_add_section(char *name) { struct conf_section *section; if (!name) return NULL; section = malloc(sizeof(struct conf_section)); if (section) { INIT_LIST_HEAD(§ion->list); INIT_LIST_HEAD(§ion->tupel); strncpy(section->name, name, sizeof(section->name)); list_add_tail(§ion->list, &config_list); } return section; } /** * config_add_tupel() * fuegt einer section ein config tupel hinzu * * @param *section config section * @param *option name der option * @param *parameter wert der option * @return false bei fehler */ static int config_add_tupel(struct conf_section *section, char *option, char *parameter) { struct conf_tupel *tupel; if (!section || !option || !parameter) return 0; if (!(tupel = malloc(sizeof(struct conf_tupel)))) return 0; INIT_LIST_HEAD(&tupel->list); tupel->option = strdup(option); tupel->parameter = strdup(parameter); list_add_tail(&tupel->list, §ion->tupel); return 1; } /** * config_free() * entfernt die config_liste aus dem Speicher */ static void config_free() { struct conf_section *section, *section_tmp; struct conf_tupel *tupel, *tupel_tmp; list_for_each_entry_safe(section, section_tmp, &config_list, list) { list_for_each_entry_safe(tupel, tupel_tmp, §ion->tupel, list) { list_del(&tupel->list); free(tupel->option); free(tupel->parameter); free(tupel); } list_del(§ion->list); free(section); } } /** * config_parse() * parsed die configfile * * @param *config filename des configfiles * @return false bei fehler */ int config_parse(char *config) { struct conf_section *section = NULL; FILE *fz; int i = 0, ret = 1; char *row, *tok, *tok2; if (!config) return 0; if (!(row = malloc(1024))) return 0; if (!(fz = fopen(config, "r"))) { log_print("config_parse(): %s", config); return 0; } while (fgets(row, 1024, fz)) { i++; /* kommentar oder leere zeile */ if (row[0] == '#' || row[0] <= ' ') { continue; /* neue section */ } else if (row[0] == '[') { tok = strtok(row +1, " ]\n"); section = config_add_section(tok); if (!section) { log_print("config_parse(): invalid section in row %d", i); ret = 0; break; } continue; /* option, aber es gab noch keine section */ } else if (!section) { log_print("config_parse(): missing section in row %d", i); ret = 0; break; } /* option */ if ((tok = strtok(row, " \n")) && (tok2 = strtok(NULL, " \n"))) if (!config_add_tupel(section, tok, tok2)) log_print("config_parse(): invalid row %d", i); } fclose(fz); free(row); /* beim beenden die liste wieder freigeben */ if (atexit(config_free) != 0) { log_print("config_parse(): atexit()"); return 0; } #ifdef DEBUG { struct conf_section *section; struct conf_tupel *tupel; list_for_each_entry(section, &config_list, list) list_for_each_entry(tupel, §ion->tupel, list) printf("%s: %s = %s\n", section->name, tupel->option, tupel->parameter); } #endif return ret; } /** * config_get_section() * gibt eine benannte section zurueck * * @param *name name der section * @return pointer auf die section, oder NULL bei fehler */ struct conf_section * config_get_section(char *name) { struct conf_section *section; list_for_each_entry(section, &config_list, list) { if (!strcmp(section->name, name)) return section; } return NULL; } /** * config_get_parameter() * gibt den parameter der ersten passenden option * in einer section zurueck * * @param *section pointer auf die section * @param *option option name * @return pointer auf den parameter string oder NULL bei fehler */ char * config_get_parameter(struct conf_section *section, char *option) { struct conf_tupel *tupel; list_for_each_entry(tupel, §ion->tupel, list) { if (!strcmp(tupel->option, option)) return tupel->parameter; } return NULL; } /** * config_get_string() * gibt den parameter des section/option tupels zurueck * * @param *section name der section * @param *option name der option * @param *def default string * @return parameter string oder default string bei fehler */ char * config_get_string(char *section, char *option, char *def) { struct conf_section *tmp; char *ret; tmp = config_get_section(section); if (tmp && (ret = config_get_parameter(tmp, option))) return ret; return def; } /** * config_get_int() * gibt den parameter des section/option tupels zurueck * * @param *section name der section * @param *option name der option * @param *def default wert * @return parameter wert oder default wert bei fehler */ int config_get_int(char *section, char *option, int def) { char *ret; ret = config_get_string(section, option, NULL); return ret ? atoi(ret) : def; }