Statistics
| Revision:

root / libsylph / prefs.c @ 3070

History | View | Annotate | Download (12.5 kB)

1 528 hiro
/*
2 578 hiro
 * LibSylph -- E-Mail client library
3 2123 hiro
 * Copyright (C) 1999-2009 Hiroyuki Yamamoto
4 528 hiro
 *
5 578 hiro
 * This library is free software; you can redistribute it and/or
6 578 hiro
 * modify it under the terms of the GNU Lesser General Public
7 578 hiro
 * License as published by the Free Software Foundation; either
8 578 hiro
 * version 2.1 of the License, or (at your option) any later version.
9 528 hiro
 *
10 578 hiro
 * This library is distributed in the hope that it will be useful,
11 528 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 578 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 578 hiro
 * Lesser General Public License for more details.
14 528 hiro
 *
15 578 hiro
 * You should have received a copy of the GNU Lesser General Public
16 578 hiro
 * License along with this library; if not, write to the Free Software
17 578 hiro
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 528 hiro
 */
19 528 hiro
20 528 hiro
#ifdef HAVE_CONFIG_H
21 528 hiro
#  include "config.h"
22 528 hiro
#endif
23 528 hiro
24 528 hiro
#include <glib.h>
25 528 hiro
#include <glib/gi18n.h>
26 528 hiro
#include <stdio.h>
27 528 hiro
#include <stdlib.h>
28 528 hiro
#include <string.h>
29 528 hiro
#include <unistd.h>
30 528 hiro
#include <errno.h>
31 528 hiro
32 2123 hiro
#ifdef G_OS_WIN32
33 2123 hiro
#  include <windows.h>
34 2123 hiro
#  include <io.h>
35 2123 hiro
#endif
36 2123 hiro
37 528 hiro
#include "prefs.h"
38 528 hiro
#include "codeconv.h"
39 528 hiro
#include "utils.h"
40 528 hiro
41 528 hiro
typedef enum
42 528 hiro
{
43 528 hiro
        DUMMY_PARAM
44 528 hiro
} DummyEnum;
45 528 hiro
46 2081 hiro
typedef struct _PrefFilePrivate        PrefFilePrivate;
47 2081 hiro
48 2081 hiro
struct _PrefFilePrivate {
49 2081 hiro
        FILE *fp;
50 2081 hiro
        gchar *path;
51 2081 hiro
        gint backup_generation;
52 2081 hiro
};
53 2081 hiro
54 530 hiro
static void prefs_config_parse_one_line        (GHashTable        *param_table,
55 530 hiro
                                         const gchar        *buf);
56 530 hiro
57 530 hiro
GHashTable *prefs_param_table_get(PrefParam *param)
58 530 hiro
{
59 530 hiro
        GHashTable *table;
60 530 hiro
        gint i;
61 530 hiro
62 530 hiro
        g_return_val_if_fail(param != NULL, NULL);
63 530 hiro
64 530 hiro
        table = g_hash_table_new(g_str_hash, g_str_equal);
65 530 hiro
66 530 hiro
        for (i = 0; param[i].name != NULL; i++) {
67 530 hiro
                g_hash_table_insert(table, param[i].name, &param[i]);
68 530 hiro
        }
69 530 hiro
70 530 hiro
        return table;
71 530 hiro
}
72 530 hiro
73 530 hiro
void prefs_param_table_destroy(GHashTable *param_table)
74 530 hiro
{
75 530 hiro
        g_hash_table_destroy(param_table);
76 530 hiro
}
77 530 hiro
78 528 hiro
void prefs_read_config(PrefParam *param, const gchar *label,
79 528 hiro
                       const gchar *rcfile, const gchar *encoding)
