summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux/syslinux-4.03/com32/hdt/hdt-cli.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux/syslinux-4.03/com32/hdt/hdt-cli.c')
-rw-r--r--contrib/syslinux/syslinux-4.03/com32/hdt/hdt-cli.c1121
1 files changed, 0 insertions, 1121 deletions
diff --git a/contrib/syslinux/syslinux-4.03/com32/hdt/hdt-cli.c b/contrib/syslinux/syslinux-4.03/com32/hdt/hdt-cli.c
deleted file mode 100644
index 639bcdb..0000000
--- a/contrib/syslinux/syslinux-4.03/com32/hdt/hdt-cli.c
+++ /dev/null
@@ -1,1121 +0,0 @@
-/* ----------------------------------------------------------------------- *
- *
- * Copyright 2009 Erwan Velu - 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 <stdlib.h>
-#include <string.h>
-#include <syslinux/config.h>
-#include <getkey.h>
-#include "hdt-cli.h"
-#include "hdt-common.h"
-
-struct cli_mode_descr *list_modes[] = {
- &hdt_mode,
- &dmi_mode,
- &syslinux_mode,
- &pxe_mode,
- &kernel_mode,
- &cpu_mode,
- &pci_mode,
- &vesa_mode,
- &disk_mode,
- &vpd_mode,
- &memory_mode,
- NULL,
-};
-
-/*
- * .aliases = {"q", "quit"} won't work since it is an array of pointers, not an
- * array of variables. There is no easy way around it besides declaring the arrays of
- * strings first.
- */
-const char *exit_aliases[] = { "q", "quit" };
-const char *help_aliases[] = { "h", "?" };
-
-/* List of aliases */
-struct cli_alias hdt_aliases[] = {
- {
- .command = CLI_EXIT,
- .nb_aliases = 2,
- .aliases = exit_aliases,
- },
- {
- .command = CLI_HELP,
- .nb_aliases = 2,
- .aliases = help_aliases,
- },
-};
-
-struct cli_mode_descr *current_mode;
-int autocomplete_backlog;
-
-struct autocomplete_list {
- char autocomplete_token[MAX_LINE_SIZE];
- struct autocomplete_list *next;
-};
-struct autocomplete_list *autocomplete_head = NULL;
-struct autocomplete_list *autocomplete_tail = NULL;
-struct autocomplete_list *autocomplete_last_seen = NULL;
-
-static void autocomplete_add_token_to_list(const char *token)
-{
- struct autocomplete_list *new = malloc(sizeof(struct autocomplete_list));
-
- strlcpy(new->autocomplete_token, token, sizeof(new->autocomplete_token));
- new->next = NULL;
- autocomplete_backlog++;
-
- if (autocomplete_tail != NULL)
- autocomplete_tail->next = new;
- if (autocomplete_head == NULL)
- autocomplete_head = new;
- autocomplete_tail = new;
-}
-
-static void autocomplete_destroy_list(void)
-{
- struct autocomplete_list *tmp = NULL;
-
- while (autocomplete_head != NULL) {
- tmp = autocomplete_head->next;
- free(autocomplete_head);
- autocomplete_head = tmp;
- }
- autocomplete_backlog = 0;
- autocomplete_tail = NULL;
- autocomplete_last_seen = NULL;
-}
-
-/**
- * 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 = 0;
-
- 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);
- break;
- case PXE_MODE:
- if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
- printf("You are not currently using PXELINUX\n");
- break;
- }
- hdt_cli.mode = mode;
- 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);
- 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);
- break;
- case PCI_MODE:
- hdt_cli.mode = mode;
- 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);
- 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) {
- printf("No valid DMI table found, exiting.\n");
- break;
- }
- hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_DMI);
- break;
- case DISK_MODE:
- detect_disks(hardware);
- hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_DISK);
- break;
- case VPD_MODE:
- detect_vpd(hardware);
- if (!hardware->is_vpd_valid) {
- printf("No valid VPD table found, exiting.\n");
- break;
- }
- hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_VPD);
- break;
- case MEMORY_MODE:
- hdt_cli.mode = mode;
- snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_MEMORY);
- break;
- default:
- /* Invalid mode */
- printf("Unknown mode, please choose among:\n");
- while (list_modes[i]) {
- printf("\t%s\n", list_modes[i]->name);
- i++;
- }
- }
-
- find_cli_mode_descr(hdt_cli.mode, &current_mode);
- /* There is not cli_mode_descr struct for the exit mode */
- if (current_mode == NULL && hdt_cli.mode != EXIT_MODE) {
- /* Shouldn't get here... */
- printf("!!! BUG: Mode '%d' unknown.\n", hdt_cli.mode);
- }
-}
-
-/**
- * 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)
-{
- int i = 0;
-
- while (list_modes[i]) {
- if (!strncmp(name, list_modes[i]->name, sizeof(list_modes[i]->name)))
- break;
- i++;
- }
-
- if (!list_modes[i])
- return INVALID_MODE;
- else
- return list_modes[i]->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 cli_mode_descr
- * structure.
- * Note: the current mode name is stored in hdt_cli.mode.
- **/
-void find_cli_mode_descr(cli_mode_t mode, struct cli_mode_descr **mode_found)
-{
- int i = 0;
-
- while (list_modes[i] && list_modes[i]->mode != mode)
- i++;
-
- /* Shouldn't get here... */
- if (!list_modes[i])
- *mode_found = NULL;
- else
- *mode_found = list_modes[i];
-}
-
-/**
- * expand_aliases - resolve aliases mapping
- * @line: command line to parse
- * @command: first token in the line
- * @module: second token in the line
- * @argc: number of arguments
- * @argv: array of arguments
- *
- * We maintain a small list of static alises to enhance user experience.
- * Only commands can be aliased (first token). Otherwise it can become really hairy...
- **/
-static void expand_aliases(char *line __unused, char **command, char **module,
- int *argc, char **argv)
-{
- struct cli_mode_descr *mode;
- int i, j;
-
- find_cli_mode_descr(mode_s_to_mode_t(*command), &mode);
- if (mode != NULL && *module == NULL) {
- /*
- * The user specified a mode instead of `set mode...', e.g.
- * `dmi' instead of `set mode dmi'
- */
-
- /* *argv is NULL since *module is NULL */
- *argc = 1;
- *argv = malloc(*argc * sizeof(char *));
- argv[0] = malloc((sizeof(*command) + 1) * sizeof(char));
- strlcpy(argv[0], *command, sizeof(*command) + 1);
- dprintf("CLI DEBUG: ALIAS %s ", *command);
-
- strlcpy(*command, CLI_SET, sizeof(CLI_SET)); /* set */
-
- *module = malloc(sizeof(CLI_MODE) * sizeof(char));
- strlcpy(*module, CLI_MODE, sizeof(CLI_MODE)); /* mode */
-
- dprintf("--> %s %s %s\n", *command, *module, argv[0]);
- goto out;
- }
-
- /* Simple aliases mapping a single command to another one */
- for (i = 0; i < MAX_ALIASES; i++) {
- for (j = 0; j < hdt_aliases[i].nb_aliases; j++) {
- if (!strncmp(*command, hdt_aliases[i].aliases[j],
- sizeof(hdt_aliases[i].aliases[j]))) {
- dprintf("CLI DEBUG: ALIAS %s ", *command);
- strlcpy(*command, hdt_aliases[i].command,
- sizeof(hdt_aliases[i].command) + 1);
- dprintf("--> %s\n", *command);
- goto out; /* Don't allow chaining aliases */
- }
- }
- }
- return;
-
-out:
- dprintf("CLI DEBUG: New parameters:\n");
- dprintf("CLI DEBUG: command = %s\n", *command);
- dprintf("CLI DEBUG: module = %s\n", *module);
- dprintf("CLI DEBUG: argc = %d\n", *argc);
- for (i = 0; i < *argc; i++)
- dprintf("CLI DEBUG: argv[%d] = %s\n", i, argv[0]);
- return;
-}
-
-/**
- * parse_command_line - low level parser for the command line
- * @line: command line to parse
- * @command: first token in the line
- * @module: second token in the line
- * @argc: number of arguments
- * @argv: array of arguments
- *
- * The format of the command line is:
- * <main command> [<module on which to operate> [<args>]]
- * command is always malloc'ed (even for an empty line)
- **/
-static void parse_command_line(char *line, char **command, char **module,
- int *argc, char **argv)
-{
- int argc_iter = 0, args_pos = 0, token_found = 0, token_len = 0;
- int args_len = 0;
- char *pch = NULL, *pch_next = NULL, *tmp_pch_next = NULL;
-
- *command = NULL;
- *module = NULL;
- *argc = 0;
-
- pch = line;
- while (pch != NULL) {
- pch_next = strchr(pch + 1, ' ');
- tmp_pch_next = pch_next;
-
- /*
- * Skip whitespaces if the user entered
- * 'set mode foo' for 'set mode foo'
- * ^ ^
- * |___|___ pch
- * |___ pch_next <- wrong!
- *
- * We still keep the position into tmp_pch_next to compute
- * the lenght of the current token.
- */
- while (pch_next != NULL && !strncmp(pch_next, CLI_SPACE, 1))
- pch_next++;
-
- /* End of line guaranteed to be zeroed */
- if (pch_next == NULL) {
- token_len = (int)(strchr(pch + 1, '\0') - pch);
- args_len = token_len;
- } else {
- token_len = (int)(tmp_pch_next - pch);
- args_len = (int)(pch_next - pch);
- }
-
- if (token_found == 0) {
- /* Main command to execute */
- *command = malloc((token_len + 1) * sizeof(char));
- strlcpy(*command, pch, token_len);
- (*command)[token_len] = '\0';
- dprintf("CLI DEBUG: command = %s\n", *command);
- args_pos += args_len;
- } else if (token_found == 1) {
- /* Module */
- *module = malloc((token_len + 1) * sizeof(char));
- strlcpy(*module, pch, token_len);
- (*module)[token_len] = '\0';
- dprintf("CLI DEBUG: module = %s\n", *module);
- args_pos += args_len;
- } else
- (*argc)++;
-
- token_found++;
- pch = pch_next;
- }
- dprintf("CLI DEBUG: argc = %d\n", *argc);
-
- /* Skip arguments handling if none is supplied */
- if (!*argc)
- return;
-
- /* Transform the arguments string into an array */
- *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);
- argv[argc_iter] = malloc(sizeof(pch) * sizeof(char));
- strlcpy(argv[argc_iter], pch, sizeof(pch));
- argc_iter++;
- pch = strtok(NULL, CLI_SPACE);
- /*
- * strtok(NULL, CLI_SPACE) over a stream of spaces
- * will return an empty string
- */
- while (pch != NULL && !strncmp(pch, "", 1))
- pch = strtok(NULL, CLI_SPACE);
- }
-}
-
-/**
- * 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.
- **/
-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;
-
- if (modules_list == NULL)
- goto not_found;
-
- /* Find the callback to execute */
- while (modules_list->modules[modules_iter].name &&
- strcmp(module_name, modules_list->modules[modules_iter].name) != 0)
- modules_iter++;
-
- if (modules_list->modules[modules_iter].name) {
- *module_found = &(modules_list->modules[modules_iter]);
- dprintf("CLI DEBUG: module %s found\n", (*module_found)->name);
- return;
- }
-
-not_found:
- *module_found = NULL;
- return;
-}
-
-/**
- * autocomplete_command - print matching commands
- * @command: Beginning of the command
- *
- * Given a string @command, print all availables commands starting with
- * @command. Commands are found within the list of commands for the current
- * mode and the hdt mode (if the current mode is not hdt).
- **/
-static void autocomplete_command(char *command)
-{
- int j = 0;
- struct cli_callback_descr *associated_module = NULL;
-
- /* First take care of the two special commands: 'show' and 'set' */
- if (strncmp(CLI_SHOW, command, strlen(command)) == 0) {
- printf("%s\n", CLI_SHOW);
- autocomplete_add_token_to_list(CLI_SHOW);
- }
- if (strncmp(CLI_SET, command, strlen(command)) == 0) {
- printf("%s\n", CLI_SET);
- autocomplete_add_token_to_list(CLI_SET);
- }
-
- /*
- * Then, go through the modes for the special case
- * '<mode>' -> 'set mode <mode>'
- */
- while (list_modes[j]) {
- if (strncmp(list_modes[j]->name, command, strlen(command)) == 0) {
- printf("%s\n", list_modes[j]->name);
- autocomplete_add_token_to_list(list_modes[j]->name);
- }
- j++;
- }
-
- /*
- * Let's go now through the list of default_modules for the current mode
- * (single token commands for the current_mode)
- */
- j = 0;
- if (current_mode->default_modules && current_mode->default_modules->modules) {
- while (current_mode->default_modules->modules[j].name) {
- if (strncmp(current_mode->default_modules->modules[j].name,
- command, strlen(command)) == 0) {
- printf("%s\n", current_mode->default_modules->modules[j].name);
- autocomplete_add_token_to_list(current_mode->default_modules->
- modules[j].name);
- }
- j++;
- }
- }
-
- /*
- * Finally, if the current_mode is not hdt, list the available
- * default_modules of hdt (these are always available from any mode).
- */
- if (current_mode->mode == HDT_MODE)
- return;
-
- if (!hdt_mode.default_modules || !hdt_mode.default_modules->modules)
- return;
-
- j = 0;
- while (hdt_mode.default_modules &&
- hdt_mode.default_modules->modules[j].name) {
- /*
- * 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 tests 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 &&
- strncmp(command,
- hdt_mode.default_modules->modules[j].name,
- strlen(command)) == 0) {
- printf("%s\n", hdt_mode.default_modules->modules[j].name);
- autocomplete_add_token_to_list(hdt_mode.default_modules->modules[j].
- name);
- }
- j++;
- }
-}
-
-/**
- * autocomplete_module - print matching modules
- * @command: Command on the command line (not NULL)
- * @module: Beginning of the module
- *
- * Given a command @command and a string @module, print all availables modules
- * starting with @module for command @command. Commands are found within the
- * list of commands for the current mode and the hdt mode (if the current mode
- * is not hdt).
- **/
-static void autocomplete_module(char *command, char *module)
-{
- int j = 0;
- char autocomplete_full_line[MAX_LINE_SIZE];
-
- if (strncmp(CLI_SHOW, command, strlen(command)) == 0) {
- if (!current_mode->show_modules || !current_mode->show_modules->modules)
- return;
-
- while (current_mode->show_modules->modules[j].name) {
- if (strncmp(current_mode->show_modules->modules[j].name,
- module, strlen(module)) == 0) {
- printf("%s\n", current_mode->show_modules->modules[j].name);
- sprintf(autocomplete_full_line, "%s %s",
- CLI_SHOW, current_mode->show_modules->modules[j].name);
- autocomplete_add_token_to_list(autocomplete_full_line);
- }
- j++;
- }
- } else if (strncmp(CLI_SET, command, strlen(command)) == 0) {
- j = 0;
- if (!current_mode->set_modules || !current_mode->set_modules->modules)
- return;
-
- while (current_mode->set_modules->modules[j].name) {
- if (strncmp(current_mode->set_modules->modules[j].name,
- module, strlen(module)) == 0) {
- printf("%s\n", current_mode->set_modules->modules[j].name);
- sprintf(autocomplete_full_line, "%s %s",
- CLI_SET, current_mode->set_modules->modules[j].name);
- autocomplete_add_token_to_list(autocomplete_full_line);
- }
- j++;
- }
- }
-}
-
-/**
- * autocomplete - find possible matches for a command line
- * @line: command line to parse
- **/
-static void autocomplete(char *line)
-{
- int i;
- int argc = 0;
- char *command = NULL, *module = NULL;
- char **argv = NULL;
-
- parse_command_line(line, &command, &module, &argc, argv);
-
- /* If the user specified arguments, there is nothing we can complete */
- if (argc != 0)
- goto out;
-
- /* No argument, (the start of) a module has been specified */
- if (module != NULL) {
- autocomplete_module(command, module);
- free(module);
- goto out;
- }
-
- /* No argument, no module, (the start of) a command has been specified */
- if (command != NULL) {
- autocomplete_command(command);
- free(command);
- goto out;
- }
-
-out:
- /* Let's not forget to clean ourselves */
- for (i = 0; i < argc; i++)
- free(argv[i]);
- if (argc > 0)
- free(argv);
- return;
-}
-
-/**
- * exec_command - main logic to map the command line to callbacks
- **/
-static void exec_command(char *line, struct s_hardware *hardware)
-{
- int argc, i = 0;
- char *command = NULL, *module = NULL;
- char **argv = NULL;
- struct cli_callback_descr *current_module = NULL;
-
- /* This will allocate memory for command and module */
- parse_command_line(line, &command, &module, &argc, argv);
-
- /*
- * Expand shortcuts, if needed
- * This will allocate memory for argc/argv
- */
- expand_aliases(line, &command, &module, &argc, argv);
-
- if (module == NULL) {
- dprintf("CLI DEBUG: single command detected\n");
- /*
- * A single word was specified: look at the list of default
- * commands in the current mode to see if there is a match.
- * If not, it may be a generic function (exit, help, ...). These
- * are stored in the list of default commands of the hdt mode.
- */
- find_cli_callback_descr(command, current_mode->default_modules,
- &current_module);
- if (current_module != NULL)
- current_module->exec(argc, argv, hardware);
- else if (!strncmp(command, CLI_SHOW, sizeof(CLI_SHOW) - 1) &&
- current_mode->show_modules != NULL &&
- current_mode->show_modules->default_callback != NULL)
- current_mode->show_modules->default_callback(argc, argv, hardware);
- else if (!strncmp(command, CLI_SET, sizeof(CLI_SET) - 1) &&
- current_mode->set_modules != NULL &&
- current_mode->set_modules->default_callback != NULL)
- current_mode->set_modules->default_callback(argc, argv, hardware);
- else {
- find_cli_callback_descr(command, hdt_mode.default_modules,
- &current_module);
- if (current_module != NULL)
- current_module->exec(argc, argv, hardware);
- else
- printf("unknown command: '%s'\n", command);
- }
- } else {
- /*
- * 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>
- * e.g.
- * dmi> show system
- * dmi> show bank 1
- * dmi> show memory 0 1
- * pci> show device 12
- * hdt> set mode dmi
- */
- if (!strncmp(command, CLI_SHOW, sizeof(CLI_SHOW) - 1)) {
- dprintf("CLI DEBUG: %s command detected\n", CLI_SHOW);
- /* Look first for a 'show' callback in the current mode */
- find_cli_callback_descr(module, current_mode->show_modules,
- &current_module);
- /* Execute the callback, if found */
- if (current_module != NULL)
- current_module->exec(argc, argv, hardware);
- else {
- /* Look now for a 'show' callback in the hdt mode */
- find_cli_callback_descr(module, hdt_mode.show_modules,
- &current_module);
- /* Execute the callback, if found */
- if (current_module != NULL)
- current_module->exec(argc, argv, hardware);
- else
- printf("unknown module: '%s'\n", module);
- }
- } else if (!strncmp(command, CLI_SET, sizeof(CLI_SET) - 1)) {
- dprintf("CLI DEBUG: %s command detected\n", CLI_SET);
- /* Look now for a 'set' callback in the hdt mode */
- find_cli_callback_descr(module, current_mode->set_modules,
- &current_module);
- /* Execute the callback, if found */
- if (current_module != NULL)
- current_module->exec(argc, argv, hardware);
- else {
- /* Look now for a 'set' callback in the hdt mode */
- find_cli_callback_descr(module, hdt_mode.set_modules,
- &current_module);
- /* Execute the callback, if found */
- if (current_module != NULL)
- current_module->exec(argc, argv, hardware);
- else
- printf("unknown module: '%s'\n", module);
- }
- }
- }
-
- /* Let's not forget to clean ourselves */
- if (command != NULL)
- free(command);
- if (module != NULL)
- free(module);
- for (i = 0; i < argc; i++)
- free(argv[i]);
- if (argc > 0)
- free(argv);
-}
-
-static void reset_prompt(void)
-{
- /* No need to display the prompt if we exit */
- if (hdt_cli.mode != EXIT_MODE) {
- printf("%s", hdt_cli.prompt);
- /* Reset the line */
- hdt_cli.cursor_pos = 0;
- }
-}
-
-void start_auto_mode(struct s_hardware *hardware)
-{
- char *mypch;
- int nb_commands = 0;
- char *commands[MAX_NB_AUTO_COMMANDS];
-
- if (!quiet)
- more_printf("\nEntering Auto mode\n");
-
- /* Protecting the auto_label from the strtok modifications */
- char *temp = strdup(hardware->auto_label);
-
- /* Searching & saving all commands */
- mypch = strtok(temp, AUTO_SEPARATOR);
- while (mypch != NULL) {
- if ((strlen(remove_spaces(mypch)) > 0) &&
- (remove_spaces(mypch)[0] != AUTO_SEPARATOR[0])) {
- nb_commands++;
- if ((commands[nb_commands] = malloc(AUTO_COMMAND_SIZE)) != NULL) {
- sprintf(commands[nb_commands], "%s", remove_spaces(mypch));
- } else
- nb_commands--;
- }
- mypch = strtok(NULL, AUTO_SEPARATOR);
- }
-
- /* Executing found commands */
- for (int i = 1; i <= nb_commands; i++) {
- if (commands[i]) {
- if (!quiet)
- more_printf("%s%s\n", hdt_cli.prompt, commands[i]);
- exec_command(commands[i], hardware);
- free(commands[i]);
- }
- }
-
- if (!quiet)
- more_printf("\nExiting Auto mode\n");
-
- more_printf("\n");
-}
-
-void print_history(int argc, char **argv, struct s_hardware * hardware)
-{
- (void)argc;
- (void)argv;
- (void)hardware;
-
- reset_more_printf();
- for (int i = 1; i <= MAX_HISTORY_SIZE; i++) {
- if (i == hdt_cli.history_pos) {
- more_printf("*%d:'%s'\n", i, hdt_cli.history[i]);
- continue;
- }
- if (strlen(hdt_cli.history[i]) == 0)
- continue;
- more_printf(" %d:'%s'\n", i, hdt_cli.history[i]);
- }
-}
-
-/* Code that manages the cli mode */
-void start_cli_mode(struct s_hardware *hardware)
-{
- int current_key = 0;
- int future_history_pos = 1; /* position of the next position in the history */
- int current_future_history_pos = 1; /* Temp variable */
- bool display_history = true; /* Temp Variable */
- char temp_command[MAX_LINE_SIZE];
-
- hdt_cli.cursor_pos = 0;
- memset(hdt_cli.history, 0, sizeof(hdt_cli.history));
- hdt_cli.history_pos = 1;
- hdt_cli.max_history_pos = 1;
-
- /* Find the mode selected */
- set_mode(HDT_MODE, hardware);
- find_cli_mode_descr(hdt_cli.mode, &current_mode);
- if (current_mode == NULL) {
- /* Shouldn't get here... */
- printf("!!! BUG: Mode '%d' unknown.\n", hdt_cli.mode);
- return;
- }
-
- /* Start the auto mode if the command line is set */
- if (strlen(hardware->auto_label) > 0) {
- start_auto_mode(hardware);
- }
-
- printf("Entering CLI mode\n");
-
- reset_prompt();
-
- while (hdt_cli.mode != EXIT_MODE) {
-
- /* Display the cursor */
- display_cursor(true);
-
- /* Let's put the cursor blinking until we get an input */
- set_cursor_blink(true);
-
- /* We wait endlessly for a keyboard input */
- current_key = get_key(stdin, 0);
-
- /* We have to cancel the blinking mode to prevent
- * input text to blink */
- set_cursor_blink(false);
-
- /* Reset autocomplete buffer unless TAB is pressed */
- if (current_key != KEY_TAB)
- autocomplete_destroy_list();
-
- switch (current_key) {
- /* clear until then end of line */
- case KEY_CTRL('k'):
- /* Clear the end of the line */
- clear_end_of_line();
- memset(&INPUT[hdt_cli.cursor_pos], 0,
- strlen(INPUT) - hdt_cli.cursor_pos);
- break;
-
- case KEY_CTRL('c'):
- printf("\n");
- reset_prompt();
- break;
-
- case KEY_LEFT:
- if (hdt_cli.cursor_pos > 0) {
- move_cursor_left(1);
- hdt_cli.cursor_pos--;
- }
- break;
-
- case KEY_RIGHT:
- if (hdt_cli.cursor_pos < (int)strlen(INPUT)) {
- move_cursor_right(1);
- hdt_cli.cursor_pos++;
- }
- break;
-
- case KEY_CTRL('e'):
- case KEY_END:
- /* Calling with a 0 value will make the cursor move */
- /* So, let's move the cursor only if needed */
- if ((strlen(INPUT) - hdt_cli.cursor_pos) > 0) {
- /* Return to the begining of line */
- move_cursor_right(strlen(INPUT) - hdt_cli.cursor_pos);
- hdt_cli.cursor_pos = strlen(INPUT);
- }
- break;
-
- case KEY_CTRL('a'):
- case KEY_HOME:
- /* Calling with a 0 value will make the cursor move */
- /* So, let's move the cursor only if needed */
- if (hdt_cli.cursor_pos > 0) {
- /* Return to the begining of line */
- move_cursor_left(hdt_cli.cursor_pos);
- hdt_cli.cursor_pos = 0;
- }
- break;
-
- case KEY_UP:
-
- /* Saving future position */
- current_future_history_pos = future_history_pos;
-
- /* We have to compute the next position */
- if (future_history_pos == 1) {
- future_history_pos = MAX_HISTORY_SIZE;
- } else {
- future_history_pos--;
- }
-
- /* Does the next position is valid */
- if (strlen(hdt_cli.history[future_history_pos]) == 0) {
- /* Position is invalid, restoring position */
- future_history_pos = current_future_history_pos;
- break;
- }
-
- /* Let's make that future position the one we use */
- memset(INPUT, 0, sizeof(INPUT));
- strlcpy(INPUT, hdt_cli.history[future_history_pos], sizeof(INPUT));
-
- /* Clear the line */
- clear_line();
-
- /* Move to the begining of line */
- move_cursor_to_column(0);
-
- reset_prompt();
- printf("%s", INPUT);
- hdt_cli.cursor_pos = strlen(INPUT);
- break;
-
- case KEY_DOWN:
- display_history = true;
-
- /* Saving future position */
- current_future_history_pos = future_history_pos;
-
- if (future_history_pos == MAX_HISTORY_SIZE) {
- future_history_pos = 1;
- } else {
- future_history_pos++;
- }
-
- /* Does the next position is valid */
- if (strlen(hdt_cli.history[future_history_pos]) == 0)
- display_history = false;
-
- /* An exception is made to reach the last empty line */
- if (future_history_pos == hdt_cli.max_history_pos)
- display_history = true;
-
- if (display_history == false) {
- /* Position is invalid, restoring position */
- future_history_pos = current_future_history_pos;
- break;
- }
-
- /* Let's make that future position the one we use */
- memset(INPUT, 0, sizeof(INPUT));
- strlcpy(INPUT, hdt_cli.history[future_history_pos], sizeof(INPUT));
-
- /* Clear the line */
- clear_line();
-
- /* Move to the begining of line */
- move_cursor_to_column(0);
-
- reset_prompt();
- printf("%s", INPUT);
- hdt_cli.cursor_pos = strlen(INPUT);
- break;
-
- case KEY_TAB:
- if (autocomplete_backlog) {
- clear_line();
- /* Move to the begining of line */
- move_cursor_to_column(0);
- reset_prompt();
- printf("%s", autocomplete_last_seen->autocomplete_token);
- strlcpy(INPUT,
- autocomplete_last_seen->autocomplete_token,
- sizeof(INPUT));
- hdt_cli.cursor_pos = strlen(INPUT);
-
- /* Cycle through the list */
- autocomplete_last_seen = autocomplete_last_seen->next;
- if (autocomplete_last_seen == NULL)
- autocomplete_last_seen = autocomplete_head;
- } else {
- printf("\n");
- autocomplete(skip_spaces(INPUT));
- autocomplete_last_seen = autocomplete_head;
-
- printf("%s%s", hdt_cli.prompt, INPUT);
- }
- break;
-
- case KEY_ENTER:
- printf("\n");
- if (strlen(remove_spaces(INPUT)) < 1) {
- reset_prompt();
- break;
- }
- exec_command(remove_spaces(INPUT), hardware);
- hdt_cli.history_pos++;
-
- /* Did we reach the end of the history ?*/
- if (hdt_cli.history_pos > MAX_HISTORY_SIZE) {
- /* Let's return at the beginning */
- hdt_cli.history_pos = 1;
- }
-
- /* Does the next position is already used ?
- * If yes, we are cycling in history */
- if (strlen(INPUT) > 0) {
- /* Let's clean that entry */
- memset(&INPUT,0,sizeof(INPUT));
- }
-
- future_history_pos = hdt_cli.history_pos;
- if (hdt_cli.history_pos > hdt_cli.max_history_pos)
- hdt_cli.max_history_pos = hdt_cli.history_pos;
- reset_prompt();
- break;
-
- case KEY_CTRL('d'):
- case KEY_DELETE:
- /* No need to delete when input is empty */
- if (strlen(INPUT) == 0)
- break;
- /* Don't delete when cursor is at the end of the line */
- if (hdt_cli.cursor_pos >= strlen(INPUT))
- break;
-
- for (int c = hdt_cli.cursor_pos; c < (int)strlen(INPUT) - 1; c++)
- INPUT[c] = INPUT[c + 1];
- INPUT[strlen(INPUT) - 1] = '\0';
-
- /* Clear the end of the line */
- clear_end_of_line();
-
- /* Print the resulting buffer */
- printf("%s", INPUT + hdt_cli.cursor_pos);
-
- /* Replace the cursor at the proper place */
- if (strlen(INPUT + hdt_cli.cursor_pos) > 0)
- move_cursor_left(strlen(INPUT + hdt_cli.cursor_pos));
- break;
-
- case KEY_DEL:
- case KEY_BACKSPACE:
- /* Don't delete prompt */
- if (hdt_cli.cursor_pos == 0)
- break;
-
- for (int c = hdt_cli.cursor_pos - 1;
- c < (int)strlen(INPUT) - 1; c++)
- INPUT[c] = INPUT[c + 1];
- INPUT[strlen(INPUT) - 1] = '\0';
-
- /* Get one char back */
- move_cursor_left(1);
-
- /* Clear the end of the line */
- clear_end_of_line();
-
- /* Print the resulting buffer */
- printf("%s", INPUT + hdt_cli.cursor_pos - 1);
-
- /* Realing to a char before the place we were */
- hdt_cli.cursor_pos--;
- move_cursor_to_column(strlen(hdt_cli.prompt) + hdt_cli.cursor_pos +
- 1);
-
- break;
-
- case KEY_F1:
- printf("\n");
- exec_command(CLI_HELP, hardware);
- reset_prompt();
- break;
-
- default:
- if ((current_key < 0x20) || (current_key > 0x7e))
- break;
- /* Prevent overflow */
- if (hdt_cli.cursor_pos > MAX_LINE_SIZE - 2)
- break;
- /* If we aren't at the end of the input line, let's insert */
- if (hdt_cli.cursor_pos < (int)strlen(INPUT)) {
- char key[2];
- int trailing_chars = strlen(INPUT) - hdt_cli.cursor_pos;
- memset(temp_command, 0, sizeof(temp_command));
- strlcpy(temp_command, INPUT, hdt_cli.cursor_pos);
- sprintf(key, "%c", current_key);
- strncat(temp_command, key, 1);
- strncat(temp_command,
- INPUT + hdt_cli.cursor_pos, trailing_chars);
- memset(INPUT, 0, sizeof(INPUT));
- snprintf(INPUT, sizeof(INPUT), "%s", temp_command);
-
- /* Clear the end of the line */
- clear_end_of_line();
-
- /* Print the resulting buffer */
- printf("%s", INPUT + hdt_cli.cursor_pos);
-
- /* Return where we must put the new char */
- move_cursor_left(trailing_chars);
-
- } else {
- putchar(current_key);
- INPUT[hdt_cli.cursor_pos] = current_key;
- }
- hdt_cli.cursor_pos++;
- break;
- }
- }
-}