1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/config.c Sun Oct 21 05:31:07 2007 +0000
1.5 + * $Id: config.c,v 1.1 2007-10-17 11:26:45 nkeynes Exp $
1.7 + * User configuration support
1.9 + * Copyright (c) 2005 Nathan Keynes.
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.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.22 +#include <unistd.h>
1.25 +#include <stdlib.h>
1.26 +#include <string.h>
1.27 +#include <glib/gstrfuncs.h>
1.29 +#include "config.h"
1.30 +#include "maple/maple.h"
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.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.45 +static struct lxdream_config_entry serial_config[] =
1.46 + {{ "device", CONFIG_TYPE_FILE, "/dev/ttyS1" },
1.47 + { NULL, CONFIG_TYPE_NONE }};
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.55 +static gchar *lxdream_config_load_filename = NULL;
1.56 +static gchar *lxdream_config_save_filename = NULL;
1.58 +gboolean lxdream_find_config()
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.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.72 + lxdream_config_load_filename = g_strdup(lxdream_config_save_filename);
1.77 +void lxdream_set_config_filename( const gchar *filename )
1.79 + if( lxdream_config_load_filename != NULL ) {
1.80 + g_free(lxdream_config_load_filename);
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.86 + lxdream_config_save_filename = g_strdup(filename);
1.89 +void lxdream_set_default_config( )
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.106 + maple_detach_all();
1.109 +const gchar *lxdream_get_config_value( int key )
1.111 + return global_config[key].value;
1.114 +void lxdream_set_config_value( int key, const gchar *value )
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.120 + param->value = g_strdup(value);
1.123 +gboolean lxdream_load_config( )
1.125 + if( lxdream_config_load_filename == NULL ) {
1.126 + lxdream_find_config();
1.128 + return lxdream_load_config_file(lxdream_config_load_filename);
1.131 +gboolean lxdream_save_config( )
1.133 + if( lxdream_config_save_filename == NULL ) {
1.134 + lxdream_find_config();
1.136 + return lxdream_save_config_file(lxdream_config_save_filename);
1.139 +gboolean lxdream_load_config_file( const gchar *filename )
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.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.157 + result = lxdream_load_config_stream( f );
1.162 +gboolean lxdream_load_config_stream( FILE *f )
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.172 + while( fgets( buf, sizeof(buf), f ) != NULL ) {
1.174 + if( buf[0] == '#' )
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.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.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.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.207 + maple_subdevice = 0;
1.208 + device = maple_new_device( value );
1.209 + if( device == NULL ) {
1.210 + ERROR( "Unrecognized device '%s'", value );
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.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.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.235 + while( param->key != NULL ) {
1.236 + if( strcasecmp( param->key, buf ) == 0 ) {
1.237 + param->value = g_strdup(value);
1.248 +gboolean lxdream_save_config_file( const gchar *filename )
1.250 + FILE *f = fopen(filename, "wo");
1.252 + if( f == NULL ) {
1.253 + ERROR( "Unable to open '%s': %s", filename, strerror(errno) );
1.256 + result = lxdream_save_config_stream(f);
1.261 +gboolean lxdream_save_config_stream( FILE *f )
1.263 + struct lxdream_config_group *group = &lxdream_config_root[0];
1.265 + while( group->key != NULL ) {
1.266 + struct lxdream_config_entry *entry = group->params;
1.267 + fprintf( f, "[%s]\n", group->key );
1.269 + if( entry != NULL ) {
1.270 + while( entry->key != NULL ) {
1.271 + fprintf( f, "%s = %s\n", entry->key, entry->value );
1.274 + } else if( strcmp(group->key, "controllers") == 0 ) {
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.281 + fprintf( f, "Device %d = %s\n", i, dev->device_class->name );
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.293 + fprintf( f, "\n" );