/* * Copyright (C) 2010 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include FILE_LICENCE ( GPL2_OR_LATER ); /** @file * * Non-volatile option commands * */ /** "show" options */ struct show_options {}; /** "show" option list */ static struct option_descriptor show_opts[] = {}; /** "show" command descriptor */ static struct command_descriptor show_cmd = COMMAND_DESC ( struct show_options, show_opts, 1, 1, "" ); /** * "show" command * * @v argc Argument count * @v argv Argument list * @ret rc Return status code */ static int show_exec ( int argc, char **argv ) { struct show_options opts; const char *name; char name_buf[32]; char value_buf[256]; int rc; /* Parse options */ if ( ( rc = parse_options ( argc, argv, &show_cmd, &opts ) ) != 0 ) return rc; /* Parse setting name */ name = argv[optind]; /* Fetch setting */ if ( ( rc = fetchf_named_setting ( name, name_buf, sizeof ( name_buf ), value_buf, sizeof ( value_buf ) ) ) < 0 ) { printf ( "Could not find \"%s\": %s\n", name, strerror ( rc ) ); return rc; } /* Print setting value */ printf ( "%s = %s\n", name_buf, value_buf ); return 0; } /** "set", "clear", and "read" options */ struct set_core_options {}; /** "set", "clear", and "read" option list */ static struct option_descriptor set_core_opts[] = {}; /** "set" command descriptor */ static struct command_descriptor set_cmd = COMMAND_DESC ( struct set_core_options, set_core_opts, 1, MAX_ARGUMENTS, " " ); /** "clear" and "read" command descriptor */ static struct command_descriptor clear_read_cmd = COMMAND_DESC ( struct set_core_options, set_core_opts, 1, 1, "" ); /** * "set", "clear", and "read" command * * @v argc Argument count * @v argv Argument list * @v cmd Command descriptor * @v get_value Method to obtain setting value * @ret rc Return status code */ static int set_core_exec ( int argc, char **argv, struct command_descriptor *cmd, int ( * get_value ) ( const char *name, char **args, char **value ) ) { struct set_core_options opts; const char *name; char *value; int rc; /* Parse options */ if ( ( rc = parse_options ( argc, argv, cmd, &opts ) ) != 0 ) goto err_parse_options; /* Parse setting name */ name = argv[optind]; /* Parse setting value */ if ( ( rc = get_value ( name, &argv[ optind + 1 ], &value ) ) != 0 ) goto err_get_value; /* Determine total length of command line */ if ( ( rc = storef_named_setting ( name, &setting_type_string, value ) ) != 0 ) { printf ( "Could not %s \"%s\": %s\n", argv[0], name, strerror ( rc ) ); goto err_store; } free ( value ); return 0; err_store: free ( value ); err_get_value: err_parse_options: return rc; } /** * Get setting value for "set" command * * @v name Setting name * @v args Remaining arguments * @ret value Setting value * @ret rc Return status code */ static int set_value ( const char *name __unused, char **args, char **value ) { *value = concat_args ( args ); if ( ! *value ) return -ENOMEM; return 0; } /** * "set" command * * @v argc Argument count * @v argv Argument list * @ret rc Return status code */ static int set_exec ( int argc, char **argv ) { return set_core_exec ( argc, argv, &set_cmd, set_value ); } /** * Get setting value for "clear" command * * @v name Setting name * @v args Remaining arguments * @ret value Setting value * @ret rc Return status code */ static int clear_value ( const char *name __unused, char **args __unused, char **value ) { *value = NULL; return 0; } /** * "clear" command * * @v argc Argument count * @v argv Argument list * @ret rc Return status code */ static int clear_exec ( int argc, char **argv ) { return set_core_exec ( argc, argv, &clear_read_cmd, clear_value ); } /** * Get setting value for "read" command * * @v name Setting name * @v args Remaining arguments * @ret value Setting value * @ret rc Return status code */ static int read_value ( const char *name, char **args __unused, char **value ) { char *existing; int rc; /* Read existing value */ if ( ( rc = fetchf_named_setting_copy ( name, &existing ) ) < 0 ) goto err_existing; /* Read new value */ if ( ( rc = readline_history ( NULL, existing, NULL, value ) ) != 0 ) goto err_new; /* Success */ rc = 0; err_new: free ( existing ); err_existing: return rc; } /** * "read" command * * @v argc Argument count * @v argv Argument list * @ret rc Return status code */ static int read_exec ( int argc, char **argv ) { return set_core_exec ( argc, argv, &clear_read_cmd, read_value ); } /** Non-volatile option commands */ struct command nvo_commands[] __command = { { .name = "show", .exec = show_exec, }, { .name = "set", .exec = set_exec, }, { .name = "clear", .exec = clear_exec, }, { .name = "read", .exec = read_exec, }, };