Search
lxdream.org :: lxdream/src/config.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/config.c
changeset 450:207461e79f21
next458:cbb2dd12daeb
author nkeynes
date Wed Oct 17 11:26:45 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Split config management out to config.[ch]
Manage config filename
Check home dir + sysconfdir for conf file
Initial work on a path settings dialog
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/config.c Wed Oct 17 11:26:45 2007 +0000
1.3 @@ -0,0 +1,294 @@
1.4 +/**
1.5 + * $Id: config.c,v 1.1 2007-10-17 11:26:45 nkeynes Exp $
1.6 + *
1.7 + * User configuration support
1.8 + *
1.9 + * Copyright (c) 2005 Nathan Keynes.
1.10 + *
1.11 + * This program is free software; you can redistribute it and/or modify
1.12 + * it under the terms of the GNU General Public License as published by
1.13 + * the Free Software Foundation; either version 2 of the License, or
1.14 + * (at your option) any later version.
1.15 + *
1.16 + * This program is distributed in the hope that it will be useful,
1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.19 + * GNU General Public License for more details.
1.20 + */
1.21 +
1.22 +#include <unistd.h>
1.23 +#include <stdio.h>
1.24 +#include <errno.h>
1.25 +#include <stdlib.h>
1.26 +#include <string.h>
1.27 +#include <glib/gstrfuncs.h>
1.28 +#include "dream.h"
1.29 +#include "config.h"
1.30 +#include "maple/maple.h"
1.31 +
1.32 +gboolean lxdream_load_config_file( const gchar *filename );
1.33 +gboolean lxdream_save_config_file( const gchar *filename );
1.34 +gboolean lxdream_load_config_stream( FILE *f );
1.35 +gboolean lxdream_save_config_stream( FILE *f );
1.36 +
1.37 +static struct lxdream_config_entry global_config[] =
1.38 + {{ "bios", CONFIG_TYPE_FILE, "dcboot.rom" },
1.39 + { "flash", CONFIG_TYPE_FILE, "dcflash.rom" },
1.40 + { "default path", CONFIG_TYPE_PATH, "." },
1.41 + { "save path", CONFIG_TYPE_PATH, "save" },
1.42 + { "bootstrap", CONFIG_TYPE_FILE, "IP.BIN" },
1.43 + { NULL, CONFIG_TYPE_NONE }};
1.44 +
1.45 +static struct lxdream_config_entry serial_config[] =
1.46 + {{ "device", CONFIG_TYPE_FILE, "/dev/ttyS1" },
1.47 + { NULL, CONFIG_TYPE_NONE }};
1.48 +
1.49 +struct lxdream_config_group lxdream_config_root[] =
1.50 + {{ "global", global_config },
1.51 + { "controllers", NULL },
1.52 + { "serial", serial_config },
1.53 + { NULL, CONFIG_TYPE_NONE }};
1.54 +
1.55 +static gchar *lxdream_config_load_filename = NULL;
1.56 +static gchar *lxdream_config_save_filename = NULL;
1.57 +
1.58 +gboolean lxdream_find_config()
1.59 +{
1.60 + char *home = getenv("HOME");
1.61 + if( lxdream_config_save_filename == NULL ) {
1.62 + lxdream_config_save_filename = g_strdup_printf("%s/.%s", home, DEFAULT_CONFIG_FILENAME);
1.63 + }
1.64 + if( lxdream_config_load_filename == NULL ) {
1.65 + if( access(lxdream_config_save_filename, R_OK) == 0 ) {
1.66 + lxdream_config_load_filename = g_strdup(lxdream_config_save_filename);
1.67 + } else if( access( PACKAGE_CONF_DIR "/" DEFAULT_CONFIG_FILENAME, R_OK ) == 0 ) {
1.68 + lxdream_config_load_filename = g_strdup(PACKAGE_CONF_DIR "/" DEFAULT_CONFIG_FILENAME);
1.69 + } else if( access( "./" DEFAULT_CONFIG_FILENAME, R_OK ) == 0 ) {
1.70 + lxdream_config_load_filename = g_strdup("./" DEFAULT_CONFIG_FILENAME);
1.71 + } else {
1.72 + lxdream_config_load_filename = g_strdup(lxdream_config_save_filename);
1.73 + }
1.74 + }
1.75 +}
1.76 +
1.77 +void lxdream_set_config_filename( const gchar *filename )
1.78 +{
1.79 + if( lxdream_config_load_filename != NULL ) {
1.80 + g_free(lxdream_config_load_filename);
1.81 + }
1.82 + lxdream_config_load_filename = g_strdup(filename);
1.83 + if( lxdream_config_save_filename != NULL ) {
1.84 + g_free(lxdream_config_save_filename);
1.85 + }
1.86 + lxdream_config_save_filename = g_strdup(filename);
1.87 +}
1.88 +
1.89 +void lxdream_set_default_config( )
1.90 +{
1.91 + struct lxdream_config_group *group = lxdream_config_root;
1.92 + while( group->key != NULL ) {
1.93 + struct lxdream_config_entry *param = group->params;
1.94 + if( param != NULL ) {
1.95 + while( param->key != NULL ) {
1.96 + if( param->value != param->default_value ) {
1.97 + if( param->value != NULL )
1.98 + free( param->value );
1.99 + param->value = (gchar *)param->default_value;
1.100 + }
1.101 + param++;
1.102 + }
1.103 + }
1.104 + group++;
1.105 + }
1.106 + maple_detach_all();
1.107 +}
1.108 +
1.109 +const gchar *lxdream_get_config_value( int key )
1.110 +{
1.111 + return global_config[key].value;
1.112 +}
1.113 +
1.114 +void lxdream_set_config_value( int key, const gchar *value )
1.115 +{
1.116 + struct lxdream_config_entry *param = &global_config[key];
1.117 + if( param->value != param->default_value && param->value != NULL ) {
1.118 + free( param->value );
1.119 + }
1.120 + param->value = g_strdup(value);
1.121 +}
1.122 +
1.123 +gboolean lxdream_load_config( )
1.124 +{
1.125 + if( lxdream_config_load_filename == NULL ) {
1.126 + lxdream_find_config();
1.127 + }
1.128 + return lxdream_load_config_file(lxdream_config_load_filename);
1.129 +}
1.130 +
1.131 +gboolean lxdream_save_config( )
1.132 +{
1.133 + if( lxdream_config_save_filename == NULL ) {
1.134 + lxdream_find_config();
1.135 + }
1.136 + return lxdream_save_config_file(lxdream_config_save_filename);
1.137 +}
1.138 +
1.139 +gboolean lxdream_load_config_file( const gchar *filename )
1.140 +{
1.141 + FILE *f;
1.142 + gboolean result;
1.143 +
1.144 + if( access(filename, F_OK) != 0 ) {
1.145 + INFO( "Configuration file '%s' does not exist, creating from defaults" );
1.146 + lxdream_set_default_config();
1.147 + lxdream_save_config();
1.148 + }
1.149 +
1.150 + f = fopen(filename, "ro");
1.151 + if( f == NULL ) {
1.152 + ERROR( "Unable to open configuration file '%s': %s", filename, strerror(errno) );
1.153 + lxdream_set_default_config();
1.154 + return FALSE;
1.155 + }
1.156 +
1.157 + result = lxdream_load_config_stream( f );
1.158 + fclose(f);
1.159 + return result;
1.160 +}
1.161 +
1.162 +gboolean lxdream_load_config_stream( FILE *f )
1.163 +{
1.164 +
1.165 + char buf[512];
1.166 + int maple_device = -1, maple_subdevice = -1;
1.167 + struct lxdream_config_group devgroup;
1.168 + struct lxdream_config_group *group = NULL;
1.169 + maple_device_t device = NULL;
1.170 + lxdream_set_default_config();
1.171 +
1.172 + while( fgets( buf, sizeof(buf), f ) != NULL ) {
1.173 + g_strstrip(buf);
1.174 + if( buf[0] == '#' )
1.175 + continue;
1.176 + if( *buf == '[' ) {
1.177 + char *p = strchr(buf, ']');
1.178 + if( p != NULL ) {
1.179 + struct lxdream_config_group *tmp_group;
1.180 + maple_device = maple_subdevice = -1;
1.181 + *p = '\0';
1.182 + g_strstrip(buf+1);
1.183 + tmp_group = &lxdream_config_root[0];
1.184 + while( tmp_group->key != NULL ) {
1.185 + if( strcasecmp(tmp_group->key, buf+1) == 0 ) {
1.186 + group = tmp_group;
1.187 + break;
1.188 + }
1.189 + tmp_group++;
1.190 + }
1.191 + }
1.192 + } else if( group != NULL ) {
1.193 + char *value = strchr( buf, '=' );
1.194 + if( value != NULL ) {
1.195 + struct lxdream_config_entry *param = group->params;
1.196 + *value = '\0';
1.197 + value++;
1.198 + g_strstrip(buf);
1.199 + g_strstrip(value);
1.200 + if( strcmp(group->key,"controllers") == 0 ) {
1.201 + if( g_strncasecmp( buf, "device ", 7 ) == 0 ) {
1.202 + maple_device = strtoul( buf+7, NULL, 0 );
1.203 + if( maple_device < 0 || maple_device > 3 ) {
1.204 + ERROR( "Device number must be between 0..3 (not '%s')", buf+7);
1.205 + continue;
1.206 + }
1.207 + maple_subdevice = 0;
1.208 + device = maple_new_device( value );
1.209 + if( device == NULL ) {
1.210 + ERROR( "Unrecognized device '%s'", value );
1.211 + } else {
1.212 + devgroup.key = "controllers";
1.213 + devgroup.params = maple_get_device_config(device);
1.214 + maple_attach_device( device, maple_device, maple_subdevice );
1.215 + group = &devgroup;
1.216 + }
1.217 + continue;
1.218 + } else if( g_strncasecmp( buf, "subdevice ", 10 ) == 0 ) {
1.219 + maple_subdevice = strtoul( buf+10, NULL, 0 );
1.220 + if( maple_device == -1 ) {
1.221 + ERROR( "Subdevice not allowed without primary device" );
1.222 + } else if( maple_subdevice < 1 || maple_subdevice > 5 ) {
1.223 + ERROR( "Subdevice must be between 1..5 (not '%s')", buf+10 );
1.224 + } else if( (device = maple_new_device(value)) == NULL ) {
1.225 + ERROR( "Unrecognized subdevice '%s'", value );
1.226 + } else {
1.227 + devgroup.key = "controllers";
1.228 + devgroup.params = maple_get_device_config(device);
1.229 + maple_attach_device( device, maple_device, maple_subdevice );
1.230 + group = &devgroup;
1.231 + }
1.232 + continue;
1.233 + }
1.234 + }
1.235 + while( param->key != NULL ) {
1.236 + if( strcasecmp( param->key, buf ) == 0 ) {
1.237 + param->value = g_strdup(value);
1.238 + break;
1.239 + }
1.240 + param++;
1.241 + }
1.242 + }
1.243 + }
1.244 + }
1.245 + return TRUE;
1.246 +}
1.247 +
1.248 +gboolean lxdream_save_config_file( const gchar *filename )
1.249 +{
1.250 + FILE *f = fopen(filename, "wo");
1.251 + gboolean result;
1.252 + if( f == NULL ) {
1.253 + ERROR( "Unable to open '%s': %s", filename, strerror(errno) );
1.254 + return FALSE;
1.255 + }
1.256 + result = lxdream_save_config_stream(f);
1.257 + fclose(f);
1.258 + return TRUE;
1.259 +}
1.260 +
1.261 +gboolean lxdream_save_config_stream( FILE *f )
1.262 +{
1.263 + struct lxdream_config_group *group = &lxdream_config_root[0];
1.264 +
1.265 + while( group->key != NULL ) {
1.266 + struct lxdream_config_entry *entry = group->params;
1.267 + fprintf( f, "[%s]\n", group->key );
1.268 +
1.269 + if( entry != NULL ) {
1.270 + while( entry->key != NULL ) {
1.271 + fprintf( f, "%s = %s\n", entry->key, entry->value );
1.272 + entry++;
1.273 + }
1.274 + } else if( strcmp(group->key, "controllers") == 0 ) {
1.275 + int i,j;
1.276 + for( i=0; i<4; i++ ) {
1.277 + for( j=0; j<6; j++ ) {
1.278 + maple_device_t dev = maple_get_device( i, j );
1.279 + if( dev != NULL ) {
1.280 + if( j == 0 )
1.281 + fprintf( f, "Device %d = %s\n", i, dev->device_class->name );
1.282 + else
1.283 + fprintf( f, "Subdevice %d = %s\n", j, dev->device_class->name );
1.284 + entry = dev->get_config(dev);
1.285 + while( entry->key != NULL ) {
1.286 + fprintf( f, "%*c%s = %s\n", j==0?4:8, ' ',entry->key, entry->value );
1.287 + entry++;
1.288 + }
1.289 + }
1.290 + }
1.291 + }
1.292 + }
1.293 + fprintf( f, "\n" );
1.294 + group++;
1.295 + }
1.296 + return TRUE;
1.297 +}
.