FS#12076 - DB stats resurrection: If the filename was changed, require
[kugel-rb.git] / apps / plugins / lib / configfile.c
blobab1e21ad4acf9a0efdbf9005d723037b75269149
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "plugin.h"
22 #include "configfile.h"
24 static void get_cfg_filename(char* buf, int buf_len, const char* filename)
26 #ifdef APPLICATION
27 rb->snprintf(buf, buf_len, PLUGIN_DATA_DIR "/%s", filename);
28 #else
29 char *s;
30 rb->strcpy(buf, rb->plugin_get_current_filename());
31 s = rb->strrchr(buf, '/');
32 if (!s) /* should never happen */
34 rb->snprintf(buf, buf_len, PLUGIN_DATA_DIR "/%s", filename);
36 else
38 s++;
39 *s = '\0';
40 rb->strcat(s, filename);
42 #endif
45 int configfile_save(const char *filename, struct configdata *cfg,
46 int num_items, int version)
48 int fd;
49 int i;
50 char buf[MAX_PATH];
52 get_cfg_filename(buf, MAX_PATH, filename);
53 fd = rb->creat(buf, 0666);
54 if(fd < 0)
55 return fd*10 - 1;
57 /* pre-allocate 10 bytes for INT */
58 rb->fdprintf(fd, "file version: %10d\n", version);
60 for(i = 0;i < num_items;i++) {
61 switch(cfg[i].type) {
62 case TYPE_INT:
63 /* pre-allocate 10 bytes for INT */
64 rb->fdprintf(fd, "%s: %10d\n",
65 cfg[i].name,
66 *cfg[i].int_p);
67 break;
69 case TYPE_BOOL:
70 rb->fdprintf(fd, "%s: %10d\n",
71 cfg[i].name,
72 (int)*cfg[i].bool_p);
73 break;
75 case TYPE_ENUM:
76 rb->fdprintf(fd, "%s: %s\n",
77 cfg[i].name,
78 cfg[i].values[*cfg[i].int_p]);
79 break;
81 case TYPE_STRING:
82 rb->fdprintf(fd, "%s: %s\n",
83 cfg[i].name,
84 cfg[i].string);
85 break;
90 rb->close(fd);
91 return 0;
94 int configfile_load(const char *filename, struct configdata *cfg,
95 int num_items, int min_version)
97 int fd;
98 int i, j;
99 char *name;
100 char *val;
101 char buf[MAX_PATH];
102 int file_version = -1;
103 int tmp;
105 get_cfg_filename(buf, MAX_PATH, filename);
106 fd = rb->open(buf, O_RDONLY);
107 if(fd < 0)
108 return fd*10 - 1;
110 while(rb->read_line(fd, buf, MAX_PATH) > 0) {
111 rb->settings_parseline(buf, &name, &val);
113 /* Bail out if the file version is too old */
114 if(!rb->strcmp("file version", name)) {
115 file_version = rb->atoi(val);
116 if(file_version < min_version) {
117 rb->close(fd);
118 return -1;
122 for(i = 0;i < num_items;i++) {
123 if(!rb->strcmp(cfg[i].name, name)) {
124 switch(cfg[i].type) {
125 case TYPE_INT:
126 tmp = rb->atoi(val);
127 /* Only set it if it's within range */
128 if(tmp >= cfg[i].min && tmp <= cfg[i].max)
129 *cfg[i].int_p = tmp;
130 break;
132 case TYPE_BOOL:
133 tmp = rb->atoi(val);
134 *cfg[i].bool_p = (bool)tmp;
135 break;
137 case TYPE_ENUM:
138 for(j = 0;j < cfg[i].max;j++) {
139 if(!rb->strcmp(cfg[i].values[j], val)) {
140 *cfg[i].int_p = j;
143 break;
145 case TYPE_STRING:
146 rb->strlcpy(cfg[i].string, val, cfg[i].max);
147 break;
153 rb->close(fd);
154 return 0;
157 int configfile_get_value(const char* filename, const char* name)
159 int fd;
160 char *pname;
161 char *pval;
162 char buf[MAX_PATH];
164 get_cfg_filename(buf, MAX_PATH, filename);
165 fd = rb->open(buf, O_RDONLY);
166 if(fd < 0)
167 return -1;
169 while(rb->read_line(fd, buf, MAX_PATH) > 0)
171 rb->settings_parseline(buf, &pname, &pval);
172 if(!rb->strcmp(name, pname))
174 rb->close(fd);
175 return rb->atoi(pval);
179 rb->close(fd);
180 return -1;
183 int configfile_update_entry(const char* filename, const char* name, int val)
185 int fd;
186 char *pname;
187 char *pval;
188 char path[MAX_PATH];
189 char buf[256];
190 int found = 0;
191 int line_len = 0;
192 int pos = 0;
194 /* open the current config file */
195 get_cfg_filename(path, MAX_PATH, filename);
196 fd = rb->open(path, O_RDWR);
197 if(fd < 0)
198 return -1;
200 /* read in the current stored settings */
201 while((line_len = rb->read_line(fd, buf, 256)) > 0)
203 rb->settings_parseline(buf, &pname, &pval);
204 if(!rb->strcmp(name, pname))
206 found = 1;
207 rb->lseek(fd, pos, SEEK_SET);
208 /* pre-allocate 10 bytes for INT */
209 rb->fdprintf(fd, "%s: %10d\n", pname, val);
210 break;
212 pos += line_len;
215 /* if (name/val) is a new entry just append to file */
216 if (found == 0)
217 /* pre-allocate 10 bytes for INT */
218 rb->fdprintf(fd, "%s: %10d\n", name, val);
220 rb->close(fd);
222 return found;