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