80 528 hiro
{
81 528 hiro
        FILE *fp;
82 528 hiro
        gchar buf[PREFSBUFSIZE];
83 528 hiro
        gchar *block_label;
84 530 hiro
        GHashTable *param_table;
85 528 hiro
86 528 hiro
        g_return_if_fail(param != NULL);
87 528 hiro
        g_return_if_fail(label != NULL);
88 528 hiro
        g_return_if_fail(rcfile != NULL);
89 528 hiro
90 528 hiro
        debug_print("Reading configuration...\n");
91 528 hiro
92 528 hiro
        prefs_set_default(param);
93 528 hiro
94 528 hiro
        if ((fp = g_fopen(rcfile, "rb")) == NULL) {
95 528 hiro
                if (ENOENT != errno) FILE_OP_ERROR(rcfile, "fopen");
96 528 hiro
                return;
97 528 hiro
        }
98 528 hiro
99 528 hiro
        block_label = g_strdup_printf("[%s]", label);
100 528 hiro
101 528 hiro
        /* search aiming block */
102 528 hiro
        while (fgets(buf, sizeof(buf), fp) != NULL) {
103 528 hiro
                gint val;
104 528 hiro
105 528 hiro
                if (encoding) {
106 528 hiro
                        gchar *conv_str;
107 528 hiro
108 528 hiro
                        conv_str = conv_codeset_strdup
109 528 hiro
                                (buf, encoding, CS_INTERNAL);
110 528 hiro
                        if (!conv_str)
111 528 hiro
                                conv_str = g_strdup(buf);
112 528 hiro
                        val = strncmp
113 528 hiro
                                (conv_str, block_label, strlen(block_label));
114 528 hiro
                        g_free(conv_str);
115 528 hiro
                } else
116 528 hiro
                        val = strncmp(buf, block_label, strlen(block_label));
117 528 hiro
                if (val == 0) {
118 528 hiro
                        debug_print("Found %s\n", block_label);
119 528 hiro
                        break;
120 528 hiro
                }
121 528 hiro
        }
122 528 hiro
        g_free(block_label);
123 528 hiro
124 530 hiro
        param_table = prefs_param_table_get(param);
125 530 hiro
126 528 hiro
        while (fgets(buf, sizeof(buf), fp) != NULL) {
127 528 hiro
                strretchomp(buf);
128 530 hiro
                if (buf[0] == '\0') continue;
129 528 hiro
                /* reached next block */
130 528 hiro
                if (buf[0] == '[') break;
131 528 hiro
132 528 hiro
                if (encoding) {
133 528 hiro
                        gchar *conv_str;
134 528 hiro
135 528 hiro
                        conv_str = conv_codeset_strdup
136 528 hiro
                                (buf, encoding, CS_INTERNAL);
137 528 hiro
                        if (!conv_str)
138 528 hiro
                                conv_str = g_strdup(buf);
139 530 hiro
                        prefs_config_parse_one_line(param_table, conv_str);
140 528 hiro
                        g_free(conv_str);
141 528 hiro
                } else
142 530 hiro
                        prefs_config_parse_one_line(param_table, buf);
143 528 hiro
        }
144 528 hiro
145 530 hiro
        prefs_param_table_destroy(param_table);
146 530 hiro
147 528 hiro
        debug_print("Finished reading configuration.\n");
148 528 hiro
        fclose(fp);
149 528 hiro
}
150 528 hiro
151 530 hiro
static void prefs_config_parse_one_line(GHashTable *param_table,
152 530 hiro
                                        const gchar *buf)
