From d83c6c4302760c46197f7c70722a64cbfcaa388e Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 20 Sep 2023 16:05:42 +0200 Subject: [PATCH] normalize all filenames to absolute at init --- dist/x48ng.man.1 | 10 +-- src/emu_init.c | 200 +++++++++++++++++------------------------- src/runtime_options.c | 151 ++++++++++++++++--------------- src/runtime_options.h | 12 ++- src/ui_sdl.c | 2 +- 5 files changed, 175 insertions(+), 200 deletions(-) diff --git a/dist/x48ng.man.1 b/dist/x48ng.man.1 index 597f0b7..62dd489 100644 --- a/dist/x48ng.man.1 +++ b/dist/x48ng.man.1 @@ -57,15 +57,15 @@ where options include: .br \-\-config\-dir= use as x48ng's home (default: ~/.x48ng/) .br - \-\-rom\-file= use (relative to ) as ROM (default: rom) + \-\-rom= use (absolute or relative to ) as ROM (default: rom) .br - \-\-ram\-file= use (relative to ) as RAM (default: ram) + \-\-ram= use (absolute or relative to ) as RAM (default: ram) .br - \-\-state\-file= use (relative to ) as STATE (default: hp48) + \-\-state= use (absolute or relative to ) as STATE (default: hp48) .br - \-\-port1\-file= use (relative to ) as PORT1 (default: port1) + \-\-port1= use (absolute or relative to ) as PORT1 (default: port1) .br - \-\-port2\-file= use (relative to ) as PORT2 (default: port2) + \-\-port2= use (absolute or relative to ) as PORT2 (default: port2) .br \-\-serial\-line= use as serial device default: /dev/ttyS0) .br diff --git a/src/emu_init.c b/src/emu_init.c index 539cd7d..973d4cf 100644 --- a/src/emu_init.c +++ b/src/emu_init.c @@ -117,10 +117,10 @@ int init_emulator( void ) { /* if forced initialize or files were not readble => initialize */ if ( verbose ) - fprintf( stderr, "initialization of %s\n", homeDirectory ); + fprintf( stderr, "initialization of %s\n", normalized_config_path ); init_saturn(); - if ( !read_rom( romFileName ) ) + if ( !read_rom( normalized_rom_path ) ) exit( 1 ); return 0; @@ -391,7 +391,7 @@ int read_mem_file( char* name, word_4* mem, int size ) { /* * size is same as memory size, old version file */ - if ( fread( mem, 1, ( size_t )size, fp ) != size ) { + if ( fread( mem, 1, ( size_t )size, fp ) != ( unsigned long )size ) { if ( verbose ) fprintf( stderr, "can\'t read %s\n", name ); fclose( fp ); @@ -422,7 +422,8 @@ int read_mem_file( char* name, word_4* mem, int size ) { mem[ j++ ] = ( word_4 )( ( ( int )byte >> 4 ) & 0xf ); } } else { - if ( fread( tmp_mem, 1, ( size_t )size / 2, fp ) != size / 2 ) { + if ( fread( tmp_mem, 1, ( size_t )size / 2, fp ) != + ( unsigned long )( size / 2 ) ) { if ( verbose ) fprintf( stderr, "can\'t read %s\n", name ); fclose( fp ); @@ -448,45 +449,30 @@ int read_mem_file( char* name, word_4* mem, int size ) { } int read_files( void ) { - char config_dir[ 1024 ]; - char fnam[ 1024 ]; unsigned long v1, v2; int i, read_version; int ram_size; struct stat st; FILE* fp; - get_home_directory( config_dir ); - strcat( config_dir, "/" ); - /*************************************************/ /* 1. read ROM from ~/.x48ng/rom into saturn.rom */ /*************************************************/ saturn.rom = ( word_4* )NULL; - if ( romFileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, romFileName ); - if ( !read_rom_file( fnam, &saturn.rom, &rom_size ) ) + if ( !read_rom_file( normalized_rom_path, &saturn.rom, &rom_size ) ) return 0; if ( verbose ) - printf( "read %s\n", fnam ); + printf( "read %s\n", normalized_rom_path ); rom_is_new = 0; /**************************************************/ /* 2. read saved state from ~/.x48ng/hp48 into fp */ /**************************************************/ - if ( stateFileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, stateFileName ); - if ( NULL == ( fp = fopen( fnam, "r" ) ) ) { + if ( NULL == ( fp = fopen( normalized_state_path, "r" ) ) ) { if ( verbose ) - fprintf( stderr, "can\'t open %s\n", fnam ); + fprintf( stderr, "can\'t open %s\n", normalized_state_path ); return 0; } @@ -529,10 +515,11 @@ int read_files( void ) { */ if ( !read_state_file( fp ) ) { if ( verbose ) - fprintf( stderr, "can\'t handle %s\n", fnam ); + fprintf( stderr, "can\'t handle %s\n", + normalized_state_path ); init_saturn(); } else if ( verbose ) - printf( "read %s\n", fnam ); + printf( "read %s\n", normalized_state_path ); } } fclose( fp ); @@ -553,17 +540,12 @@ int read_files( void ) { /*************************************************/ /* 3. read RAM from ~/.x48ng/ram into saturn.ram */ /*************************************************/ - if ( ramFileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, ramFileName ); - if ( ( fp = fopen( fnam, "r" ) ) == NULL ) { + if ( ( fp = fopen( normalized_ram_path, "r" ) ) == NULL ) { if ( verbose ) - fprintf( stderr, "can\'t open %s\n", fnam ); + fprintf( stderr, "can\'t open %s\n", normalized_ram_path ); return 0; } - if ( !read_mem_file( fnam, saturn.ram, ram_size ) ) + if ( !read_mem_file( normalized_ram_path, saturn.ram, ram_size ) ) return 0; /**************************************/ @@ -579,18 +561,14 @@ int read_files( void ) { port1_is_ram = 0; saturn.port1 = ( unsigned char* )0; - if ( port1FileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, port1FileName ); - if ( stat( fnam, &st ) >= 0 ) { + if ( stat( normalized_port1_path, &st ) >= 0 ) { port1_size = 2 * st.st_size; if ( ( port1_size == 0x10000 ) || ( port1_size == 0x40000 ) ) { if ( NULL == ( saturn.port1 = ( word_4* )malloc( port1_size ) ) ) { if ( verbose ) fprintf( stderr, "can\'t malloc PORT1[%ld]\n", port1_size ); - } else if ( !read_mem_file( fnam, saturn.port1, port1_size ) ) { + } else if ( !read_mem_file( normalized_port1_path, saturn.port1, + port1_size ) ) { port1_size = 0; port1_is_ram = 0; } else { @@ -616,12 +594,7 @@ int read_files( void ) { port2_is_ram = 0; saturn.port2 = ( unsigned char* )0; - if ( port2FileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, port2FileName ); - if ( stat( fnam, &st ) >= 0 ) { + if ( stat( normalized_port2_path, &st ) >= 0 ) { port2_size = 2 * st.st_size; if ( ( opt_gx && ( ( port2_size % 0x40000 ) == 0 ) ) || ( !opt_gx && @@ -629,7 +602,8 @@ int read_files( void ) { if ( NULL == ( saturn.port2 = ( word_4* )malloc( port2_size ) ) ) { if ( verbose ) fprintf( stderr, "can\'t malloc PORT2[%ld]\n", port2_size ); - } else if ( !read_mem_file( fnam, saturn.port2, port2_size ) ) { + } else if ( !read_mem_file( normalized_port2_path, saturn.port2, + port2_size ) ) { port2_size = 0; port2_is_ram = 0; } else { @@ -773,54 +747,13 @@ int write_mem_file( char* name, word_4* mem, int size ) { return 1; } -int write_files( void ) { - char config_dir[ 1024 ]; - char fnam[ 1024 ]; - struct stat st; - int i, make_dir; - int ram_size; +int write_state_file( char* filename ) { + int i; FILE* fp; - make_dir = 0; - get_home_directory( config_dir ); - - if ( stat( config_dir, &st ) == -1 ) { - if ( errno == ENOENT ) { - make_dir = 1; - } else { - if ( verbose ) - fprintf( stderr, "can\'t stat %s, saving to /tmp\n", - config_dir ); - strcpy( config_dir, "/tmp" ); - } - } else { - if ( !S_ISDIR( st.st_mode ) ) { - if ( verbose ) - fprintf( stderr, "%s is no directory, saving to /tmp\n", - config_dir ); - strcpy( config_dir, "/tmp" ); - } - } - - if ( make_dir ) { - if ( mkdir( config_dir, 0777 ) == -1 ) { - if ( verbose ) - fprintf( stderr, "can\'t mkdir %s, saving to /tmp\n", - config_dir ); - strcpy( config_dir, "/tmp" ); - } - } - - strcat( config_dir, "/" ); - - if ( stateFileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, stateFileName ); - if ( ( fp = fopen( fnam, "w" ) ) == NULL ) { + if ( ( fp = fopen( filename, "w" ) ) == NULL ) { if ( verbose ) - fprintf( stderr, "can\'t open %s, no saving done\n", fnam ); + fprintf( stderr, "can\'t open %s, no saving done\n", filename ); return 0; } @@ -918,45 +851,72 @@ int write_files( void ) { } fclose( fp ); if ( verbose ) - printf( "wrote %s\n", fnam ); + printf( "wrote %s\n", filename ); - if ( rom_is_new ) { - strcpy( fnam, config_dir ); - strcat( fnam, romFileName ); - if ( !write_mem_file( fnam, saturn.rom, rom_size ) ) - return 0; + return 1; +} + +int write_files( void ) { + struct stat st; + int make_dir = 0; + int ram_size = opt_gx ? RAM_SIZE_GX : RAM_SIZE_SX; + + if ( stat( normalized_config_path, &st ) == -1 ) { + if ( errno == ENOENT ) { + make_dir = 1; + } else { + if ( verbose ) + fprintf( stderr, "can\'t stat %s, saving to /tmp\n", + normalized_config_path ); + strcpy( normalized_config_path, "/tmp" ); + } + } else { + if ( !S_ISDIR( st.st_mode ) ) { + if ( verbose ) + fprintf( stderr, "%s is no directory, saving to /tmp\n", + normalized_config_path ); + strcpy( normalized_config_path, "/tmp" ); + } } - if ( opt_gx ) - ram_size = RAM_SIZE_GX; - else - ram_size = RAM_SIZE_SX; + if ( make_dir ) { + if ( mkdir( normalized_config_path, 0777 ) == -1 ) { + if ( verbose ) + fprintf( stderr, "can\'t mkdir %s, saving to /tmp\n", + normalized_config_path ); + strcpy( normalized_config_path, "/tmp" ); + } + } - if ( ramFileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, ramFileName ); - if ( !write_mem_file( fnam, saturn.ram, ram_size ) ) + if ( !write_state_file( normalized_state_path ) ) + return 0; + + rom_is_new = make_dir; + if ( rom_is_new ) { + char new_rom_path[ MAX_LENGTH_FILENAME ]; + + strcpy( new_rom_path, normalized_config_path ); + strcat( new_rom_path, "rom" ); + + if ( !write_mem_file( new_rom_path, saturn.rom, rom_size ) ) + return 0; + + if ( verbose ) + printf( "wrote %s\n", new_rom_path ); + } + + if ( !write_mem_file( normalized_ram_path, saturn.ram, ram_size ) ) return 0; if ( ( port1_size > 0 ) && port1_is_ram ) { - if ( port1FileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, port1FileName ); - if ( !write_mem_file( fnam, saturn.port1, port1_size ) ) + if ( !write_mem_file( normalized_port1_path, saturn.port1, + port1_size ) ) return 0; } if ( ( port2_size > 0 ) && port2_is_ram ) { - if ( port2FileName[ 0 ] == '/' ) - strcpy( fnam, "" ); - else - strcpy( fnam, config_dir ); - strcat( fnam, port2FileName ); - if ( !write_mem_file( fnam, saturn.port2, port2_size ) ) + if ( !write_mem_file( normalized_port2_path, saturn.port2, + port2_size ) ) return 0; } diff --git a/src/runtime_options.c b/src/runtime_options.c index cf94401..cfcfc1a 100644 --- a/src/runtime_options.c +++ b/src/runtime_options.c @@ -20,8 +20,8 @@ int initialize = 0; int resetOnStartup = 0; char* serialLine = "/dev/ttyS0"; -char* homeDirectory = ".x48ng"; +char* configDir = ".x48ng"; char* romFileName = "rom"; char* ramFileName = "ram"; char* stateFileName = "hp48"; @@ -55,31 +55,72 @@ char* mediumFont = "-*-fixed-bold-r-normal-*-15-*-*-*-*-*-iso8859-1"; char* largeFont = "-*-fixed-medium-r-normal-*-20-*-*-*-*-*-iso8859-1"; char* connFont = "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-iso8859-1"; -void get_home_directory( char* path ) { - char* p; +char normalized_config_path[ MAX_LENGTH_FILENAME ]; +char normalized_rom_path[ MAX_LENGTH_FILENAME ]; +char normalized_ram_path[ MAX_LENGTH_FILENAME ]; +char normalized_state_path[ MAX_LENGTH_FILENAME ]; +char normalized_port1_path[ MAX_LENGTH_FILENAME ]; +char normalized_port2_path[ MAX_LENGTH_FILENAME ]; + +void get_absolute_config_dir( char* source, char* dest ) { + char* home; struct passwd* pwd; - if ( homeDirectory[ 0 ] == '/' ) - strcpy( path, homeDirectory ); - else { - p = getenv( "HOME" ); - if ( p ) { - strcpy( path, p ); - strcat( path, "/" ); + if ( source[ 0 ] != '/' ) { + home = getenv( "HOME" ); + if ( home ) { + strcpy( dest, home ); + strcat( dest, "/" ); } else { pwd = getpwuid( getuid() ); if ( pwd ) { - strcpy( path, pwd->pw_dir ); - strcat( path, "/" ); + strcpy( dest, pwd->pw_dir ); + strcat( dest, "/" ); } else { if ( verbose ) fprintf( stderr, "can\'t figure out your home directory, " "trying /tmp\n" ); - strcpy( path, "/tmp" ); + strcpy( dest, "/tmp" ); } } - strcat( path, homeDirectory ); } + strcat( dest, source ); + if ( dest[ strlen( dest ) ] != '/' ) + strcat( dest, "/" ); +} + +static inline void normalize_filenames( void ) { + get_absolute_config_dir( configDir, normalized_config_path ); + + if ( romFileName[ 0 ] == '/' ) + strcpy( normalized_rom_path, "" ); + else + strcpy( normalized_rom_path, normalized_config_path ); + strcat( normalized_rom_path, romFileName ); + + if ( ramFileName[ 0 ] == '/' ) + strcpy( normalized_ram_path, "" ); + else + strcpy( normalized_ram_path, normalized_config_path ); + strcat( normalized_ram_path, ramFileName ); + + if ( stateFileName[ 0 ] == '/' ) + strcpy( normalized_state_path, "" ); + else + strcpy( normalized_state_path, normalized_config_path ); + strcat( normalized_state_path, stateFileName ); + + if ( port1FileName[ 0 ] == '/' ) + strcpy( normalized_port1_path, "" ); + else + strcpy( normalized_port1_path, normalized_config_path ); + strcat( normalized_port1_path, port1FileName ); + + if ( port2FileName[ 0 ] == '/' ) + strcpy( normalized_port2_path, "" ); + else + strcpy( normalized_port2_path, normalized_config_path ); + strcat( normalized_port2_path, port2FileName ); } int parse_args( int argc, char* argv[] ) { @@ -89,11 +130,11 @@ int parse_args( int argc, char* argv[] ) { char* optstring = "c:S:u:hvVtsirT"; static struct option long_options[] = { { "config-dir", required_argument, NULL, 1000 }, - { "rom-file", required_argument, NULL, 1010 }, - { "ram-file", required_argument, NULL, 1011 }, - { "state-file", required_argument, NULL, 1012 }, - { "port1-file", required_argument, NULL, 1013 }, - { "port2-file", required_argument, NULL, 1014 }, + { "rom", required_argument, NULL, 1010 }, + { "ram", required_argument, NULL, 1011 }, + { "state", required_argument, NULL, 1012 }, + { "port1", required_argument, NULL, 1013 }, + { "port2", required_argument, NULL, 1014 }, { "serial-line", required_argument, NULL, 1015 }, @@ -137,15 +178,15 @@ int parse_args( int argc, char* argv[] ) { "\t-v --version\t\t\tshow version\n" "\t --config-dir=\t\tuse as x48ng's home (default: " "~/.x48ng/)\n" - "\t --rom-file=\tuse (absolute or relative to " + "\t --rom=\tuse (absolute or relative to " ") as ROM (default: rom)\n" - "\t --ram-file=\tuse (absolute or relative to " + "\t --ram=\tuse (absolute or relative to " ") as RAM (default: ram)\n" - "\t --state-file=\tuse (absolute or relative " + "\t --state=\tuse (absolute or relative " "to ) as STATE (default: hp48)\n" - "\t --port1-file=\tuse (absolute or relative " + "\t --port1=\tuse (absolute or relative " "to ) as PORT1 (default: port1)\n" - "\t --port2-file=\tuse (absolute or relative " + "\t --port2=\tuse (absolute or relative " "to ) as PORT2 (default: port2)\n" "\t --serial-line=\t\tuse as serial device default: " "%s)\n" @@ -201,7 +242,7 @@ int parse_args( int argc, char* argv[] ) { exit( 0 ); break; case 1000: - homeDirectory = optarg; + configDir = optarg; break; case 1010: romFileName = optarg; @@ -283,6 +324,8 @@ int parse_args( int argc, char* argv[] ) { fprintf( stderr, "\n" ); } + normalize_filenames(); + if ( verbose ) { fprintf( stderr, "verbose = %i\n", verbose ); fprintf( stderr, "useTerminal = %i\n", useTerminal ); @@ -308,7 +351,7 @@ int parse_args( int argc, char* argv[] ) { } fprintf( stderr, "serialLine = %s\n", serialLine ); - fprintf( stderr, "homeDirectory = %s\n", homeDirectory ); + fprintf( stderr, "configDir = %s\n", configDir ); fprintf( stderr, "romFileName = %s\n", romFileName ); fprintf( stderr, "ramFileName = %s\n", ramFileName ); fprintf( stderr, "stateFileName = %s\n", stateFileName ); @@ -328,53 +371,17 @@ int parse_args( int argc, char* argv[] ) { fprintf( stderr, "mediumFont = %s\n", mediumFont ); fprintf( stderr, "largeFont = %s\n", largeFont ); fprintf( stderr, "connFont = %s\n", connFont ); - } - /* check that homeDirectory exists, otherwise initialize */ - char config_dir[ 1024 ]; - char rom_filename[ 1024 ]; - char config_filename[ 1024 ]; - struct stat sb; - - get_home_directory( config_dir ); - if ( romFileName[ 0 ] == '/' ) - strcpy( rom_filename, "" ); - else - strcpy( rom_filename, config_dir ); - strcat( rom_filename, romFileName ); - - if ( stat( config_dir, &sb ) == 0 && S_ISDIR( sb.st_mode ) && - stat( rom_filename, &sb ) == 0 ) { - if ( verbose ) - fprintf( stderr, "%s exists\n", config_dir ); - - /* a config_dir exists with a romFileName in it. */ - /* we can initialize if necessary */ - if ( !initialize ) { - /* Not forced to initialize but does stateFileName exist? */ - if ( stateFileName[ 0 ] == '/' ) - strcpy( config_filename, "" ); - else - strcpy( config_filename, config_dir ); - strcat( config_filename, stateFileName ); - /* if not then initialize */ - initialize = stat( config_filename, &sb ) == 0 ? 0 : 1; - - /* Not forced to initialize but does ramFileName exist? */ - if ( ramFileName[ 0 ] == '/' ) - strcpy( config_filename, "" ); - else - strcpy( config_filename, config_dir ); - strcat( config_filename, ramFileName ); - /* if not then initialize */ - initialize = stat( config_filename, &sb ) == 0 ? 0 : 1; - } - } else { - if ( mkdir( config_dir, 0755 ) == 0 ) - fprintf( stderr, "Created %s, please copy a rom in it.\n", - config_dir ); - - exit( 1 ); + fprintf( stderr, "normalized_config_path = %s\n", + normalized_config_path ); + fprintf( stderr, "normalized_rom_path = %s\n", normalized_rom_path ); + fprintf( stderr, "normalized_ram_path = %s\n", normalized_ram_path ); + fprintf( stderr, "normalized_state_path = %s\n", + normalized_state_path ); + fprintf( stderr, "normalized_port1_path = %s\n", + normalized_port1_path ); + fprintf( stderr, "normalized_port2_path = %s\n", + normalized_port2_path ); } return ( optind ); diff --git a/src/runtime_options.h b/src/runtime_options.h index 3eb6e63..fd31931 100644 --- a/src/runtime_options.h +++ b/src/runtime_options.h @@ -17,8 +17,8 @@ extern int resetOnStartup; extern int frontend_type; extern char* serialLine; -extern char* homeDirectory; +extern char* configDir; extern char* romFileName; extern char* ramFileName; extern char* stateFileName; @@ -47,10 +47,18 @@ extern char* mediumFont; extern char* largeFont; extern char* connFont; +#define MAX_LENGTH_FILENAME 2048 +extern char normalized_config_path[ MAX_LENGTH_FILENAME ]; +extern char normalized_rom_path[ MAX_LENGTH_FILENAME ]; +extern char normalized_ram_path[ MAX_LENGTH_FILENAME ]; +extern char normalized_state_path[ MAX_LENGTH_FILENAME ]; +extern char normalized_port1_path[ MAX_LENGTH_FILENAME ]; +extern char normalized_port2_path[ MAX_LENGTH_FILENAME ]; + /*************/ /* functions */ /*************/ -extern void get_home_directory( char* path ); +extern void get_absolute_config_dir( char* source, char* path ); extern int parse_args( int argc, char* argv[] ); #endif /* !_OPTIONS_H */ diff --git a/src/ui_sdl.c b/src/ui_sdl.c index 77016ca..cab7f2d 100644 --- a/src/ui_sdl.c +++ b/src/ui_sdl.c @@ -2415,7 +2415,7 @@ static void button_release_all( void ) { } static void SDLDrawSerialDevices() { - char text[ 1024 ]; + char text[ 1024 ] = ""; if ( verbose ) { fprintf( stderr, "wire_name: %s\n", wire_name );