1 // MaCoPiX = Mascot Construnctive Pilot for X
2 // (ActX / Gtk+ Evolution)
3 //
4 //
5 // configfile.c
6 // Save Data Access for MaCoPiX
7 // (diverting from original program of XMMS)
8 // *** See below copyright. ***
9 //
10 // Copyright 2002-2007 K.Chimari
11 // http://rosegray.sakura.ne.jp/
12 //
13 //
14 // This program is free software; you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation; either version 2 of the License, or
17 // (at your option) any later version.
18 //
19 // This program is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU General Public License for more details.
23 //
24 // You should have received a copy of the GNU General Public License
25 // along with this program; if not, write to the Free Software
26 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 //
28
29 //
30 // XMMS - Cross-platform multimedia player
31 // Copyright (C) 1998-1999 Peter Alm, Mikael Alm, Olle Hallnas,
32 // Thomas Nilsson and 4Front Technologies
33 //
34 //
35 // This program is free software; you can redistribute it and/or modify
36 // it under the terms of the GNU General Public License as published by
37 // the Free Software Foundation; either version 2 of the License, or
38 // (at your option) any later version.
39 //
40 // This program is distributed in the hope that it will be useful,
41 // but WITHOUT ANY WARRANTY; without even the implied warranty of
42 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43 // GNU General Public License for more details.
44 //
45 // You should have received a copy of the GNU General Public License
46 // along with this program; if not, write to the Free Software
47 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
48 //
49 //
50
51 #include "main.h"
52
53 #include <sys/stat.h>
54 #include <unistd.h>
55 #include <stdio.h>
56 #include <string.h>
57 #include <stdlib.h>
58 #include "configfile.h"
59
60 static ConfigSection *xmms_cfg_create_section(ConfigFile * cfg, gchar * name);
61 static ConfigLine *xmms_cfg_create_string(ConfigSection * section, gchar * key, gchar * value);
62 static ConfigSection *xmms_cfg_find_section(ConfigFile * cfg, gchar * name);
63 static ConfigLine *xmms_cfg_find_string(ConfigSection * section, gchar * key);
64
65 extern gchar* to_utf8();
66 extern gchar* to_locale();
67
68
xmms_cfg_new(void)69 ConfigFile *xmms_cfg_new(void)
70 {
71 ConfigFile *cfg;
72
73 cfg = g_malloc0(sizeof (ConfigFile));
74
75 return cfg;
76 }
77
xmms_cfg_open_file(gchar * input_filename)78 ConfigFile *xmms_cfg_open_file(gchar * input_filename)
79 {
80 ConfigFile *cfg;
81
82 FILE *file;
83 gchar *buffer, **lines, *tmp;
84 gint i;
85 struct stat stats;
86 ConfigSection *section = NULL;
87 gint ehe;
88 #ifdef USE_WIN32
89 gboolean UNIX_flag;
90 #endif
91 gchar *filename;
92
93 //filename = to_locale(input_filename);
94 filename = g_strdup(input_filename);
95
96 #ifdef USE_WIN32
97 if (stat(filename, &stats) == -1){
98 g_free(filename);
99 return NULL;
100 }
101 #else
102 if (lstat(filename, &stats) == -1){
103 g_free(filename);
104 return NULL;
105 }
106 #endif
107 if (!(file = fopen(filename, "r"))){
108 g_free(filename);
109 return NULL;
110 }
111
112 g_free(filename);
113
114 buffer = g_malloc(stats.st_size + 1);
115 // if (fread(buffer, 1, stats.st_size, file) != stats.st_size)
116 ehe=fread(buffer, 1, stats.st_size, file);
117 #ifdef USE_WIN32
118 if (ehe > stats.st_size)
119 {
120 g_free(buffer);
121 fclose(file);
122 return NULL;
123 }
124 else if ( ehe == stats.st_size ){
125 UNIX_flag=TRUE;
126 }
127 else {
128 UNIX_flag=FALSE;
129 }
130 #else
131 if (ehe != stats.st_size)
132 {
133 g_free(buffer);
134 fclose(file);
135 return NULL;
136 }
137 #endif
138 fclose(file);
139 buffer[stats.st_size] = '\0';
140
141 cfg = g_malloc0(sizeof (ConfigFile));
142 #ifdef USE_WIN32
143 if(UNIX_flag)
144 lines = g_strsplit(buffer, "\n", 0);
145 else
146 lines = g_strsplit(buffer, "\n", 0);
147 #else
148 lines = g_strsplit(buffer, "\n", 0);
149 #endif
150 g_free(buffer);
151 i = 0;
152 while (lines[i])
153 {
154 if (lines[i][0] == '[')
155 {
156 if ((tmp = strchr(lines[i], ']')))
157 {
158 *tmp = '\0';
159 section = xmms_cfg_create_section(cfg, &lines[i][1]);
160 }
161 }
162 else if (lines[i][0] != '#' && section)
163 {
164 if ((tmp = strchr(lines[i], '=')))
165 {
166 *tmp = '\0';
167 tmp++;
168 xmms_cfg_create_string(section, lines[i], tmp);
169 }
170 }
171 i++;
172 }
173 g_strfreev(lines);
174 return cfg;
175 }
176
xmms_cfg_write_file(ConfigFile * cfg,gchar * input_filename)177 gboolean xmms_cfg_write_file(ConfigFile * cfg, gchar * input_filename)
178 {
179 FILE *file;
180 GList *section_list, *line_list;
181 ConfigSection *section;
182 ConfigLine *line;
183 gchar *filename;
184
185 //filename = to_locale(input_filename);
186 filename = g_strdup(input_filename);
187
188 if (!(file = fopen(filename, "w")))
189 return FALSE;
190
191 section_list = cfg->sections;
192 while (section_list)
193 {
194 section = (ConfigSection *) section_list->data;
195 if (section->lines)
196 {
197 fprintf(file, "[%s]\n", section->name);
198 line_list = section->lines;
199 while (line_list)
200 {
201 line = (ConfigLine *) line_list->data;
202 fprintf(file, "%s=%s\n", line->key, line->value);
203 line_list = g_list_next(line_list);
204 }
205 fprintf(file, "\n");
206 }
207 section_list = g_list_next(section_list);
208 }
209 fclose(file);
210 return TRUE;
211 }
212
xmms_cfg_read_string(ConfigFile * cfg,gchar * section,gchar * key,gchar ** value)213 gboolean xmms_cfg_read_string(ConfigFile * cfg, gchar * section, gchar * key, gchar ** value)
214 {
215 ConfigSection *sect;
216 ConfigLine *line;
217
218 if (!(sect = xmms_cfg_find_section(cfg, section)))
219 return FALSE;
220 if (!(line = xmms_cfg_find_string(sect, key)))
221 return FALSE;
222 *value = g_strdup(line->value);
223 return TRUE;
224 }
225
xmms_cfg_read_int(ConfigFile * cfg,gchar * section,gchar * key,gint * value)226 gboolean xmms_cfg_read_int(ConfigFile * cfg, gchar * section, gchar * key, gint * value)
227 {
228 gchar *str;
229
230 if (!xmms_cfg_read_string(cfg, section, key, &str))
231 return FALSE;
232 *value = atoi(str);
233 g_free(str);
234
235 return TRUE;
236 }
237
xmms_cfg_read_boolean(ConfigFile * cfg,gchar * section,gchar * key,gboolean * value)238 gboolean xmms_cfg_read_boolean(ConfigFile * cfg, gchar * section, gchar * key, gboolean * value)
239 {
240 gchar *str;
241
242 if (!xmms_cfg_read_string(cfg, section, key, &str))
243 return FALSE;
244 if (!strcasecmp(str, "TRUE"))
245 *value = TRUE;
246 else
247 *value = FALSE;
248 g_free(str);
249 return TRUE;
250 }
251
xmms_cfg_read_float(ConfigFile * cfg,gchar * section,gchar * key,gfloat * value)252 gboolean xmms_cfg_read_float(ConfigFile * cfg, gchar * section, gchar * key, gfloat * value)
253 {
254 gchar *str;
255
256 if (!xmms_cfg_read_string(cfg, section, key, &str))
257 return FALSE;
258
259 *value = (gfloat) g_strtod(str, NULL);
260 g_free(str);
261
262 return TRUE;
263 }
264
xmms_cfg_read_double(ConfigFile * cfg,gchar * section,gchar * key,gdouble * value)265 gboolean xmms_cfg_read_double(ConfigFile * cfg, gchar * section, gchar * key, gdouble * value)
266 {
267 gchar *str;
268
269 if (!xmms_cfg_read_string(cfg, section, key, &str))
270 return FALSE;
271
272 *value = g_strtod(str, NULL);
273 g_free(str);
274
275 return TRUE;
276 }
277
xmms_cfg_write_string(ConfigFile * cfg,gchar * section,gchar * key,gchar * value)278 void xmms_cfg_write_string(ConfigFile * cfg, gchar * section, gchar * key, gchar * value)
279 {
280 ConfigSection *sect;
281 ConfigLine *line;
282
283 sect = xmms_cfg_find_section(cfg, section);
284 if (!sect)
285 sect = xmms_cfg_create_section(cfg, section);
286 if ((line = xmms_cfg_find_string(sect, key)))
287 {
288 g_free(line->value);
289 line->value = g_strchug(g_strchomp(g_strdup(value)));
290 }
291 else
292 xmms_cfg_create_string(sect, key, value);
293 }
294
xmms_cfg_write_int(ConfigFile * cfg,gchar * section,gchar * key,gint value)295 void xmms_cfg_write_int(ConfigFile * cfg, gchar * section, gchar * key, gint value)
296 {
297 gchar *strvalue;
298
299 strvalue = g_strdup_printf("%d", value);
300 xmms_cfg_write_string(cfg, section, key, strvalue);
301 g_free(strvalue);
302 }
303
xmms_cfg_write_boolean(ConfigFile * cfg,gchar * section,gchar * key,gboolean value)304 void xmms_cfg_write_boolean(ConfigFile * cfg, gchar * section, gchar * key, gboolean value)
305 {
306 if (value)
307 xmms_cfg_write_string(cfg, section, key, "TRUE");
308 else
309 xmms_cfg_write_string(cfg, section, key, "FALSE");
310 }
311
xmms_cfg_write_float(ConfigFile * cfg,gchar * section,gchar * key,gfloat value)312 void xmms_cfg_write_float(ConfigFile * cfg, gchar * section, gchar * key, gfloat value)
313 {
314 gchar *strvalue;
315
316 strvalue = g_strdup_printf("%g", value);
317 xmms_cfg_write_string(cfg, section, key, strvalue);
318 g_free(strvalue);
319 }
320
xmms_cfg_write_double(ConfigFile * cfg,gchar * section,gchar * key,gdouble value)321 void xmms_cfg_write_double(ConfigFile * cfg, gchar * section, gchar * key, gdouble value)
322 {
323 gchar *strvalue;
324
325 strvalue = g_strdup_printf("%g", value);
326 xmms_cfg_write_string(cfg, section, key, strvalue);
327 g_free(strvalue);
328 }
329
xmms_cfg_remove_key(ConfigFile * cfg,gchar * section,gchar * key)330 void xmms_cfg_remove_key(ConfigFile * cfg, gchar * section, gchar * key)
331 {
332 ConfigSection *sect;
333 ConfigLine *line;
334
335 if ((sect = xmms_cfg_find_section(cfg, section)))
336 {
337 if ((line = xmms_cfg_find_string(sect, key)))
338 {
339 g_free(line->key);
340 g_free(line->value);
341 g_free(line);
342 sect->lines = g_list_remove(sect->lines, line);
343 }
344 }
345 }
346
xmms_cfg_free(ConfigFile * cfg)347 void xmms_cfg_free(ConfigFile * cfg)
348 {
349 ConfigSection *section;
350 ConfigLine *line;
351 GList *section_list, *line_list;
352
353 section_list = cfg->sections;
354 while (section_list)
355 {
356 section = (ConfigSection *) section_list->data;
357 g_free(section->name);
358
359 line_list = section->lines;
360 while (line_list)
361 {
362 line = (ConfigLine *) line_list->data;
363 g_free(line->key);
364 g_free(line->value);
365 g_free(line);
366 line_list = g_list_next(line_list);
367 }
368 g_list_free(section->lines);
369 g_free(section);
370
371 section_list = g_list_next(section_list);
372 }
373 g_list_free(cfg->sections);
374 }
375
xmms_cfg_create_section(ConfigFile * cfg,gchar * name)376 static ConfigSection *xmms_cfg_create_section(ConfigFile * cfg, gchar * name)
377 {
378 ConfigSection *section;
379
380 section = g_malloc0(sizeof (ConfigSection));
381 section->name = g_strdup(name);
382 cfg->sections = g_list_append(cfg->sections, section);
383
384 return section;
385 }
386
xmms_cfg_create_string(ConfigSection * section,gchar * key,gchar * value)387 static ConfigLine *xmms_cfg_create_string(ConfigSection * section, gchar * key, gchar * value)
388 {
389 ConfigLine *line;
390
391 line = g_malloc0(sizeof (ConfigLine));
392 line->key = g_strchug(g_strchomp(g_strdup(key)));
393 line->value = g_strchug(g_strchomp(g_strdup(value)));
394 section->lines = g_list_append(section->lines, line);
395
396 return line;
397 }
398
xmms_cfg_find_section(ConfigFile * cfg,gchar * name)399 static ConfigSection *xmms_cfg_find_section(ConfigFile * cfg, gchar * name)
400 {
401 ConfigSection *section;
402 GList *list;
403
404 list = cfg->sections;
405 while (list)
406 {
407 section = (ConfigSection *) list->data;
408 if (!strcasecmp(section->name, name))
409 return section;
410 list = g_list_next(list);
411 }
412 return NULL;
413 }
414
xmms_cfg_find_string(ConfigSection * section,gchar * key)415 static ConfigLine *xmms_cfg_find_string(ConfigSection * section, gchar * key)
416 {
417 ConfigLine *line;
418 GList *list;
419
420 list = section->lines;
421 while (list)
422 {
423 line = (ConfigLine *) list->data;
424 if (!strcasecmp(line->key, key))
425 return line;
426 list = g_list_next(list);
427 }
428 return NULL;
429 }
430
431