153 528 hiro
{
154 530 hiro
        PrefParam *param;
155 530 hiro
        const gchar *p = buf;
156 530 hiro
        gchar *name;
157 528 hiro
        const gchar *value;
158 528 hiro
159 530 hiro
        while (*p && *p != '=')
160 530 hiro
                p++;
161 528 hiro
162 530 hiro
        if (*p != '=') {
163 530 hiro
                g_warning("invalid pref line: %s\n", buf);
164 530 hiro
                return;
165 528 hiro
        }
166 530 hiro
167 530 hiro
        name = g_strndup(buf, p - buf);
168 530 hiro
        value = p + 1;
169 530 hiro
170 530 hiro
        /* debug_print("%s = %s\n", name, value); */
171 530 hiro
172 530 hiro
        param = g_hash_table_lookup(param_table, name);
173 530 hiro
174 530 hiro
        if (!param) {
175 530 hiro
                debug_print("pref key '%s' (value '%s') not found\n",
176 530 hiro
                            name, value);
177 530 hiro
                g_free(name);
178 530 hiro
                return;
179 530 hiro
        }
180 530 hiro
181 530 hiro
        switch (param->type) {
182 530 hiro
        case P_STRING:
183 530 hiro
                g_free(*((gchar **)param->data));
184 530 hiro
                *((gchar **)param->data) = *value ? g_strdup(value) : NULL;
185 530 hiro
                break;
186 530 hiro
        case P_INT:
187 530 hiro
                *((gint *)param->data) = (gint)atoi(value);
188 530 hiro
                break;
189 530 hiro
        case P_BOOL:
190 530 hiro
                *((gboolean *)param->data) =
191 530 hiro
                        (*value == '0' || *value == '\0') ? FALSE : TRUE;
192 530 hiro
                break;
193 530 hiro
        case P_ENUM:
194 530 hiro
                *((DummyEnum *)param->data) = (DummyEnum)atoi(value);
195 530 hiro
                break;
196 530 hiro
        case P_USHORT:
197 530 hiro
                *((gushort *)param->data) = (gushort)atoi(value);
198 530 hiro
                break;
199 530 hiro
        default:
200 530 hiro
                break;
201 530 hiro
        }
202 530 hiro
203 530 hiro
        g_free(name);
204 528 hiro
}
205 528 hiro
206 528 hiro
#define TRY(func) \
207 528 hiro
if (!(func)) \
208 528 hiro
{ \
209 528 hiro
        g_warning(_("failed to write configuration to file\n")); \
210 528 hiro
        if (orig_fp) fclose(orig_fp); \
211 528 hiro
        prefs_file_close_revert(pfile); \
212 528 hiro
        g_free(rcpath); \
213 528 hiro
        g_free(block_label); \
214 528 hiro
        return; \
215 528 hiro
} \
216 528 hiro
217 528 hiro
void prefs_write_config(PrefParam *param, const gchar *label,
218 528 hiro
                        const gchar *rcfile)
219 528 hiro
{
220 528 hiro
        FILE *orig_fp;
221 528 hiro
        PrefFile *pfile;
222 528 hiro
        gchar *rcpath;
223 528 hiro
        gchar buf[PREFSBUFSIZE];
224 528 hiro
        gchar *block_label = NULL;
225 528 hiro
        gboolean block_matched = FALSE;
226 528 hiro
227 528 hiro
        g_return_if_fail(param != NULL);
228 528 hiro
        g_return_if_fail(label != NULL);
229 528 hiro
        g_return_if_fail(rcfile != NULL);
230 528 hiro
231 528 hiro
        rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, rcfile, NULL);
232 528 hiro
        if ((orig_fp = g_fopen(rcpath, "rb")) == NULL) {
233 528 hiro
                if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
234 528 hiro
        }
235 528 hiro
236 528 hiro
        if ((pfile = prefs_file_open(rcpath)) == NULL) {
237 528 hiro
                g_warning(_("failed to write configuration to file\n"));
238 528 hiro
                if (orig_fp) fclose(orig_fp);
239 528 hiro
                g_free(rcpath);
240 528 hiro
                return;
241 528 hiro
        }
242 528 hiro
243 528 hiro
        block_label = g_strdup_printf("[%s]", label);
244 528 hiro
245 528 hiro
        /* search aiming block */
246 528 hiro
        if (orig_fp) {
247 528 hiro
                while (fgets(buf, sizeof(buf), orig_fp) != NULL) {
248 528 hiro
                        gint val;
249 528 hiro
250 528 hiro
                        val = strncmp(buf, block_label, strlen(block_label));
251 528 hiro
                        if (val == 0) {
252 528 hiro
                                debug_print(_("Found %s\n"), block_label);
253 528 hiro
                                block_matched = TRUE;
254 528 hiro
                                break;
255 528 hiro
                        } else
256 528 hiro
                                TRY(fputs(buf, pfile->fp) != EOF);
257 528 hiro
                }
258 528 hiro
        }
259 528 hiro
260 528 hiro
        TRY(fprintf(pfile->fp, "%s\n", block_label) > 0);
