/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2002 Linus Nielsen Feltzing * * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "plugin.h" #include "configfile.h" static const struct plugin_api *cfg_rb; void configfile_init(const struct plugin_api* newrb) { cfg_rb = newrb; } static void get_cfg_filename(char* buf, int buf_len, const char* filename) { char *s; cfg_rb->strcpy(buf, cfg_rb->plugin_get_current_filename()); s = cfg_rb->strrchr(buf, '/'); if (!s) /* should never happen */ { cfg_rb->snprintf(buf, buf_len, PLUGIN_DIR "/%s", filename); } else { s++; *s = '\0'; cfg_rb->strcat(s, filename); } } int configfile_save(const char *filename, struct configdata *cfg, int num_items, int version) { int fd; int i; char buf[MAX_PATH]; get_cfg_filename(buf, MAX_PATH, filename); fd = cfg_rb->creat(buf); if(fd < 0) return fd*10 - 1; /* pre-allocate 10 bytes for INT */ cfg_rb->fdprintf(fd, "file version: %10d\n", version); for(i = 0;i < num_items;i++) { switch(cfg[i].type) { case TYPE_INT: /* pre-allocate 10 bytes for INT */ cfg_rb->fdprintf(fd, "%s: %10d\n", cfg[i].name, *cfg[i].val); break; case TYPE_ENUM: cfg_rb->fdprintf(fd, "%s: %s\n", cfg[i].name, cfg[i].values[*cfg[i].val]); break; case TYPE_STRING: cfg_rb->fdprintf(fd, "%s: %s\n", cfg[i].name, cfg[i].string); break; } } cfg_rb->close(fd); return 0; } int configfile_load(const char *filename, struct configdata *cfg, int num_items, int min_version) { int fd; int i, j; char *name; char *val; char buf[MAX_PATH]; int file_version = -1; int tmp; get_cfg_filename(buf, MAX_PATH, filename); fd = cfg_rb->open(buf, O_RDONLY); if(fd < 0) return fd*10 - 1; while(cfg_rb->read_line(fd, buf, MAX_PATH) > 0) { cfg_rb->settings_parseline(buf, &name, &val); /* Bail out if the file version is too old */ if(!cfg_rb->strcmp("file version", name)) { file_version = cfg_rb->atoi(val); if(file_version < min_version) { cfg_rb->close(fd); return -1; } } for(i = 0;i < num_items;i++) { if(!cfg_rb->strcmp(cfg[i].name, name)) { switch(cfg[i].type) { case TYPE_INT: tmp = cfg_rb->atoi(val); /* Only set it if it's within range */ if(tmp >= cfg[i].min && tmp <= cfg[i].max) *cfg[i].val = tmp; break; case TYPE_ENUM: for(j = 0;j < cfg[i].max;j++) { if(!cfg_rb->strcmp(cfg[i].values[j], val)) { *cfg[i].val = j; } } break; case TYPE_STRING: cfg_rb->strncpy(cfg[i].string, val, cfg[i].max); break; } } } } cfg_rb->close(fd); return 0; } int configfile_get_value(const char* filename, const char* name) { int fd; char *pname; char *pval; char buf[MAX_PATH]; get_cfg_filename(buf, MAX_PATH, filename); fd = cfg_rb->open(buf, O_RDONLY); if(fd < 0) return -1; while(cfg_rb->read_line(fd, buf, MAX_PATH) > 0) { cfg_rb->settings_parseline(buf, &pname, &pval); if(!cfg_rb->strcmp(name, pname)) { cfg_rb->close(fd); return cfg_rb->atoi(pval); } } cfg_rb->close(fd); return -1; } int configfile_update_entry(const char* filename, const char* name, int val) { int fd; char *pname; char *pval; char path[MAX_PATH]; char buf[256]; int found = 0; int line_len = 0; int pos = 0; /* open the current config file */ get_cfg_filename(path, MAX_PATH, filename); fd = cfg_rb->open(path, O_RDWR); if(fd < 0) return -1; /* read in the current stored settings */ while((line_len = cfg_rb->read_line(fd, buf, 256)) > 0) { cfg_rb->settings_parseline(buf, &pname, &pval); if(!cfg_rb->strcmp(name, pname)) { found = 1; cfg_rb->lseek(fd, pos, SEEK_SET); /* pre-allocate 10 bytes for INT */ cfg_rb->fdprintf(fd, "%s: %10d\n", pname, val); break; } pos += line_len; } /* if (name/val) is a new entry just append to file */ if (found == 0) /* pre-allocate 10 bytes for INT */ cfg_rb->fdprintf(fd, "%s: %10d\n", name, val); cfg_rb->close(fd); return found; }