#ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "mcpu-tool-options.h" #define MCPU_LD_SYSTEM_CONFIG_FILE "/etc/mcpu/mcpu-ld.conf" static const char * program_basename( const char *name ) { const char *p; if( name == NULL || *name == 0 ) return( "mcpu" ); p = name + strlen( name ); while( p != name && p[-1] != '/' ) --p; return( p ); } /* End of program_basename() */ static int read_optional_config( mcpu_tool_options *options, const char *filename, int *was_read ) { struct stat st; if( was_read != NULL ) *was_read = 0; if( stat(filename, &st) != 0 ) { if( errno == ENOENT ) return( 0 ); fprintf( stderr, "%s: cannot stat configuration '%s': %s\n", options->progname, filename, strerror(errno) ); return( -1 ); } if( mcpu_config_read(&options->config, filename, 1) != 0 ) { fprintf( stderr, "%s: cannot read configuration '%s': %s\n", options->progname, filename, strerror(errno) ); return( -1 ); } if( was_read != NULL ) *was_read = 1; return( 0 ); } /* End of read_optional_config() */ void mcpu_tool_options_init( mcpu_tool_options *options, const char *progname ) { if( options == NULL ) return; memset( options, 0, sizeof(*options) ); options->progname = program_basename( progname ); mcpu_runtime_paths_init( &options->runtime ); mcpu_config_init( &options->config ); mcpu_library_search_init( &options->library_search ); } /* End of mcpu_tool_options_init() */ void mcpu_tool_options_free( mcpu_tool_options *options ) { if( options == NULL ) return; free( options->user_config_file ); options->user_config_file = NULL; mcpu_runtime_paths_free( &options->runtime ); mcpu_config_free( &options->config ); mcpu_library_search_free( &options->library_search ); } /* End of mcpu_tool_options_free() */ int mcpu_tool_parse_common_option( mcpu_tool_options *options, int argc, char **argv, int *index ) { const char *arg; if( options == NULL || argv == NULL || index == NULL || *index < 0 || *index >= argc ) { errno = EINVAL; return( -1 ); } arg = argv[*index]; if( mcpu_version_parse_option(arg, &options->version_action) ) return( 1 ); if( strcmp(arg, "--no-config") == 0 ) { options->no_config = 1; return( 1 ); } if( strcmp(arg, "--dump-config") == 0 ) { options->dump_config = 1; return( 1 ); } if( strcmp(arg, "--print-search-dirs") == 0 ) { options->print_search_dirs = 1; return( 1 ); } if( strncmp(arg, "--sys-root=", 11) == 0 ) { if( arg[11] == 0 ) { fprintf( stderr, "%s: empty path in '--sys-root='\n", options->progname ); return( -1 ); } options->sys_root = arg + 11; options->no_config = 1; return( 1 ); } if( strcmp(arg, "--sys-root") == 0 ) { if( *index + 1 >= argc || argv[*index + 1][0] == 0 ) { fprintf( stderr, "%s: argument missing after '--sys-root'\n", options->progname ); return( -1 ); } ++*index; options->sys_root = argv[*index]; options->no_config = 1; return( 1 ); } return( 0 ); } /* End of mcpu_tool_parse_common_option() */ int mcpu_tool_add_library_directory( mcpu_tool_options *options, const char *directory ) { if( options == NULL || directory == NULL || *directory == 0 ) { errno = EINVAL; return( -1 ); } return( mcpu_library_search_add_directory(&options->library_search, directory) ); } /* End of mcpu_tool_add_library_directory() */ int mcpu_tool_add_library_path( mcpu_tool_options *options, const char *path ) { if( options == NULL || path == NULL || *path == 0 ) { errno = EINVAL; return( -1 ); } return( mcpu_library_search_add_list(&options->library_search, path) ); } /* End of mcpu_tool_add_library_path() */ int mcpu_tool_resolve_library( const mcpu_tool_options *options, const char *name, char **resolved ) { if( options == NULL ) { errno = EINVAL; return( -1 ); } return( mcpu_library_search_resolve(&options->library_search, options->runtime.system_library_path, name, resolved) ); } /* End of mcpu_tool_resolve_library() */ int mcpu_tool_resolve_library_alternatives( const mcpu_tool_options *options, const char *const *names, size_t name_count, char **resolved, size_t *selected_index ) { if( options == NULL ) { errno = EINVAL; return( -1 ); } return( mcpu_library_search_resolve_alternatives( &options->library_search, options->runtime.system_library_path, names, name_count, resolved, selected_index) ); } /* End of mcpu_tool_resolve_library_alternatives() */ int mcpu_tool_options_prepare( mcpu_tool_options *options, const char *argv0 ) { const char *home; const char *value; if( options == NULL ) { errno = EINVAL; return( -1 ); } options->runtime_config_read = 0; options->system_config_read = 0; options->user_config_read = 0; if( options->sys_root != NULL ) { if( mcpu_runtime_paths_set_root(&options->runtime, options->sys_root) != 0 ) { fprintf( stderr, "%s: cannot use MCPU system root '%s': %s\n", options->progname, options->sys_root, strerror(errno) ); return( -1 ); } } else if( mcpu_runtime_paths_discover(&options->runtime, argv0) != 0 ) { fprintf( stderr, "%s: cannot determine MCPU installation root: %s\n", options->progname, strerror(errno) ); return( -1 ); } if( mcpu_config_set(&options->config, "MCPU_LD_SYSTEM_LIBRARY_PATH", options->runtime.system_library_path) != 0 ) return( -1 ); free( options->user_config_file ); options->user_config_file = NULL; home = getenv( "HOME" ); if( home != NULL && *home != 0 ) { size_t n = strlen(home) + sizeof("/.mcpu/etc/mcpu-ld.conf"); options->user_config_file = (char *)malloc( n ); if( options->user_config_file == NULL ) return( -1 ); snprintf( options->user_config_file, n, "%s/.mcpu/etc/mcpu-ld.conf", home ); } if( !options->no_config ) { if( options->runtime.config_file == NULL || read_optional_config(options, options->runtime.config_file, &options->runtime_config_read) != 0 ) return( -1 ); if( read_optional_config(options, MCPU_LD_SYSTEM_CONFIG_FILE, &options->system_config_read) != 0 ) return( -1 ); if( options->user_config_file != NULL && read_optional_config(options, options->user_config_file, &options->user_config_read) != 0 ) return( -1 ); } value = mcpu_config_get( &options->config, "MCPU_LD_SYSTEM_LIBRARY_PATH" ); if( value == NULL || mcpu_runtime_paths_set_system_library(&options->runtime, value) != 0 ) return( -1 ); return( 0 ); } /* End of mcpu_tool_options_prepare() */ int mcpu_tool_has_information_action( const mcpu_tool_options *options ) { if( options == NULL ) return( 0 ); return( options->dump_config || options->print_search_dirs || options->version_action != MCPU_VERSION_NONE ); } /* End of mcpu_tool_has_information_action() */ static int print_config_file_state( FILE *stream, const char *path, int was_read ) { if( path == NULL ) return( 0 ); if( fprintf(stream, " config: %s [%s]\n", path, was_read ? "read" : "not found") < 0 ) return( -1 ); return( 0 ); } /* End of print_config_file_state() */ int mcpu_tool_dump_config( const mcpu_tool_options *options, FILE *stream ) { const char *library_path; if( options == NULL || stream == NULL ) { errno = EINVAL; return( -1 ); } library_path = options->runtime.system_library_path; if( library_path == NULL ) library_path = ""; if( fprintf(stream, "MCPU configuration:\n") < 0 || fprintf(stream, " runtime root: %s\n", options->runtime.installation_root ? options->runtime.installation_root : "") < 0 ) return( -1 ); if( options->sys_root != NULL ) { if( fprintf(stream, " configuration: disabled by --sys-root\n") < 0 ) return( -1 ); } else if( options->no_config ) { if( fprintf(stream, " configuration: disabled by --no-config\n") < 0 ) return( -1 ); } else { if( fprintf(stream, " configuration: enabled\n") < 0 || print_config_file_state(stream, options->runtime.config_file, options->runtime_config_read) != 0 || print_config_file_state(stream, MCPU_LD_SYSTEM_CONFIG_FILE, options->system_config_read) != 0 || print_config_file_state(stream, options->user_config_file, options->user_config_read) != 0 ) return( -1 ); } if( fprintf(stream, "MCPU_LD_SYSTEM_LIBRARY_PATH = %s;\n", library_path) < 0 ) return( -1 ); return( ferror(stream) ? -1 : 0 ); } /* End of mcpu_tool_dump_config() */ int mcpu_tool_print_search_dirs( const mcpu_tool_options *options, FILE *stream ) { const char *path; size_t i; if( options == NULL || stream == NULL ) { errno = EINVAL; return( -1 ); } path = options->runtime.system_library_path; if( fprintf(stream, "libraries:\n") < 0 ) return( -1 ); for( i = 0; i < options->library_search.count; ++i ) if( fprintf(stream, " %s\n", options->library_search.directory[i]) < 0 ) return( -1 ); if( path != NULL && *path != 0 && fprintf(stream, " %s\n", path) < 0 ) return( -1 ); return( ferror(stream) ? -1 : 0 ); } /* End of mcpu_tool_print_search_dirs() */