261 528 hiro
        g_free(block_label);
262 528 hiro
        block_label = NULL;
263 528 hiro
264 528 hiro
        /* write all param data to file */
265 528 hiro
        TRY(prefs_file_write_param(pfile, param) == 0);
266 528 hiro
267 528 hiro
        if (block_matched) {
268 528 hiro
                while (fgets(buf, sizeof(buf), orig_fp) != NULL) {
269 528 hiro
                        /* next block */
270 528 hiro
                        if (buf[0] == '[') {
271 528 hiro
                                TRY(fputc('\n', pfile->fp) != EOF &&
272 528 hiro
                                    fputs(buf, pfile->fp)  != EOF);
273 528 hiro
                                break;
274 528 hiro
                        }
275 528 hiro
                }
276 528 hiro
                while (fgets(buf, sizeof(buf), orig_fp) != NULL)
277 528 hiro
                        TRY(fputs(buf, pfile->fp) != EOF);
278 528 hiro
        }
279 528 hiro
280 528 hiro
        if (orig_fp) fclose(orig_fp);
281 528 hiro
        if (prefs_file_close(pfile) < 0)
282 528 hiro
                g_warning(_("failed to write configuration to file\n"));
283 528 hiro
        g_free(rcpath);
284 528 hiro
285 528 hiro
        debug_print(_("Configuration is saved.\n"));
286 528 hiro
}
287 528 hiro
288 528 hiro
gint prefs_file_write_param(PrefFile *pfile, PrefParam *param)
289 528 hiro
{
290 528 hiro
        gint i;
291 528 hiro
        gchar buf[PREFSBUFSIZE];
292 528 hiro
293 528 hiro
        for (i = 0; param[i].name != NULL; i++) {
294 528 hiro
                switch (param[i].type) {
295 528 hiro
                case P_STRING:
296 528 hiro
                        g_snprintf(buf, sizeof(buf), "%s=%s\n", param[i].name,
297 528 hiro
                                   *((gchar **)param[i].data) ?
298 528 hiro
                                   *((gchar **)param[i].data) : "");
299 528 hiro
                        break;
300 528 hiro
                case P_INT:
301 528 hiro
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
302 528 hiro
                                   *((gint *)param[i].data));
303 528 hiro
                        break;
304 528 hiro
                case P_BOOL:
305 528 hiro
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
306 528 hiro
                                   *((gboolean *)param[i].data));
307 528 hiro
                        break;
308 528 hiro
                case P_ENUM:
309 528 hiro
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
310 528 hiro
                                   *((DummyEnum *)param[i].data));
311 528 hiro
                        break;
312 528 hiro
                case P_USHORT:
313 528 hiro
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
314 528 hiro
                                   *((gushort *)param[i].data));
315 528 hiro
                        break;
316 528 hiro
                default:
317 528 hiro
                        buf[0] = '\0';
318 528 hiro
                }
319 528 hiro
320 528 hiro
                if (buf[0] != '\0') {
321 528 hiro
                        if (fputs(buf, pfile->fp) == EOF) {
322 528 hiro
                                perror("fputs");
323 528 hiro
                                return -1;
324 528 hiro
                        }
325 528 hiro
                }
326 528 hiro
        }
327 528 hiro
328 528 hiro
        return 0;
