diff options
Diffstat (limited to 'cfg.c')
-rw-r--r-- | cfg.c | 140 |
1 files changed, 95 insertions, 45 deletions
@@ -1,11 +1,11 @@ -/* $Id: cfg.c 750 2007-01-20 06:58:56Z michael $ - * $URL: https://ssl.bulix.org/svn/lcd4linux/branches/0.10.1/cfg.c $ - * $URL: https://ssl.bulix.org/svn/lcd4linux/branches/0.10.1/cfg.c $ +/* $Id: cfg.c 1109 2010-02-12 13:16:27Z mjona $ + * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/cfg.c $ + * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/cfg.c $ * * config file stuff * - * Copyright (C) 1999, 2000 Michael Reinelt <reinelt@eunet.at> - * Copyright (C) 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net> + * Copyright (C) 1999, 2000 Michael Reinelt <michael@reinelt.co.at> + * Copyright (C) 2004, 2009 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net> * * This file is part of LCD4Linux. * @@ -48,6 +48,9 @@ * This list was allocated be cfg_list() and must be * freed by the caller! * + * cfg_rename (section, old, new) + * changes the key of a existing entry + * * cfg_get_raw (section, key, defval) * return the a value for a given key in a given section * or <defval> if key does not exist. Does NOT evaluate @@ -132,15 +135,19 @@ static char *strip(char *s, const int strip_comments) if (*p == '"') do p++; - while (*p && *p != '\n' && *p != '"'); + while (*p && *p != '\n' && *p != '\r' && *p != '"'); if (*p == '\'') do p++; - while (*p && *p != '\n' && *p != '\''); + while (*p && *p != '\n' && *p != '\r' && *p != '\''); if (*p == '\n' || (strip_comments && *p == '#' && (p == s || *(p - 1) != '\\'))) { *p = '\0'; break; } + if (*p == '\r' && *(p + 1) == '\n') { + /* replace <CR> from DOS <CR><LF> with blank */ + *p = ' '; + } } for (p--; p > s && isblank(*p); p--) @@ -150,41 +157,6 @@ static char *strip(char *s, const int strip_comments) } -/* unquote a string */ -static char *dequote(char *string) -{ - int quote = 0; - char *s = string; - char *p = string; - - do { - if (*s == '\'') { - quote = !quote; - *p++ = *s; - } else if (quote && *s == '\\') { - s++; - if (*s >= '0' && *s <= '7') { - int n; - unsigned int c = 0; - sscanf(s, "%3o%n", &c, &n); - if (c == 0 || c > 255) { - error("WARNING: illegal '\\' in <%s>", string); - } else { - *p++ = c; - s += n - 1; - } - } else { - *p++ = *s; - } - } else { - *p++ = *s; - } - } while (*s++); - - return string; -} - - /* which if a string contains only valid chars */ /* i.e. start with a char and contains chars and nums */ static int validchars(const char *string, const int numstart) @@ -233,14 +205,14 @@ static void cfg_add(const char *section, const char *key, const char *val, const free(buffer); if (entry->val) free(entry->val); - entry->val = dequote(strdup(val)); + entry->val = strdup(val); return; } nConfig++; Config = realloc(Config, nConfig * sizeof(ENTRY)); Config[nConfig - 1].key = buffer; - Config[nConfig - 1].val = dequote(strdup(val)); + Config[nConfig - 1].val = strdup(val); Config[nConfig - 1].lock = lock; qsort(Config, nConfig, sizeof(ENTRY), c_sort); @@ -310,6 +282,58 @@ char *cfg_list(const char *section) } +int cfg_rename(const char *section, const char *old, const char *new) +{ + char *buffer; + ENTRY *old_entry, *new_entry; + + /* prepare old section.key */ + buffer = malloc(strlen(section) + strlen(old) + 2); + *buffer = '\0'; + if (section != NULL && *section != '\0') { + strcpy(buffer, section); + strcat(buffer, "."); + } + strcat(buffer, old); + + /* lookup old entry */ + old_entry = bsearch(buffer, Config, nConfig, sizeof(ENTRY), c_lookup); + free(buffer); + + if (old_entry == NULL) { + error("internal error: cfg_rename(%s, %s, %s) failed: entry not found!", section, old, new); + return -1; + } + + /* prepare new section.key */ + buffer = malloc(strlen(section) + strlen(new) + 2); + *buffer = '\0'; + if (section != NULL && *section != '\0') { + strcpy(buffer, section); + strcat(buffer, "."); + } + strcat(buffer, new); + + /* lookup new entry */ + new_entry = bsearch(buffer, Config, nConfig, sizeof(ENTRY), c_lookup); + + if (new_entry != NULL) { + info("cfg_rename(%s, %s, %s) failed: entry already exists!", section, old, new); + free(buffer); + return -1; + } + + /* replace key */ + free(old_entry->key); + old_entry->key = buffer; + + /* sort table again */ + qsort(Config, nConfig, sizeof(ENTRY), c_sort); + + return 0; +} + + static char *cfg_lookup(const char *section, const char *key) { int len; @@ -367,7 +391,7 @@ char *cfg_get(const char *section, const char *key, const char *defval) if (expression != NULL) { if (*expression == '\0') - return ""; + return strdup(""); if (Compile(expression, &tree) == 0 && Eval(tree, &result) == 0) { retval = strdup(R2S(&result)); DelTree(tree); @@ -461,10 +485,12 @@ static int cfg_check_source(const char *file) error("security error: owner and/or group of '%s' don't match", file); error = -1; } +#if ! defined(__CYGWIN__) if (stbuf.st_mode & S_IRWXG || stbuf.st_mode & S_IRWXO) { error("security error: group or other have access to '%s'", file); error = -1; } +#endif return error; } @@ -614,6 +640,26 @@ static int cfg_read(const char *file) } +static void cfg_dump(void) +{ + int i, len; + + /* find longest key for pretty output */ + len = 1; + for (i = 0; i < nConfig; i++) { + int l = strlen(Config[i].key); + if (l > len) + len = l; + } + + info("Dump of %s:", Config_File); + for (i = 0; i < nConfig; i++) { + info(" %-*s %s", len, Config[i].key, Config[i].val); + } + info(" "); +} + + int cfg_init(const char *file) { if (cfg_check_source(file) == -1) { @@ -625,8 +671,12 @@ int cfg_init(const char *file) if (Config_File) free(Config_File); + Config_File = strdup(file); + if (verbose_level > 1) + cfg_dump(); + return 0; } |