aboutsummaryrefslogtreecommitdiffstats
path: root/cfg.c
diff options
context:
space:
mode:
authorreinelt <>2004-01-08 05:28:12 +0000
committerreinelt <>2004-01-08 05:28:12 +0000
commit81dbc5fd7b41af8ba7f02da82d762ebb46aab8f0 (patch)
treebe3f4a3b44ddd0a5ddc60608e9b133361af5c3bc /cfg.c
parent895982032e2b237e9810dd11b7c70a66e1a9c34c (diff)
downloadlcd4linux-81dbc5fd7b41af8ba7f02da82d762ebb46aab8f0.tar.gz
[lcd4linux @ 2004-01-08 05:28:12 by reinelt]
Luk Claes added to AUTHORS cfg: group handling ('{}') added
Diffstat (limited to 'cfg.c')
-rw-r--r--cfg.c230
1 files changed, 191 insertions, 39 deletions
diff --git a/cfg.c b/cfg.c
index 7f73c77..892ee97 100644
--- a/cfg.c
+++ b/cfg.c
@@ -1,8 +1,9 @@
-/* $Id: cfg.c,v 1.20 2004/01/07 10:15:41 reinelt Exp $^
+/* $Id: cfg.c,v 1.21 2004/01/08 05:28:12 reinelt Exp $^
*
* config file stuff
*
* Copyright 1999, 2000 Michael Reinelt <reinelt@eunet.at>
+ * Copyright 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
*
* This file is part of LCD4Linux.
*
@@ -22,6 +23,10 @@
*
*
* $Log: cfg.c,v $
+ * Revision 1.21 2004/01/08 05:28:12 reinelt
+ * Luk Claes added to AUTHORS
+ * cfg: group handling ('{}') added
+ *
* Revision 1.20 2004/01/07 10:15:41 reinelt
* small glitch in evaluator fixed
* made config table sorted and access with bsearch(),
@@ -184,13 +189,14 @@ static int c_sort (const void *a, const void *b)
}
+// remove leading and trailing whitespace
static char *strip (char *s, 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=='\'') do p++; while (*p && *p!='\n' && *p!='\'');
if (*p=='\n' || (strip_comments && *p=='#' && (p==s || *(p-1)!='\\'))) {
*p='\0';
@@ -202,6 +208,7 @@ static char *strip (char *s, int strip_comments)
}
+// unquote a string
static char *dequote (char *string)
{
char *s=string;
@@ -219,11 +226,38 @@ static char *dequote (char *string)
}
-static void cfg_add (char *key, char *val, int lock)
+// which if a string contains only valid chars
+// i.e. start with a char and contains chars and nums
+static int validchars (char *string)
{
- ENTRY *entry;
+ char *c;
- entry=bsearch(key, Config, nConfig, sizeof(ENTRY), c_lookup);
+ for (c=string; *c; c++) {
+ if ((*c>='A' && *c<='Z') || (*c>='a' && *c<='z') || *c=='_') continue;
+ if ((*c>='0' && *c<='9') && (c>string)) continue;
+ return 0;
+ }
+ return 1;
+}
+
+
+static void cfg_add (char *group, char *key, char *val, int lock)
+{
+ char *buffer;
+ ENTRY *entry;
+
+ // allocate buffer
+ buffer=malloc(strlen(group)+strlen(key)+2);
+ *buffer='\0';
+
+ // prepare group:key
+ if (*group!='\0') {
+ strcpy(buffer, group);
+ strcat(buffer, ".");
+ }
+ strcat (buffer, key);
+
+ entry=bsearch(buffer, Config, nConfig, sizeof(ENTRY), c_lookup);
if (entry!=NULL) {
if (entry->lock>lock) return;
@@ -234,7 +268,7 @@ static void cfg_add (char *key, char *val, int lock)
nConfig++;
Config=realloc(Config, nConfig*sizeof(ENTRY));
- Config[nConfig-1].key=strdup(key);
+ Config[nConfig-1].key=strdup(buffer);
Config[nConfig-1].val=dequote(strdup(val));
Config[nConfig-1].lock=lock;
@@ -257,7 +291,8 @@ int l4l_cfg_cmd (char *arg)
}
}
if (*key=='\0' || *val=='\0') return -1;
- cfg_add (key, val, 1);
+ if (!validchars(key)) return -1;
+ cfg_add ("", key, val, 1);
return 0;
}
@@ -306,7 +341,7 @@ int l4l_cfg_number (char *key, int defval, int min, int max, int *value)
}
-static int check_cfg_source(char *file)
+static int cfg_check_source(char *file)
{
/* as passwords and commands are stored in the config file,
* we will check that:
@@ -347,23 +382,14 @@ static int check_cfg_source(char *file)
}
-static void cfg_plugin (RESULT *result, RESULT *arg1)
-{
- char *value=cfg_get(R2S(arg1), "");
- SetResult(&result, R_STRING, value);
-}
-
-
-int l4l_cfg_init (char *file)
+static int cfg_read (char *file)
{
FILE *stream;
char buffer[256];
- char *line, *p, *s;
-
- if (check_cfg_source(file) == -1) {
- error("config file '%s' is insecure, aborting", file);
- return -1;
- }
+ char group[256];
+ char *line, *key, *val, *end;
+ int group_open, group_close;
+ int error, lineno;
stream=fopen (file, "r");
if (stream==NULL) {
@@ -371,35 +397,161 @@ int l4l_cfg_init (char *file)
return -1;
}
- if (Config_File) free (Config_File);
- Config_File=strdup(file);
-
+ // start with empty group
+ strcpy(group, "");
+
+ 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;
- for (p=line; *p; p++) {
- if (isblank(*p)) {
- *p++='\0';
+
+ // reset group flags
+ group_open=0;
+ group_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;
}
}
- p=strip(p, 1);
- if (*p) for (s=p; *(s+1); s++);
- else s=p;
- if (*p=='"' && *s=='"') {
- *s='\0';
- p++;
+
+ // 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 group has been opened
+ if (*end=='{') {
+ group_open=1;
+ *end='\0';
+ val=strip(val, 0);
+ }
+
+ // provess "value" in double-quotes
+ if (*val=='"' && *end=='"') {
+ *end='\0';
+ val++;
+ }
+
+ // provess 'value' in single-quotes
+ else if (*val=='\'' && *end=='\'') {
+ *end='\0';
+ val++;
+ }
+
+ // if key is '}', a group has been closed
+ if (strcmp(key, "}")==0) {
+ group_close=1;
+ *key='\0';
+ }
+
+ // sanity check: '}' should be the only char in a line
+ if (group_close && (group_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)) {
+ error ("error in config file '%s' line %d: key '%s' is invalid", file, lineno, key);
+ error=1;
+ break;
+ }
+
+ // on group-open, check value for valid chars
+ if (group_open && !validchars(val)) {
+ error ("error in config file '%s' line %d: group '%s' is invalid", file, lineno, val);
+ error=1;
+ break;
+ }
+
+ // on group-open, append new group name
+ if (group_open) {
+ // is the group[] array big enough?
+ if (strlen(group)+strlen(key)+3 > sizeof(group)) {
+ error ("error in config file '%s' line %d: group buffer overflow", file, lineno);
+ error=1;
+ break;
+ }
+ if (*group!='\0') strcat (group, ".");
+ strcat (group, key);
+ strcat (group, ":");
+ strcat (group, val);
+ debug ("Michi: group-open=<%s>", group);
+ continue;
}
- else if (*p=='\'' && *s=='\'') {
- *s='\0';
- p++;
+
+ // on group-close, remove last group name
+ if (group_close) {
+ // sanity check: group already empty?
+ if (*group=='\0') {
+ error ("error in config file '%s' line %d: unmatched closing brace", file, lineno);
+ error=1;
+ break;
+ }
+
+ end=strrchr(group, '.');
+ if (end==NULL)
+ *group='\0';
+ else
+ *end='\0';
+ debug ("Michi: group-close1=<%s>", group);
+ continue;
}
- cfg_add (line, p, 0);
+
+ // finally: add key
+ debug ("Michi: add key=<%s> val=<%s>", key, val);
+ cfg_add (group, key, val, 0);
+
}
+
+ // sanity check: are the braces balanced?
+ if (!error && *group!='\0') {
+ error ("error in config file '%s' line %d: unbalanced braces", file, lineno);
+ error=1;
+ }
+
fclose (stream);
+ return -error;
+}
+
+
+static void cfg_plugin (RESULT *result, RESULT *arg1)
+{
+ char *value=cfg_get(R2S(arg1), "");
+ SetResult(&result, R_STRING, value);
+}
+
+
+int l4l_cfg_init (char *file)
+{
+ if (cfg_check_source(file) == -1) {
+ error("config file '%s' is insecure, aborting", file);
+ return -1;
+ }
+
+ if (cfg_read(file)<0) return -1;
+
+ if (Config_File) free (Config_File);
+ Config_File=strdup(file);
+
// register as a plugin
AddFunction ("cfg", 1, cfg_plugin);
-
+
return 0;
}