Search
lxdream.org :: lxdream/src/config.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/config.c
changeset 561:533f6b478071
prev480:d28c2992f5ee
next608:4f588e52bce0
author nkeynes
date Tue Jan 01 05:08:38 2008 +0000 (12 years ago)
branchlxdream-mmu
permissions -rw-r--r--
last change Enable Id keyword on all source files
file annotate diff log raw
nkeynes@450
     1
/**
nkeynes@561
     2
 * $Id$
nkeynes@450
     3
 *
nkeynes@450
     4
 * User configuration support
nkeynes@450
     5
 *
nkeynes@450
     6
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@450
     7
 *
nkeynes@450
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@450
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@450
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@450
    11
 * (at your option) any later version.
nkeynes@450
    12
 *
nkeynes@450
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@450
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@450
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@450
    16
 * GNU General Public License for more details.
nkeynes@450
    17
 */
nkeynes@450
    18
nkeynes@450
    19
#include <unistd.h>
nkeynes@450
    20
#include <stdio.h>
nkeynes@450
    21
#include <errno.h>
nkeynes@450
    22
#include <stdlib.h>
nkeynes@450
    23
#include <string.h>
nkeynes@480
    24
#include <glib/gmem.h>
nkeynes@450
    25
#include <glib/gstrfuncs.h>
nkeynes@450
    26
#include "dream.h"
nkeynes@450
    27
#include "config.h"
nkeynes@450
    28
#include "maple/maple.h"
nkeynes@450
    29
nkeynes@450
    30
gboolean lxdream_load_config_file( const gchar *filename );
nkeynes@450
    31
gboolean lxdream_save_config_file( const gchar *filename );
nkeynes@450
    32
gboolean lxdream_load_config_stream( FILE *f );
nkeynes@450
    33
gboolean lxdream_save_config_stream( FILE *f );
nkeynes@450
    34
nkeynes@450
    35
static struct lxdream_config_entry global_config[] =
nkeynes@450
    36
    {{ "bios", CONFIG_TYPE_FILE, "dcboot.rom" },
nkeynes@450
    37
     { "flash", CONFIG_TYPE_FILE, "dcflash.rom" },
nkeynes@450
    38
     { "default path", CONFIG_TYPE_PATH, "." },
nkeynes@450
    39
     { "save path", CONFIG_TYPE_PATH, "save" },
nkeynes@450
    40
     { "bootstrap", CONFIG_TYPE_FILE, "IP.BIN" },
nkeynes@464
    41
     { "gdrom", CONFIG_TYPE_FILE, NULL },
nkeynes@470
    42
     { "recent", CONFIG_TYPE_FILE, NULL },
nkeynes@450
    43
     { NULL, CONFIG_TYPE_NONE }};
nkeynes@450
    44
nkeynes@450
    45
static struct lxdream_config_entry serial_config[] =
nkeynes@450
    46
    {{ "device", CONFIG_TYPE_FILE, "/dev/ttyS1" },
nkeynes@450
    47
     { NULL, CONFIG_TYPE_NONE }};
nkeynes@450
    48
nkeynes@450
    49
struct lxdream_config_group lxdream_config_root[] = 
nkeynes@450
    50
    {{ "global", global_config },
nkeynes@450
    51
     { "controllers", NULL },
nkeynes@450
    52
     { "serial", serial_config },
nkeynes@450
    53
     { NULL, CONFIG_TYPE_NONE }};
nkeynes@450
    54
nkeynes@450
    55
static gchar *lxdream_config_load_filename = NULL;
nkeynes@450
    56
static gchar *lxdream_config_save_filename = NULL;
nkeynes@450
    57
nkeynes@450
    58
