--- /dev/null
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <syslinux/config.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+/**
+ * cli_clear_screen - clear (erase) the entire screen
+ **/
+static void cli_clear_screen(int argc __unused, char** argv __unused,
+ struct s_hardware *hardware __unused)
+{
+ clear_screen();
+}
+
+/**
+ * cli_set_mode - set the mode of the cli, in the cli
+ *
+ * The mode number must be supplied in argv, position 0.
+ **/
+static void cli_set_mode(int argc, char **argv,
+ struct s_hardware *hardware)
+{
+ cli_mode_t new_mode;
+
+ if (argc <= 0) {
+ printf("Which mode?\n");
+ return;
+ }
+
+ /*
+ * Note! argv[0] is a string representing the mode, we need the
+ * equivalent cli_mode_t to pass it to set_mode.
+ */
+ new_mode = mode_s_to_mode_t(argv[0]);
+ set_mode(new_mode, hardware);
+}
+
+/**
+ * do_exit - shared helper to exit a mode
+ **/
+static void do_exit(int argc __unused, char** argv __unused,
+ struct s_hardware *hardware)
+{
+ int new_mode = HDT_MODE;
+
+ switch (hdt_cli.mode) {
+ case HDT_MODE:
+ new_mode = EXIT_MODE;
+ break;
+ default:
+ new_mode = HDT_MODE;
+ break;
+ }
+
+ dprintf("CLI DEBUG: Switching from mode %d to mode %d\n", hdt_cli.mode,
+ new_mode);
+ set_mode(new_mode, hardware);
+}
+
+/**
+ * show_cli_help - shared helper to show available commands
+ **/
+static void show_cli_help(int argc __unused, char** argv __unused,
+ struct s_hardware *hardware __unused)
+{
+ int j;
+ struct cli_mode_descr *current_mode;
+ struct cli_callback_descr* associated_module = NULL;
+
+ find_cli_mode_descr(hdt_cli.mode, ¤t_mode);
+
+ printf("Available commands are:\n");
+
+ /* List first default modules of the mode */
+ if (current_mode->default_modules != NULL ) {
+ for (j = 0; j < current_mode->default_modules->nb_modules; j++) {
+ printf("%s ",
+ current_mode->default_modules->modules[j].name);
+ }
+ }
+
+ /* List secondly the show modules of the mode */
+ if (current_mode->show_modules != NULL ) {
+ more_printf("show commands:\n");
+ for (j = 0; j < current_mode->show_modules->nb_modules; j++) {
+ printf(" %s\n",
+ current_mode->show_modules->modules[j].name);
+ }
+ }
+
+ /* List finally the default modules of the hdt mode */
+ if (current_mode->mode != hdt_mode.mode &&
+ hdt_mode.default_modules != NULL ) {
+ for (j = 0; j < hdt_mode.default_modules->nb_modules; j++) {
+ /*
+ * Any default command that is present in hdt mode but
+ * not in the current mode is available. A default
+ * command can be redefined in the current mode though.
+ * This next call test this use case: if it is
+ * overwritten, do not print it again.
+ */
+ find_cli_callback_descr(hdt_mode.default_modules->modules[j].name,
+ current_mode->default_modules,
+ &associated_module);
+ if (associated_module == NULL)
+ printf("%s ",
+ hdt_mode.default_modules->modules[j].name);
+ }
+ }
+ printf("\n");
+}
+
+/* Default hdt mode */
+struct cli_callback_descr list_hdt_default_modules[] = {
+ {
+ .name = CLI_CLEAR,
+ .exec = cli_clear_screen,
+ },
+ {
+ .name = CLI_EXIT,
+ .exec = do_exit,
+ },
+ {
+ .name = CLI_HELP,
+ .exec = show_cli_help,
+ },
+};
+
+struct cli_callback_descr list_hdt_set_modules[] = {
+ {
+ .name = CLI_MODE,
+ .exec = cli_set_mode,
+ },
+};
+
+struct cli_module_descr hdt_default_modules = {
+ .modules = list_hdt_default_modules,
+ .nb_modules = 3,
+};
+
+struct cli_module_descr hdt_set_modules = {
+ .modules = list_hdt_set_modules,
+ .nb_modules = 1,
+};
+
+struct cli_mode_descr hdt_mode = {
+ .mode = HDT_MODE,
+ .name = CLI_HDT,
+ .default_modules = &hdt_default_modules,
+ .show_modules = NULL,
+ .set_modules = &hdt_set_modules,
+};
#include "hdt-cli.h"
#include "hdt-common.h"
-#define DEBUG 0
-#if DEBUG
-# define dprintf printf
-#else
-# define dprintf(f, ...) ((void)0)
-#endif
-
-
-#define MAX_MODES 2
-struct commands_mode *list_modes[] = {
+struct cli_mode_descr *list_modes[] = {
&hdt_mode,
&dmi_mode,
};
-struct s_cli hdt_cli;
-static void set_mode(cli_mode_t mode,
- struct s_hardware *hardware)
+static void handle_hdt_commands(char *cli_line, struct s_hardware *hardware)
+{
+ /* hdt cli mode specific commands */
+ if (!strncmp(cli_line, CLI_SHOW, sizeof(CLI_SHOW) - 1)) {
+ main_show(strstr(cli_line, "show") + sizeof(CLI_SHOW),
+ hardware);
+ return;
+ }
+}
+
+/**
+ * set_mode - set the current mode of the cli
+ * @mode: mode to set
+ *
+ * Unlike cli_set_mode, this function is not used by the cli directly.
+ **/
+void set_mode(cli_mode_t mode, struct s_hardware* hardware)
{
+ int i;
+
switch (mode) {
case EXIT_MODE:
hdt_cli.mode = mode;
break;
-
case HDT_MODE:
hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_HDT);
+ snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
+ CLI_HDT);
break;
-
case PXE_MODE:
if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
more_printf("You are not currently using PXELINUX\n");
break;
}
hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_PXE);
+ snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
+ CLI_PXE);
break;
-
case KERNEL_MODE:
detect_pci(hardware);
hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_KERNEL);
+ snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
+ CLI_KERNEL);
break;
-
case SYSLINUX_MODE:
hdt_cli.mode = mode;
snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
CLI_SYSLINUX);
break;
-
case VESA_MODE:
hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_VESA);
+ snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
+ CLI_VESA);
break;
-
case PCI_MODE:
hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_PCI);
+ snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
+ CLI_PCI);
if (!hardware->pci_detection)
cli_detect_pci(hardware);
break;
-
case CPU_MODE:
hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_CPU);
+ snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
+ CLI_CPU);
if (!hardware->dmi_detection)
detect_dmi(hardware);
if (!hardware->cpu_detection)
cpu_detect(hardware);
break;
-
case DMI_MODE:
detect_dmi(hardware);
if (!hardware->is_dmi_valid) {
break;
}
hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_DMI);
+ snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
+ CLI_DMI);
break;
+ default:
+ /* Invalid mode */
+ printf("Unknown mode, please choose among:\n");
+ for (i = 0; i < MAX_MODES; i++)
+ printf("\t%s\n", list_modes[i]->name);
}
}
-static void handle_hdt_commands(char *cli_line, struct s_hardware *hardware)
+/**
+ * mode_s_to_mode_t - given a mode string, return the cli_mode_t representation
+ **/
+cli_mode_t mode_s_to_mode_t(char *name)
{
- /* hdt cli mode specific commands */
- if (!strncmp(cli_line, CLI_SHOW, sizeof(CLI_SHOW) - 1)) {
- main_show(strstr(cli_line, "show") + sizeof(CLI_SHOW),
- hardware);
- return;
- }
+ int i = 0;
+
+ for (i = 0; i < MAX_MODES; i++)
+ if (!strncmp(name, list_modes[i]->name,
+ sizeof(list_modes[i]->name)))
+ break;
+
+ if (i == MAX_MODES)
+ return INVALID_MODE;
+ else
+ return list_modes[i]->mode;
}
/**
- * find_commands_mode - find the commands_mode struct associated to a mode
+ * find_cli_mode_descr - find the cli_mode_descr struct associated to a mode
* @mode: mode to look for
+ * @mode_found: store the mode if found, NULL otherwise
*
- * Given a mode name, return a pointer to the associated commands_mode structure.
+ * Given a mode name, return a pointer to the associated cli_mode_descr
+ * structure.
* Note: the current mode name is stored in hdt_cli.mode.
**/
-static struct commands_mode* find_commands_mode(cli_mode_t mode)
+void find_cli_mode_descr(cli_mode_t mode, struct cli_mode_descr **mode_found)
{
int modes_iter = 0;
while (modes_iter < MAX_MODES &&
- list_modes[modes_iter]->mode != hdt_cli.mode)
+ list_modes[modes_iter]->mode != mode)
modes_iter++;
/* Shouldn't get here... */
if (modes_iter == MAX_MODES)
- return NULL;
+ *mode_found = NULL;
else
- return list_modes[modes_iter];
-
+ *mode_found = list_modes[modes_iter];
}
/**
* <main command> [<module on which to operate> [<args>]]
**/
static void parse_command_line(char *line, char **command, char **module,
- char **argv)
+ int *argc, char **argv)
{
- int argc, argc_iter, args_pos, token_found, len;
+ int argc_iter, args_pos, token_found, len;
char *pch = NULL, *pch_next = NULL;
*command = NULL;
*module = NULL;
+ *argc = 0;
pch = line;
while (pch != NULL) {
/* Main command to execute */
*command = malloc((len + 1) * sizeof(char));
strncpy(*command, pch, len);
- (*command)[len] = NULL;
+ (*command)[len] = '\0';
dprintf("CLI DEBUG: command = %s\n", *command);
args_pos += len + 1;
} else if (token_found == 1) {
/* Module */
*module = malloc((len + 1) * sizeof(char));
strncpy(*module, pch, len);
- (*module)[len] = NULL;
+ (*module)[len] = '\0';
dprintf("CLI DEBUG: module = %s\n", *module);
args_pos += len + 1;
} else
- argc++;
+ (*argc)++;
if (pch_next != NULL)
pch_next++;
token_found++;
pch = pch_next;
}
- dprintf("CLI DEBUG: argc = %d\n", argc);
+ dprintf("CLI DEBUG: argc = %d\n", *argc);
/* Skip arguments handling if none is supplied */
- if (!argc)
+ if (!*argc)
return;
/* Transform the arguments string into an array */
- argv = malloc(argc * sizeof(char *));
+ *argv = malloc(*argc * sizeof(char *));
pch = strtok(line + args_pos, CLI_SPACE);
while (pch != NULL) {
dprintf("CLI DEBUG: argv[%d] = %s\n", argc_iter, pch);
}
/**
- * find_module_callback - find a callback in a list of modules
+ * find_cli_callback_descr - find a callback in a list of modules
* @module_name: Name of the module to find
* @modules_list: Lits of modules among which to find @module_name
* @module_found: Pointer to the matched module, NULL if not found
* Given a module name and a list of possible modules, find the corresponding
* module structure that matches the module name and store it in @module_found.
**/
-static void find_module_callback(char* module_name,
- struct commands_module_descr* modules_list,
- struct commands_module** module_found)
+void find_cli_callback_descr(const char* module_name,
+ struct cli_module_descr* modules_list,
+ struct cli_callback_descr** module_found)
{
int modules_iter = 0;
int module_len = strlen(module_name);
return;
}
-/**
- * show_cli_help - shared helper to show available commands
- **/
-static void show_cli_help(int argc, char** argv, struct s_hardware *hardware)
-{
- int j;
- struct commands_mode *current_mode;
- struct commands_module* associated_module = NULL;
-
- current_mode = find_commands_mode(hdt_cli.mode);
-
- more_printf("Available commands are:\n");
-
- /* List first default modules of the mode */
- if (current_mode->default_modules != NULL ) {
- for (j = 0; j < current_mode->default_modules->nb_modules; j++) {
- more_printf("%s ",
- current_mode->default_modules->modules[j].name);
- }
- }
-
- /* List secondly the show modules of the mode */
- if (current_mode->show_modules != NULL ) {
- more_printf("show commands:\n");
- for (j = 0; j < current_mode->show_modules->nb_modules; j++) {
- more_printf(" %s\n",
- current_mode->show_modules->modules[j].name);
- }
- }
-
- /* List finally the default modules of the hdt mode */
- if (current_mode->mode != hdt_mode.mode && hdt_mode.default_modules != NULL ) {
- for (j = 0; j < hdt_mode.default_modules->nb_modules; j++) {
- /*
- * Any default command that is present in hdt mode but
- * not in the current mode is available. A default command
- * can be redefined in the current mode though. This next
- * call test this use case: if it is overwritten, do not
- * print it again.
- */
- find_module_callback(hdt_mode.default_modules->modules[j].name,
- current_mode->default_modules,
- &associated_module);
- if (associated_module == NULL)
- more_printf("%s ",
- hdt_mode.default_modules->modules[j].name);
- }
- more_printf("\n");
- }
-}
-
-
static void exec_command(char *line,
struct s_hardware *hardware)
{
int argc = 0;
char *command = NULL, *module = NULL;
char **argv = NULL;
- struct commands_module* current_module = NULL;
- struct commands_mode *current_mode;
+ struct cli_callback_descr* current_module = NULL;
+ struct cli_mode_descr *current_mode;
/* We use sizeof BLAH - 1 to remove the last \0 */
// command[strlen(command) - 1] = '\0';
- /* XXX Extract this with a new grammar, e.g. set mode dmi */
-
- if (!strncmp(line, CLI_PCI, sizeof(CLI_PCI) - 1)) {
- set_mode(PCI_MODE, hardware);
- return;
- }
-
- if (!strncmp(line, CLI_CPU, sizeof(CLI_CPU) - 1)) {
- set_mode(CPU_MODE, hardware);
- return;
- }
-
- if (!strncmp(line, CLI_DMI, sizeof(CLI_DMI) - 1)) {
- set_mode(DMI_MODE, hardware);
- return;
- }
-
- if (!strncmp(line, CLI_PXE, sizeof(CLI_PXE) - 1)) {
- set_mode(PXE_MODE, hardware);
- return;
- }
-
- if (!strncmp(line, CLI_KERNEL, sizeof(CLI_KERNEL) - 1)) {
- set_mode(KERNEL_MODE, hardware);
- return;
- }
-
- if (!strncmp(line, CLI_SYSLINUX, sizeof(CLI_SYSLINUX) - 1)) {
- set_mode(SYSLINUX_MODE, hardware);
- return;
- }
-
- if (!strncmp(line, CLI_VESA, sizeof(CLI_VESA) - 1)) {
- set_mode(VESA_MODE, hardware);
- return;
- }
-
/*
* All commands before that line are common for all cli modes.
* The following will be specific for every mode.
*/
/* Find the mode selected */
- current_mode = find_commands_mode(hdt_cli.mode);
+ find_cli_mode_descr(hdt_cli.mode, ¤t_mode);
if (current_mode == NULL) {
/* Shouldn't get here... */
printf("!!! BUG: Mode '%s' unknown.\n", hdt_cli.mode);
}
/* This will allocate memory that will need to be freed */
- parse_command_line(line, &command, &module, argv);
+ parse_command_line(line, &command, &module, &argc, argv);
if (module == NULL) {
/*
* If not, it may be a generic function (exit, help, ...). These
* are stored in the list of default commands of the hdt mode.
*/
- find_module_callback(command, current_mode->default_modules,
- ¤t_module);
+ find_cli_callback_descr(command, current_mode->default_modules,
+ ¤t_module);
if (current_module != NULL)
current_module->exec(argc, argv, hardware);
else {
- find_module_callback(command, hdt_mode.default_modules,
+ find_cli_callback_descr(command, hdt_mode.default_modules,
¤t_module);
if (current_module != NULL) {
current_module->exec(argc, argv, hardware);
}
}
-
/*
- * Find the type of command.
+ * A module has been specified! We now need to find the type of command.
*
* The syntax of the cli is the following:
* <type of command> <module on which to operate> <args>
* dmi> show bank 1
* dmi> show memory 0 1
* pci> show device 12
+ * hdt> set mode dmi
*/
if (!strncmp(line, CLI_SHOW, sizeof(CLI_SHOW) - 1)) {
- find_module_callback(module, current_mode->show_modules, ¤t_module);
+ find_cli_callback_descr(module, current_mode->show_modules,
+ ¤t_module);
/* Execute the callback */
if (current_module != NULL)
- current_module->exec(argc, argv, hardware);
- /* XXX Add a default help option for empty commands */
+ return current_module->exec(argc, argv, hardware);
+ } else if (!strncmp(line, CLI_SET, sizeof(CLI_SET) - 1)) {
+ find_cli_callback_descr(module, current_mode->set_modules,
+ ¤t_module);
+ /* Execute the callback */
+ if (current_module != NULL)
+ return current_module->exec(argc, argv, hardware);
}
+ dprintf("CLI DEBUG: callback not found!\n", argc);
+
/* Handle here other keywords such as 'set', ... */
/* Let's not forget to clean ourselves */
}
}
-/**
- * do_exit - shared helper to exit a mode
- **/
-static void do_exit(int argc, char** argv, struct s_hardware *hardware)
-{
- int new_mode = HDT_MODE;
-
- switch (hdt_cli.mode) {
- case HDT_MODE:
- new_mode = EXIT_MODE;
- break;
- case KERNEL_MODE:
- case PXE_MODE:
- case SYSLINUX_MODE:
- case PCI_MODE:
- case DMI_MODE:
- case VESA_MODE:
- case CPU_MODE:
- new_mode = HDT_MODE;
- break;
- case EXIT_MODE:
- new_mode = EXIT_MODE; /* should not happen */
- break;
- }
-
- dprintf("CLI DEBUG: Switching from mode %d to mode %d\n", hdt_cli.mode,
- new_mode);
- set_mode(new_mode, hardware);
-}
-
static void main_show_summary(struct s_hardware *hardware)
{
detect_pci(hardware); /* pxe is detected in the pci */
}
show_main_help(hardware);
}
-
-/* Default hdt mode */
-struct commands_module list_hdt_default_modules[] = {
- {
- .name = CLI_CLEAR,
- .exec = clear_screen,
- },
- {
- .name = CLI_EXIT,
- .exec = do_exit,
- },
- {
- .name = CLI_HELP,
- .exec = show_cli_help,
- },
-};
-
-struct commands_module_descr hdt_default_modules = {
- .modules = list_hdt_default_modules,
- .nb_modules = 3,
-};
-
-struct commands_mode hdt_mode = {
- .mode = HDT_MODE,
- .default_modules = &hdt_default_modules,
- .show_modules = NULL,
-};