/* $Id$ * $URL$ * $URL$ * * config file stuff * * Copyright (C) 1999, 2000 Michael Reinelt * Copyright (C) 2004 The LCD4Linux Team * * This file is part of LCD4Linux. * * LCD4Linux 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, or (at your option) * any later version. * * LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* * exported functions: * * cfg_init (source) * read configuration from source * returns 0 if successful * returns -1 in case of an error * * cfg_source (void) * returns the file the configuration was read from * * cfg_cmd (arg) * allows us to overwrite entries in the * config-file from the command line. * arg is 'key=value' * cfg_cmd can be called _before_ cfg_read() * returns 0 if ok, -1 if arg cannot be parsed * * cfg_list (section) * returns a list of all keys in the specified section * This list was allocated be cfg_list() and must be * freed by the caller! * * cfg_get_raw (section, key, defval) * return the a value for a given key in a given section * or if key does not exist. Does NOT evaluate * the expression. Therefore used to get the expression * itself! * * cfg_get (section, key, defval) * return the a value for a given key in a given section * or if key does not exist. The specified * value in the config is treated as a expression and * is evaluated! * * cfg_number (section, key, defval, min, int max, *value) * return the a value for a given key in a given section * convert it into a number with syntax checking * check if its in a given range. As it uses cfg_get() * internally, the evaluator is used here, too. * */ #include "config.h" #include #include #include #include #include #include #include #include "debug.h" #include "evaluator.h" #include "cfg.h" #ifdef WITH_DMALLOC #include #endif typedef struct { char *key; char *val; int lock; } ENTRY; static char *Config_File = NULL; static ENTRY *Config = NULL; static int nConfig = 0; /* bsearch compare function for config entries */ static int c_lookup(const void *a, const void *b) { char *key = (char *) a; ENTRY *entry = (ENTRY *) b; return strcasecmp(key, entry->key); } /* qsort compare function for variables */ static int c_sort(const void *a, const void *b) { ENTRY *ea = (ENTRY *) a; ENTRY *eb = (ENTRY *) b; return strcasecmp(ea->key, eb->key); } /* remove leading and trailing whitespace */ static char *strip(char *s, const int strip_comments) { char *p; while (isblank(*s)) s++; for (p = s; *p; p++) { if (*p == '"') do p++; while (*p && *p != '\n' && *p != '"'); if (*p == '\'') do p++; while (*p && *p != '\n' && *p != '\''); if (*p == '\n' || (strip_comments && *p == '#' && (p == s || *(p - 1) != '\\'))) { *p = '\0'; b
# Albi - France (DVB-T transmitter of Albi ( Agglomération ) )
# Albi - France (signal DVB-T transmis depuis l'émetteur de Agglomération )
#
# ATTENTION ! Ce fichier a ete construit automatiquement a partir
# des frequences obtenues sur : http://www.tvnt.net/multiplex_frequences.htm
# en Avril 2006. Si vous constatez des problemes et voulez apporter des
# modifications au fichier, envoyez le fichier modifie a
# l'adresse linux-dvb@linuxtv.org (depot des fichiers d'init dvb)
# ou a l'auteur du fichier :
# Nicolas Estre <n_estre@yahoo.fr>
#
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
#### Albi - Agglomération ####
#R1
T 730000000 8MHz AUTO NONE QAM64 8k AUTO NONE
#R2
T 754000000 8MHz AUTO NONE QAM64 8k AUTO NONE
#R3
T 698000000 8MHz AUTO NONE QAM64 8k AUTO NONE
#R4
T 602000000 8MHz AUTO NONE QAM64 8k AUTO NONE
#R5
T 746000000 8MHz AUTO NONE QAM64 8k AUTO NONE
#R6
T 818000000 8MHz AUTO NONE QAM64 8k AUTO NONE
r = -1; } if (stbuf.st_uid != uid || stbuf.st_gid != gid) { error("security error: owner and/or group of '%s' don't match", file); error = -1; } if (stbuf.st_mode & S_IRWXG || stbuf.st_mode & S_IRWXO) { error("security error: group or other have access to '%s'", file); error = -1; } return error; } static int cfg_read(const char *file) { FILE *stream; char buffer[256]; char section[256]; char *line, *key, *val, *end; int section_open, section_close; int error, lineno; stream = fopen(file, "r"); if (stream == NULL) { error("open(%s) failed: %s", file, strerror(errno)); return -1; } /* start with empty section */ strcpy(section, ""); error = 0; lineno = 0; while ((line = fgets(buffer, 256, stream)) != NULL) { /* increment line number */ lineno++; /* skip empty lines */ if (*(line = strip(line, 1)) == '\0') continue; /* reset section flags */ section_open = 0; section_close = 0; /* key is first word */ key = line; /* search first blank between key and value */ for (val = line; *val; val++) { if (isblank(*val)) { *val++ = '\0'; break; } } /* strip value */ val = strip(val, 1); /* search end of value */ if (*val) for (end = val; *(end + 1); end++); else end = val; /* if last char is '{', a section has been opened */ if (*end == '{') { section_open = 1; *end = '\0'; val = strip(val, 0); } /* provess "value" in double-quotes */ if (*val == '"' && *end == '"') { *end = '\0'; val++; } /* if key is '}', a section has been closed */ if (strcmp(key, "}") == 0) { section_close = 1; *key = '\0'; } /* sanity check: '}' should be the only char in a line */ if (section_close && (section_open || *val != '\0')) { error("error in config file '%s' line %d: garbage after '}'", file, lineno); error = 1; break; } /* check key for valid chars */ if (!validchars(key, 0)) { error("error in config file '%s' line %d: key '%s' is invalid", file, lineno, key); error = 1; break; } /* on section-open, check value for valid chars */ if (section_open && !validchars(val, 1)) { error("error in config file '%s' line %d: section '%s' is invalid", file, lineno, val); error = 1; break; } /* on section-open, append new section name */ if (section_open) { /* is the section[] array big enough? */ if (strlen(section) + strlen(key) + 3 > sizeof(section)) { error("error in config file '%s' line %d: section buffer overflow", file, lineno); error = 1; break; } if (*section != '\0') strcat(section, "."); strcat(section, key); if (*val != '\0') { strcat(section, ":"); strcat(section, val); } continue; } /* on section-close, remove last section name */ if (section_close) { /* sanity check: section already empty? */ if (*section == '\0') { error("error in config file '%s' line %d: unmatched closing brace", file, lineno); error = 1; break; } end = strrchr(section, '.'); if (end == NULL) *section = '\0'; else *end = '\0'; continue; } /* finally: add key */ cfg_add(section, key, val, 0); } /* sanity check: are the braces balanced? */ if (!error && *section != '\0') { error("error in config file '%s' line %d: unbalanced braces", file, lineno); error = 1; } fclose(stream); return -error; } int cfg_init(const char *file) { if (cfg_check_source(file) == -1) { return -1; } if (cfg_read(file) < 0) return -1; if (Config_File) free(Config_File); Config_File = strdup(file); return 0; } char *cfg_source(void) { if (Config_File) return Config_File; else return ""; } int cfg_exit(void) { int i; for (i = 0; i < nConfig; i++) { if (Config[i].key) free(Config[i].key); if (Config[i].val) free(Config[i].val); } if (Config) { free(Config); Config = NULL; } if (Config_File) { free(Config_File); Config_File = NULL; } return 0; }