gboolean lxdream_find_config()
nkeynes@450
    59
{
nkeynes@480
    60
    gboolean result = TRUE;
nkeynes@450
    61
    char *home = getenv("HOME");
nkeynes@450
    62
    if( lxdream_config_save_filename == NULL ) {
nkeynes@450
    63
	lxdream_config_save_filename = g_strdup_printf("%s/.%s", home, DEFAULT_CONFIG_FILENAME);
nkeynes@450
    64
    }
nkeynes@450
    65
    if( lxdream_config_load_filename == NULL ) {
nkeynes@450
    66
	if( access(lxdream_config_save_filename, R_OK) == 0 ) {
nkeynes@450
    67
	    lxdream_config_load_filename = g_strdup(lxdream_config_save_filename);
nkeynes@450
    68
	} else if( access( PACKAGE_CONF_DIR "/" DEFAULT_CONFIG_FILENAME, R_OK ) == 0 ) {
nkeynes@450
    69
	    lxdream_config_load_filename = g_strdup(PACKAGE_CONF_DIR "/" DEFAULT_CONFIG_FILENAME);
nkeynes@450
    70
	} else if( access( "./" DEFAULT_CONFIG_FILENAME, R_OK ) == 0 ) {
nkeynes@450
    71
	    lxdream_config_load_filename = g_strdup("./" DEFAULT_CONFIG_FILENAME);
nkeynes@450
    72
	} else {
nkeynes@450
    73
	    lxdream_config_load_filename = g_strdup(lxdream_config_save_filename);
nkeynes@480
    74
	    result = FALSE;
nkeynes@450
    75
	}	
nkeynes@480
    76
    }
nkeynes@480
    77
    return result;
nkeynes@450
    78
}
nkeynes@450
    79
nkeynes@450
    80
void lxdream_set_config_filename( const gchar *filename )
nkeynes@450
    81
{
nkeynes@450
    82
    if( lxdream_config_load_filename != NULL ) {
nkeynes@450
    83
	g_free(lxdream_config_load_filename);
nkeynes@450
    84
    }
nkeynes@450
    85
    lxdream_config_load_filename = g_strdup(filename);
nkeynes@450
    86
    if( lxdream_config_save_filename != NULL ) {
nkeynes@450
    87
	g_free(lxdream_config_save_filename);
nkeynes@450
    88
    }
nkeynes@450
    89
    lxdream_config_save_filename = g_strdup(filename);
nkeynes@450
    90
}
nkeynes@450
    91
nkeynes@450
    92
void lxdream_set_default_config( )
nkeynes@450
    93
{
nkeynes@450
    94
    struct lxdream_config_group *group = lxdream_config_root;
nkeynes@450
    95
    while( group->key != NULL ) {
nkeynes@450
    96
	struct lxdream_config_entry *param = group->params;
nkeynes@450
    97
	if( param != NULL ) {
nkeynes@450
    98
	    while( param->key != NULL ) {
nkeynes@450
    99
		if( param->value != param->default_value ) {
nkeynes@450
   100
		    if( param->value != NULL )
nkeynes@450
   101
			free( param->value );
nkeynes@450
   102
		    param->value = (gchar *)param->default_value;
nkeynes@450
   103
		}
nkeynes@450
   104
		param++;
nkeynes@450
   105
	    }
nkeynes@450
   106
	}
nkeynes@450
   107
	group++;
nkeynes@450
   108
    }
nkeynes@450
   109
    maple_detach_all();
nkeynes@450
   110
}
nkeynes@450
   111
nkeynes@450
   112
const gchar *lxdream_get_config_value( int key )
nkeynes@450
   113
{
nkeynes@450
   114
    return global_config[key].value;
nkeynes@450
   115
}
nkeynes@450
   116
nkeynes@460
   117
void lxdream_set_config_value( lxdream_config_entry_t param, const gchar *value )
nkeynes@450
   118
{
nkeynes@475
   119
    if( param->value != value ) {
nkeynes@475
   120
	if( param->value != param->default_value && param->value != NULL ) {
nkeynes@475
   121
	    free( param->value );
nkeynes@475
   122
	}
nkeynes@475
   123
	param->value = g_strdup(value);
nkeynes@450
   124
    }
nkeynes@450
   125
}
nkeynes@450
   126
nkeynes@460
   127