329 528 hiro
}
330 528 hiro
331 528 hiro
PrefFile *prefs_file_open(const gchar *path)
332 528 hiro
{
333 2081 hiro
        PrefFilePrivate *pfile;
334 528 hiro
        gchar *tmppath;
335 528 hiro
        FILE *fp;
336 528 hiro
337 528 hiro
        g_return_val_if_fail(path != NULL, NULL);
338 528 hiro
339 528 hiro
        tmppath = g_strconcat(path, ".tmp", NULL);
340 528 hiro
        if ((fp = g_fopen(tmppath, "wb")) == NULL) {
341 528 hiro
                FILE_OP_ERROR(tmppath, "fopen");
342 528 hiro
                g_free(tmppath);
343 528 hiro
                return NULL;
344 528 hiro
        }
345 528 hiro
346 528 hiro
        if (change_file_mode_rw(fp, tmppath) < 0)
347 528 hiro
                FILE_OP_ERROR(tmppath, "chmod");
348 528 hiro
349 528 hiro
        g_free(tmppath);
350 528 hiro
351 2081 hiro
        pfile = g_new(PrefFilePrivate, 1);
352 528 hiro
        pfile->fp = fp;
353 528 hiro
        pfile->path = g_strdup(path);
354 2081 hiro
        pfile->backup_generation = 4;
355 528 hiro
356 2081 hiro
        return (PrefFile *)pfile;
357 528 hiro
}
358 528 hiro
359 2081 hiro
void prefs_file_set_backup_generation(PrefFile *pfile, gint generation)
360 2081 hiro
{
361 2081 hiro
        PrefFilePrivate *priv = (PrefFilePrivate *)pfile;
362 2081 hiro
363 2081 hiro
        g_return_if_fail(pfile != NULL);
364 2081 hiro
365 2081 hiro
        priv->backup_generation = generation;
366 2081 hiro
}
367 2081 hiro
368 2081 hiro
gint prefs_file_get_backup_generation(PrefFile *pfile)
369 2081 hiro
{
370 2081 hiro
        PrefFilePrivate *priv = (PrefFilePrivate *)pfile;
371 2081 hiro
372 2081 hiro
        g_return_val_if_fail(pfile != NULL, -1);
373 2081 hiro
374 2081 hiro
        return priv->backup_generation;
375 2081 hiro
}
376 2081 hiro
377 528 hiro
gint prefs_file_close(PrefFile *pfile)
378 528 hiro
{
379 2081 hiro
        PrefFilePrivate *priv = (PrefFilePrivate *)pfile;
380 528 hiro
        FILE *fp;
381 528 hiro
        gchar *path;
382 528 hiro
        gchar *tmppath;
383 528 hiro
        gchar *bakpath = NULL;
384 2081 hiro
        gint generation;
385 2071 hiro
        gint ret = 0;
386 528 hiro
387 528 hiro
        g_return_val_if_fail(pfile != NULL, -1);
388 528 hiro
389 528 hiro
        fp = pfile->fp;
390 528 hiro
        path = pfile->path;
391 2081 hiro
        generation = priv->backup_generation;
392 528 hiro
        g_free(pfile);
393 528 hiro
394 528 hiro
        tmppath = g_strconcat(path, ".tmp", NULL);
395 2121 hiro
        if (fflush(fp) == EOF) {
396 2121 hiro
                FILE_OP_ERROR(tmppath, "fflush");
397 2121 hiro
                fclose(fp);
398 2121 hiro
                ret = -1;
399 2121 hiro
                goto finish;
400 2121 hiro
        }
401 2121 hiro
#if HAVE_FSYNC
402 2123 hiro
        if (fsync(fileno(fp)) < 0) {
403 2123 hiro
                FILE_OP_ERROR(tmppath, "fsync");
404 2123 hiro
                fclose(fp);
405 2123 hiro
                ret = -1;
406 2123 hiro
                goto finish;
407 2122 hiro
        }
408 2123 hiro
#elif defined(G_OS_WIN32)
409 2123 hiro
        if (_commit(_fileno(fp)) < 0) {
410 2123 hiro
                FILE_OP_ERROR(tmppath, "_commit");
411 2123 hiro
                fclose(fp);
412 2123 hiro
                ret = -1;
413 2123 hiro
                goto finish;
414 2123 hiro
        }
415 2121 hiro
#endif
416 528 hiro
        if (fclose(fp) == EOF) {
417 528 hiro
                FILE_OP_ERROR(tmppath, "fclose");
418 2071 hiro
                ret = -1;
419 2071 hiro
                goto finish;
420 528 hiro
        }
421 528 hiro
422 528 hiro
        if (is_file_exist(path)) {
423 528 hiro
                bakpath = g_strconcat(path, ".bak", NULL);
424 2071 hiro
                if (is_file_exist(bakpath)) {
425 2071 hiro
                        gint i;
426 2071 hiro
                        gchar *bakpath_n, *bakpath_p;
427 2071 hiro
428 2081 hiro
                        for (i = generation; i > 0; i--) {
429 2071 hiro
                                bakpath_n = g_strdup_printf("%s.%d", bakpath,
430 2071 hiro
                                                            i);
431 2071 hiro
                                if (i == 1)
432 2071 hiro
                                        bakpath_p = g_strdup(bakpath);
433 2071 hiro
                                else
434 2071 hiro
                                        bakpath_p = g_strdup_printf
435 2071 hiro
                                                ("%s.%d", bakpath, i - 1);
436 2071 hiro
                                if (is_file_exist(bakpath_p)) {
437 2071 hiro
                                        if (rename_force(bakpath_p, bakpath_n) < 0) {
438 2071 hiro
                                                FILE_OP_ERROR(bakpath_p,
439 2071 hiro
                                                              "rename");
440 2071 hiro
                                        }
441 2071 hiro
                                }
442 2071 hiro
                                g_free(bakpath_p);
443 2071 hiro
                                g_free(bakpath_n);
444 2071 hiro
                        }
445 2071 hiro
                }
446 528 hiro
                if (rename_force(path, bakpath) < 0) {
447 528 hiro
                        FILE_OP_ERROR(path, "rename");
448 2071 hiro
                        ret = -1;
449 2071 hiro
                        goto finish;
450 528 hiro
                }
451 528 hiro
        }
452 528 hiro
453 528 hiro
        if (rename_force(tmppath, path) < 0) {
454 528 hiro
                FILE_OP_ERROR(tmppath, "rename");
455 2071 hiro
                ret = -1;
456 2071 hiro
                goto finish;
457 528 hiro
        }
458 528 hiro
459 2071 hiro
finish:
460 2071 hiro
        if (ret < 0)
461 2071 hiro
                g_unlink(tmppath);
462 528 hiro
        g_free(path);
463 528 hiro
        g_free(tmppath);
464 528 hiro
        g_free(bakpath);
465 2071 hiro
        return ret;
466 528 hiro
}
467 528 hiro
468 528 hiro
gint prefs_file_close_revert(PrefFile *pfile)
469 528 hiro
{
470 528 hiro
        gchar *tmppath;
471 528 hiro
472 528 hiro
        g_return_val_if_fail(pfile != NULL, -1);
473 528 hiro
474 528 hiro
        tmppath = g_strconcat(pfile->path, ".tmp", NULL);
475 528 hiro
        fclose(pfile->fp);
476 528 hiro
        if (g_unlink(tmppath) < 0)
477 528 hiro
                FILE_OP_ERROR(tmppath, "unlink");
478 528 hiro
        g_free(tmppath);
479 528 hiro
        g_free(pfile->path);
480 528 hiro
        g_free(pfile);
481 528 hiro
482 528 hiro
        return 0;
483 528 hiro
}
484 528 hiro
485 528 hiro
void prefs_set_default(PrefParam *param)
486 528 hiro
{
487 528 hiro
        gint i;
488 528 hiro
489 528 hiro
        g_return_if_fail(param != NULL);
490 528 hiro
491 528 hiro
        for (i = 0; param[i].name != NULL; i++) {
492 528 hiro
                if (!param[i].data) continue;
493 528 hiro
494 528 hiro
                switch (param[i].type) {
495 528 hiro
                case P_STRING:
496 528 hiro
                        if (param[i].defval != NULL) {
497 528 hiro
                                if (!g_ascii_strncasecmp(param[i].defval, "ENV_", 4)) {
498 528 hiro
                                        const gchar *envstr;
499 528 hiro
                                        gchar *tmp = NULL;
500 528 hiro
501 528 hiro
                                        envstr = g_getenv(param[i].defval + 4);
502 624 hiro
#ifdef G_OS_WIN32
503 624 hiro
                                        tmp = g_strdup(envstr);
504 624 hiro
#else
505 528 hiro
                                        if (envstr) {
506 528 hiro
                                                tmp = conv_codeset_strdup
507 528 hiro
                                                        (envstr,
508 528 hiro
                                                         conv_get_locale_charset_str(),
509 528 hiro
                                                         CS_UTF_8);
510 528 hiro
                                                if (!tmp) {
511 528 hiro
                                                        g_warning("failed to convert character set.");
512 528 hiro
                                                        tmp = g_strdup(envstr);
513 528 hiro
                                                }
514 528 hiro
                                        }
515 624 hiro
#endif
516 528 hiro
                                        *((gchar **)param[i].data) = tmp;
517 528 hiro
                                } else if (param[i].defval[0] == '~')
518 528 hiro
                                        *((gchar **)param[i].data) =
519 624 hiro
#ifdef G_OS_WIN32
520 624 hiro
                                                g_strconcat(get_rc_dir(),
521 624 hiro
#else
522 528 hiro
                                                g_strconcat(get_home_dir(),
523 624 hiro
#endif
524 528 hiro
                                                            param[i].defval + 1,
525 528 hiro
                                                            NULL);
526 528 hiro
                                else if (param[i].defval[0] != '\0')
527 528 hiro
                                        *((gchar **)param[i].data) =
528 528 hiro
                                                g_strdup(param[i].defval);
529 528 hiro
                                else
530 528 hiro
                                        *((gchar **)param[i].data) = NULL;
531 528 hiro
                        } else
532 528 hiro
                                *((gchar **)param[i].data) = NULL;
533 528 hiro
                        break;
534 528 hiro
                case P_INT:
535 528 hiro
                        if (param[i].defval != NULL)
536 528 hiro
                                *((gint *)param[i].data) =
537 528 hiro
                                        (gint)atoi(param[i].defval);
538 528 hiro
                        else
539 528 hiro
                                *((gint *)param[i].data) = 0;
540 528 hiro
                        break;
541 528 hiro
                case P_BOOL:
542 528 hiro
                        if (param[i].defval != NULL) {
543 528 hiro
                                if (!g_ascii_strcasecmp(param[i].defval, "TRUE"))
544 528 hiro
                                        *((gboolean *)param[i].data) = TRUE;
545 528 hiro
                                else
546 528 hiro
                                        *((gboolean *)param[i].data) =
547 528 hiro
                                                atoi(param[i].defval) ? TRUE : FALSE;
548 528 hiro
                        } else
549 528 hiro
                                *((gboolean *)param[i].data) = FALSE;
550 528 hiro
                        break;
551 528 hiro
                case P_ENUM:
552 528 hiro
                        if (param[i].defval != NULL)
553 528 hiro
                                *((DummyEnum*)param[i].data) =
554 528 hiro
                                        (DummyEnum)atoi(param[i].defval);
555 528 hiro
                        else
556 528 hiro
                                *((DummyEnum *)param[i].data) = 0;
557 528 hiro
                        break;
558 528 hiro
                case P_USHORT:
559 528 hiro
                        if (param[i].defval != NULL)
560 528 hiro
                                *((gushort *)param[i].data) =
561 528 hiro
                                        (gushort)atoi(param[i].defval);
562 528 hiro
                        else
563 528 hiro
                                *((gushort *)param[i].data) = 0;
564 528 hiro
                        break;
565 528 hiro
                default:
566 528 hiro
                        break;
567 528 hiro
                }
568 528 hiro
        }
569 528 hiro
}
570 528 hiro
571 528 hiro
void prefs_free(PrefParam *param)
572 528 hiro
{
573 528 hiro
        gint i;
574 528 hiro
575 528 hiro
        g_return_if_fail(param != NULL);
576 528 hiro
577 528 hiro
        for (i = 0; param[i].name != NULL; i++) {
578 528 hiro
                if (!param[i].data) continue;
579 528 hiro
580 528 hiro
                switch (param[i].type) {
581 528 hiro
                case P_STRING:
582 528 hiro
                        g_free(*((gchar **)param[i].data));
583 528 hiro
                        break;
584 528 hiro
                default:
585 528 hiro
                        break;
586 528 hiro
                }
587 528 hiro
        }
588 528 hiro
}