void lxdream_set_global_config_value( int key, const gchar *value )
nkeynes@460
   128
{
nkeynes@460
   129
    lxdream_set_config_value(&global_config[key], value);
nkeynes@460
   130
}
nkeynes@460
   131
nkeynes@458
   132
gboolean lxdream_set_group_value( lxdream_config_group_t group, const gchar *key, const gchar *value )
nkeynes@458
   133
{
nkeynes@458
   134
    int i;
nkeynes@458
   135
    for( i=0; group->params[i].key != NULL; i++ ) {
nkeynes@458
   136
	if( strcasecmp( group->params[i].key, key ) == 0 ) {
nkeynes@460
   137
	    lxdream_set_config_value( &group->params[i], value );
nkeynes@458
   138
	    return TRUE;
nkeynes@458
   139
	}
nkeynes@458
   140
    }
nkeynes@458
   141
    return FALSE;
nkeynes@458
   142
}
nkeynes@458
   143
nkeynes@460
   144
void lxdream_copy_config_list( lxdream_config_entry_t dest, lxdream_config_entry_t src )
nkeynes@460
   145
{
nkeynes@460
   146
    int i;
nkeynes@460
   147
    for( i=0; src[i].key != NULL; i++ ) {
nkeynes@460
   148
	lxdream_set_config_value( &dest[i], src[i].value );
nkeynes@460
   149
    }
nkeynes@460
   150
}
nkeynes@460
   151
nkeynes@450
   152
gboolean lxdream_load_config( )
nkeynes@450
   153
{
nkeynes@450
   154
    if( lxdream_config_load_filename == NULL ) {
nkeynes@450
   155
	lxdream_find_config();
nkeynes@450
   156
    }
nkeynes@450
   157
    return lxdream_load_config_file(lxdream_config_load_filename);
nkeynes@450
   158
}
nkeynes@450
   159
nkeynes@450
   160
gboolean lxdream_save_config( )
nkeynes@450
   161
{
nkeynes@450
   162
    if( lxdream_config_save_filename == NULL ) {
nkeynes@450
   163
	lxdream_find_config();
nkeynes@450
   164
    }
nkeynes@450
   165
    return lxdream_save_config_file(lxdream_config_save_filename);
nkeynes@450
   166
}
nkeynes@450
   167
nkeynes@450
   168
gboolean lxdream_load_config_file( const gchar *filename )
nkeynes@450
   169
{
nkeynes@450
   170
    FILE *f;
nkeynes@450
   171
    gboolean result;
nkeynes@450
   172
nkeynes@450
   173
    if( access(filename, F_OK) != 0 ) {
nkeynes@450
   174
	INFO( "Configuration file '%s' does not exist, creating from defaults" );
nkeynes@450
   175
	lxdream_set_default_config();
nkeynes@450
   176
	lxdream_save_config();
nkeynes@450
   177
    }
nkeynes@450
   178
nkeynes@450
   179
    f = fopen(filename, "ro");
nkeynes@450
   180
    if( f == NULL ) {
nkeynes@450
   181
	ERROR( "Unable to open configuration file '%s': %s", filename, strerror(errno) );
nkeynes@450
   182
	lxdream_set_default_config();
nkeynes@450
   183
	return FALSE;
nkeynes@450
   184
    }
nkeynes@450
   185
nkeynes@450
   186
    result = lxdream_load_config_stream( f );
nkeynes@450
   187
    fclose(f);
nkeynes@450
   188
    return result;
nkeynes@450
   189
}
nkeynes@450
   190
nkeynes@450
   191
gboolean lxdream_load_config_stream( FILE *f )
nkeynes@450
   192
{
nkeynes@450
   193
nkeynes@450
   194
    char buf[512];
nkeynes@450
   195
    int maple_device = -1, maple_subdevice = -1;
nkeynes@450
   196
    struct lxdream_config_group devgroup;
nkeynes@450
   197
    struct lxdream_config_group *group = NULL;
nkeynes@450
   198
    maple_device_t device = NULL;
nkeynes@450
   199
    lxdream_set_default_config();
nkeynes@450
   200
nkeynes@450
   201
    while( fgets( buf, sizeof(buf), f ) != NULL ) {
nkeynes@450
   202
	g_strstrip(buf);
nkeynes@450
   203
	if( buf[0] == '#' )
nkeynes@450
   204
	    continue;
nkeynes@450
   205
	if( *buf == '[' ) {
nkeynes@450
   206
	    char *p = strchr(buf, ']');
nkeynes@450
   207
	    if( p != NULL ) {
nkeynes@450
   208
		struct lxdream_config_group *tmp_group;
nkeynes@450
   209
		maple_device = maple_subdevice = -1;
nkeynes@450
   210
		*p = '\0';
nkeynes@450
   211
		g_strstrip(buf+1);
nkeynes@450
   212
		tmp_group = &lxdream_config_root[0];
nkeynes@450
   213
		while( tmp_group->key != NULL ) {
nkeynes@450
   214
		    if( strcasecmp(tmp_group->key, buf+1) == 0 ) {
nkeynes@450
   215
			group = tmp_group;
nkeynes@450
   216
			break;
nkeynes@450
   217
		    }
nkeynes@450
   218
		    tmp_group++;
nkeynes@450
   219
		}
nkeynes@450
   220
	    }
nkeynes@450
   221
	} else if( group != NULL ) {
nkeynes@450
   222
	    char *value = strchr( buf, '=' );
nkeynes@450
   223
	    if( value != NULL ) {
nkeynes@450
   224
		struct lxdream_config_entry *param = group->params;
nkeynes@450
   225
		*value = '\0';
nkeynes@450
   226
		value++;
nkeynes@450
   227
		g_strstrip(buf);
nkeynes@450
   228
		g_strstrip(value);
nkeynes@450
   229
		if( strcmp(group->key,"controllers") == 0  ) {
nkeynes@450
   230
		    if( g_strncasecmp( buf, "device ", 7 ) == 0 ) {
nkeynes@450
   231
			maple_device = strtoul( buf+7, NULL, 0 );
nkeynes@450
   232
			if( maple_device < 0 || maple_device > 3 ) {
nkeynes@450
   233
			    ERROR( "Device number must be between 0..3 (not '%s')", buf+7);
nkeynes@450
   234
			    continue;
nkeynes@450
   235
			}
nkeynes@450
   236
			maple_subdevice = 0;
nkeynes@450
   237
			device = maple_new_device( value );
nkeynes@450
   238
			if( device == NULL ) {
nkeynes@450
   239
			    ERROR( "Unrecognized device '%s'", value );
nkeynes@450
   240
			} else {
nkeynes@450
   241
			    devgroup.key = "controllers";
nkeynes@450
   242
			    devgroup.params = maple_get_device_config(device);
nkeynes@450
   243
			    maple_attach_device( device, maple_device, maple_subdevice );
nkeynes@450
   244
			    group = &devgroup;
nkeynes@450
   245
			}
nkeynes@450
   246
			continue;
nkeynes@450
   247
		    } else if( g_strncasecmp( buf, "subdevice ", 10 ) == 0 ) {
nkeynes@450
   248
			maple_subdevice = strtoul( buf+10, NULL, 0 );
nkeynes@450
   249
			if( maple_device == -1 ) {
nkeynes@450
   250
			    ERROR( "Subdevice not allowed without primary device" );
nkeynes@450
   251
			} else if( maple_subdevice < 1 || maple_subdevice > 5 ) {
nkeynes@450
   252
			    ERROR( "Subdevice must be between 1..5 (not '%s')", buf+10 );
nkeynes@450
   253
			} else if( (device = maple_new_device(value)) == NULL ) {
nkeynes@450
   254
			    ERROR( "Unrecognized subdevice '%s'", value );
nkeynes@450
   255
			} else {
nkeynes@450
   256
			    devgroup.key = "controllers";
nkeynes@450
   257
			    devgroup.params = maple_get_device_config(device);
nkeynes@450
   258
			    maple_attach_device( device, maple_device, maple_subdevice );
nkeynes@450
   259
			    group = &devgroup;
nkeynes@450
   260
			}
nkeynes@450
   261
			continue;
nkeynes@450
   262
		    }
nkeynes@450
   263
		}
nkeynes@450
   264
		while( param->key != NULL ) {
nkeynes@450
   265
		    if( strcasecmp( param->key, buf ) == 0 ) {
nkeynes@450
   266
			param->value = g_strdup(value);
nkeynes@450
   267
			break;
nkeynes@450
   268
		    }
nkeynes@450
   269
		    param++;
nkeynes@450
   270
		}
nkeynes@450
   271
	    }
nkeynes@450
   272
	}
nkeynes@450
   273
    }
nkeynes@450
   274
    return TRUE;
nkeynes@450
   275
}
nkeynes@450
   276
nkeynes@450
   277
gboolean lxdream_save_config_file( const gchar *filename )
nkeynes@450
   278
{
nkeynes@450
   279
    FILE *f = fopen(filename, "wo");
nkeynes@450
   280
    gboolean result;
nkeynes@450
   281
    if( f == NULL ) {
nkeynes@450
   282
	ERROR( "Unable to open '%s': %s", filename, strerror(errno) );
nkeynes@450
   283
	return FALSE;
nkeynes@450
   284
    }
nkeynes@450
   285
    result = lxdream_save_config_stream(f);
nkeynes@450
   286
    fclose(f);
nkeynes@450
   287
    return TRUE;
nkeynes@450
   288
}    
nkeynes@450
   289
nkeynes@450
   290
gboolean lxdream_save_config_stream( FILE *f )
nkeynes@450
   291
{
nkeynes@450
   292
    struct lxdream_config_group *group = &lxdream_config_root[0];
nkeynes@450
   293
    
nkeynes@450
   294
    while( group->key != NULL ) {
nkeynes@450
   295
	struct lxdream_config_entry *entry = group->params;
nkeynes@450
   296
	fprintf( f, "[%s]\n", group->key );
nkeynes@450
   297
	
nkeynes@450
   298
	if( entry != NULL ) {
nkeynes@450
   299
	    while( entry->key != NULL ) {
nkeynes@470
   300
		if( entry->value != NULL ) {
nkeynes@470
   301
		    fprintf( f, "%s = %s\n", entry->key, entry->value );
nkeynes@470
   302
		}
nkeynes@450
   303
		entry++;
nkeynes@450
   304
	    }
nkeynes@450
   305
	} else if( strcmp(group->key, "controllers") == 0 ) {
nkeynes@450
   306
	    int i,j;
nkeynes@450
   307
	    for( i=0; i<4; i++ ) {
nkeynes@450
   308
		for( j=0; j<6; j++ ) {
nkeynes@450
   309
		    maple_device_t dev = maple_get_device( i, j );
nkeynes@450
   310
		    if( dev != NULL ) {
nkeynes@450
   311
			if( j == 0 )
nkeynes@450
   312
			    fprintf( f, "Device %d = %s\n", i, dev->device_class->name );
nkeynes@450
   313
			else 
nkeynes@450
   314
			    fprintf( f, "Subdevice %d = %s\n", j, dev->device_class->name );
nkeynes@450
   315
			entry = dev->get_config(dev);
nkeynes@450
   316
			while( entry->key != NULL ) {
nkeynes@470
   317
			    if( entry->value != NULL ) {
nkeynes@470
   318
				fprintf( f, "%*c%s = %s\n", j==0?4:8, ' ',entry->key, entry->value );
nkeynes@470
   319
			    }
nkeynes@450
   320
			    entry++;
nkeynes@450
   321
			}
nkeynes@450
   322
		    }
nkeynes@450
   323
		}
nkeynes@450
   324
	    }
nkeynes@450
   325
	}
nkeynes@450
   326
	fprintf( f, "\n" );
nkeynes@450
   327
	group++;
nkeynes@450
   328
    }
nkeynes@450
   329
    return TRUE;
nkeynes@450
   330
}
.