diff options
author | profkhaos <profkhaos@Khaos-Phantom.(none)> | 2009-08-20 19:40:08 +0300 |
---|---|---|
committer | profkhaos <profkhaos@Khaos-Phantom.(none)> | 2009-08-20 19:40:08 +0300 |
commit | 157b3a28a060a0bbfce0f047c8fa3712e0520207 (patch) | |
tree | b657737d44b7000ed9f4c347cf2028317c1d1bbd | |
parent | 97f408c190b315e3bc42d59a5f1fb9bd37afe9f4 (diff) | |
download | bak.git-157b3a28a060a0bbfce0f047c8fa3712e0520207.tar.gz bak.git-157b3a28a060a0bbfce0f047c8fa3712e0520207.tar.xz bak.git-157b3a28a060a0bbfce0f047c8fa3712e0520207.zip |
CLI with history and c32 smart loading
-rw-r--r-- | com32/elflink/modules/cli.h | 2 | ||||
-rw-r--r-- | com32/include/sys/exec.h | 13 | ||||
-rw-r--r-- | com32/include/sys/module.h | 7 | ||||
-rw-r--r-- | com32/lib/sys/module/colors.c | 191 | ||||
-rw-r--r-- | com32/lib/sys/module/exec.c | 108 | ||||
-rw-r--r-- | com32/lib/sys/module/menu.h | 227 | ||||
-rw-r--r-- | com32/lib/sys/module/readconfig.c | 1061 | ||||
-rw-r--r-- | com32/lib/sys/module/refstr.c | 105 | ||||
-rw-r--r-- | com32/lib/sys/module/refstr.h | 40 | ||||
-rw-r--r-- | core/elflink/cli.c | 80 | ||||
-rw-r--r-- | core/elflink/cli.h | 5 | ||||
-rw-r--r-- | core/elflink/load_env32.c | 52 |
12 files changed, 241 insertions, 1650 deletions
diff --git a/com32/elflink/modules/cli.h b/com32/elflink/modules/cli.h index b71c894d..76f57aed 100644 --- a/com32/elflink/modules/cli.h +++ b/com32/elflink/modules/cli.h @@ -6,7 +6,7 @@ struct cli_command { struct list_head list; - char command[MAX_CMDLINE_LEN]; + char *command; }; struct list_head cli_history_head; diff --git a/com32/include/sys/exec.h b/com32/include/sys/exec.h index 31a1af2e..0cb33bce 100644 --- a/com32/include/sys/exec.h +++ b/com32/include/sys/exec.h @@ -20,6 +20,19 @@ #define EXEC_ROOT_NAME "_root_.c32" /** + * spawn_load - Load a library module or executes an executable one + * @name the name of the library/executable to use, including the extension + * (e.g. 'sort.c32') + * @argv: a NULL-terminated vector of string arguments, starting with + * the program name. + * + * This procedure in essence loads takes the name of a module and checks to see what + * kind of module it is ( executable or library ), after which is performs the + * appropriate action, either spawning or simply loading the module into memory. + */ +extern int spawn_load(const char *name,const char **argv); + +/** * exec_init - Initialize the dynamic execution environment. * * Among others, it initializes the module subsystem and loads the root diff --git a/com32/include/sys/module.h b/com32/include/sys/module.h index 368a4139..1d94c094 100644 --- a/com32/include/sys/module.h +++ b/com32/include/sys/module.h @@ -23,6 +23,13 @@ #define MODULE_NAME_SIZE 256 /* + * Some common information about what kind of modules we're dealing with + */ +#define UNKNOWN_MODULE -1 +#define EXEC_MODULE 0 +#define LIB_MODULE 1 + +/* * Initialization and finalization function signatures */ diff --git a/com32/lib/sys/module/colors.c b/com32/lib/sys/module/colors.c deleted file mode 100644 index 6505d101..00000000 --- a/com32/lib/sys/module/colors.c +++ /dev/null @@ -1,191 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved - * - * 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, Inc., 51 Franklin St, Fifth Floor, - * Boston MA 02110-1301, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <colortbl.h> -#include <sys/module.h> -#include "menu.h" - -struct color_table *console_color_table = &default_color_table; -int console_color_table_size = - (sizeof default_color_table / sizeof(struct color_table)); - - -/* - * The color/attribute indexes (\1#X, \2#XX, \3#XXX) are as follows - * - * 00 - screen Rest of the screen - * 01 - border Border area - * 02 - title Title bar - * 03 - unsel Unselected menu item - * 04 - hotkey Unselected hotkey - * 05 - sel Selection bar - * 06 - hotsel Selected hotkey - * 07 - scrollbar Scroll bar - * 08 - tabmsg Press [Tab] message - * 09 - cmdmark Command line marker - * 10 - cmdline Command line - * 11 - pwdborder Password box border - * 12 - pwdheader Password box header - * 13 - pwdentry Password box contents - * 14 - timeout_msg Timeout message - * 15 - timeout Timeout counter - * 16 - help Current entry help text - * 17 - disabled Disabled menu item - */ - -static const struct color_table default_colors[] = { - {"screen", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL}, - {"border", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL}, - {"title", "1;36;44", 0xc00090f0, 0x00000000, SHADOW_NORMAL}, - {"unsel", "37;44", 0x90ffffff, 0x00000000, SHADOW_NORMAL}, - {"hotkey", "1;37;44", 0xffffffff, 0x00000000, SHADOW_NORMAL}, - {"sel", "7;37;40", 0xe0000000, 0x20ff8000, SHADOW_ALL}, - {"hotsel", "1;7;37;40", 0xe0400000, 0x20ff8000, SHADOW_ALL}, - {"scrollbar", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL}, - {"tabmsg", "31;40", 0x90ffff00, 0x00000000, SHADOW_NORMAL}, - {"cmdmark", "1;36;40", 0xc000ffff, 0x00000000, SHADOW_NORMAL}, - {"cmdline", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL}, - {"pwdborder", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL}, - {"pwdheader", "31;47", 0x80ff8080, 0x20ffffff, SHADOW_NORMAL}, - {"pwdentry", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL}, - {"timeout_msg", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL}, - {"timeout", "1;37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL}, - {"help", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL}, - {"disabled", "1;30;44", 0x60cccccc, 0x00000000, SHADOW_NORMAL}, -}; - -#define NCOLORS (sizeof default_colors/sizeof default_colors[0]) -const int message_base_color = NCOLORS; -const int menu_color_table_size = NCOLORS + 256; - -/* Algorithmically generate the msgXX colors */ -void set_msg_colors_global(struct color_table *tbl, - unsigned int fg, unsigned int bg, - enum color_table_shadow shadow) -{ - struct color_table *cp = tbl + message_base_color; - unsigned int i; - unsigned int fga, bga; - unsigned int fgh, bgh; - unsigned int fg_idx, bg_idx; - unsigned int fg_rgb, bg_rgb; - - static const unsigned int pc2rgb[8] = - { 0x000000, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00, - 0xffffff - }; - - /* Converting PC RGBI to sensible RGBA values is an "interesting" - proposition. This algorithm may need plenty of tweaking. */ - - fga = fg & 0xff000000; - fgh = ((fg >> 1) & 0xff000000) | 0x80000000; - - bga = bg & 0xff000000; - bgh = ((bg >> 1) & 0xff000000) | 0x80000000; - - for (i = 0; i < 256; i++) { - fg_idx = i & 15; - bg_idx = i >> 4; - - fg_rgb = pc2rgb[fg_idx & 7] & fg; - bg_rgb = pc2rgb[bg_idx & 7] & bg; - - if (fg_idx & 8) { - /* High intensity foreground */ - fg_rgb |= fgh; - } else { - fg_rgb |= fga; - } - - if (bg_idx == 0) { - /* Default black background, assume transparent */ - bg_rgb = 0; - } else if (bg_idx & 8) { - bg_rgb |= bgh; - } else { - bg_rgb |= bga; - } - - cp->argb_fg = fg_rgb; - cp->argb_bg = bg_rgb; - cp->shadow = shadow; - cp++; - } -} - -struct color_table *default_color_table(void) -{ - unsigned int i; - const struct color_table *dp; - struct color_table *cp; - struct color_table *color_table; - static const int pc2ansi[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; - static char msg_names[6 * 256]; - char *mp; - - color_table = calloc(NCOLORS + 256, sizeof(struct color_table)); - - dp = default_colors; - cp = color_table; - - for (i = 0; i < NCOLORS; i++) { - *cp = *dp; - cp->ansi = refstrdup(dp->ansi); - cp++; - dp++; - } - - mp = msg_names; - for (i = 0; i < 256; i++) { - cp->name = mp; - mp += sprintf(mp, "msg%02x", i) + 1; - - rsprintf(&cp->ansi, "%s3%d;4%d", (i & 8) ? "1;" : "", - pc2ansi[i & 7], pc2ansi[(i >> 4) & 7]); - cp++; - } - - /*** XXX: This needs to move to run_menu() ***/ - console_color_table = color_table; - console_color_table_size = NCOLORS + 256; - - set_msg_colors_global(color_table, MSG_COLORS_DEF_FG, - MSG_COLORS_DEF_BG, MSG_COLORS_DEF_SHADOW); - - return color_table; -} - -struct color_table *copy_color_table(const struct color_table *master) -{ - const struct color_table *dp; - struct color_table *color_table, *cp; - unsigned int i; - - color_table = calloc(NCOLORS + 256, sizeof(struct color_table)); - - dp = master; - cp = color_table; - - for (i = 0; i < NCOLORS + 256; i++) { - *cp = *dp; - cp->ansi = refstr_get(dp->ansi); - cp++; - dp++; - } - - return color_table; -} - diff --git a/com32/lib/sys/module/exec.c b/com32/lib/sys/module/exec.c index 5671774c..52fa04d1 100644 --- a/com32/lib/sys/module/exec.c +++ b/com32/lib/sys/module/exec.c @@ -45,6 +45,13 @@ int exec_init(void) return 0; } +int get_module_type(struct elf_module *module) +{ + if(module->main_func) return EXEC_MODULE; + else if(module->init_func) return LIB_MODULE; + return UNKNOWN_MODULE; +} + int load_library(const char *name) { int res; @@ -111,10 +118,11 @@ int spawnv(const char *name, const char **argv) const char **arg; int argc; char **argp, **args; - struct elf_module *module = module_alloc(name); struct elf_module *previous; malloc_tag_t prev_mem_tag; + struct elf_module *module = module_alloc(name); + if (module == NULL) return -1; @@ -125,6 +133,11 @@ int spawnv(const char *name, const char **argv) return res; } + if (module->main_func == NULL) { + // We can't execute without a main function + module_unload(module); + return -1; + } /*if (module->main_func != NULL) { const char **last_arg = argv; void *old_tag; @@ -208,8 +221,101 @@ int spawnl(const char *name, const char *arg, ...) return spawnv(name, &arg); } +int spawn_load(const char *name,const char **argv) +{ + int res, ret_val = 0; + const char **arg; + int argc; + char **argp, **args; + struct elf_module *previous; + malloc_tag_t prev_mem_tag; + struct elf_module *module = module_alloc(name); + + int type; + + if (module == NULL) + return -1; + + res = module_load(module); + + + if (res != 0) { + module_unload(module); + return res; + } + + type=get_module_type(module); + + if(type==LIB_MODULE) + { + if (module->init_func != NULL) { + res = (*(module->init_func))(); + DBG_PRINT("Initialization function returned: %d\n", res); + } else { + DBG_PRINT("No initialization function present.\n"); + } + + if (res != 0) { + module_unload(module); + return res; + } + return 0; + } + else if(type==EXEC_MODULE) + { + previous = __syslinux_current; + prev_mem_tag = __mem_get_tag_global(); + + // Setup the new process context + __syslinux_current = module; + __mem_set_tag_global((malloc_tag_t)module); + + // Generate a new process copy of argv (on the stack) + argc = 0; + for (arg = argv; *arg; arg++) + argc++; + + args = alloca((argc+1) * sizeof(char *)); + + for (arg = argv, argp = args; *arg; arg++, argp++) { + size_t l = strlen(*arg)+1; + *argp = alloca(l); + memcpy(*argp, *arg, l); + } + + *args = NULL; + + // Execute the program + ret_val = setjmp(module->u.x.process_exit); + + if (ret_val) + ret_val--; /* Valid range is 0-255 */ + else if (!module->main_func) + ret_val = -1; + else + exit((*module->main_func)(argc, args)); /* Actually run! */ + + // Clean up the allocation context + __free_tagged(module); + // Restore the allocation context + __mem_set_tag_global(prev_mem_tag); + // Restore the process context + __syslinux_current = previous; + + res = module_unload(module); + + if (res != 0) { + return res; + } + + return ((unsigned int)ret_val & 0xFF); + } + module_unload(module); + return -1; +} void exec_term(void) { modules_term(); } + diff --git a/com32/lib/sys/module/menu.h b/com32/lib/sys/module/menu.h deleted file mode 100644 index 1d7dee80..00000000 --- a/com32/lib/sys/module/menu.h +++ /dev/null @@ -1,227 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved - * - * 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, Inc., 51 Franklin St, Fifth Floor, - * Boston MA 02110-1301, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -/* - * menu.h - * - * Header file for the simple menu system - */ - -#ifndef MENU_H -#define MENU_H - -#include <time.h> -#include <sys/time.h> -#include <sys/times.h> -#include <inttypes.h> -#include <unistd.h> -#include <colortbl.h> -#include <stdbool.h> -#include "refstr.h" - -#ifndef CLK_TCK -# define CLK_TCK sysconf(_SC_CLK_TCK) -#endif - -struct menu; - -/* Note: the _UNRES variants must always be immediately after their - "normal" versions. */ -enum menu_action { - MA_NONE, /* Undefined value */ - MA_CMD, /* Execute a command */ - MA_DISABLED, /* Disabled menu entry */ - MA_SUBMENU, /* This is a submenu entry */ - MA_GOTO, /* Go to another menu */ - MA_GOTO_UNRES, /* Unresolved go to */ - MA_QUIT, /* Quit to CLI */ - MA_EXIT, /* Exit to higher-level menu */ - MA_EXIT_UNRES, /* Unresolved exit */ -}; - -struct menu_entry { - struct menu *menu; /* Parent menu */ - const char *displayname; - const char *label; - const char *passwd; - char *helptext; - const char *cmdline; - struct menu *submenu; - struct menu_entry *next; /* Linked list of all labels across menus */ - int entry; /* Entry number inside menu */ - enum menu_action action; - unsigned char hotkey; - bool save; /* Save this entry if selected */ -}; - -static inline bool is_disabled(struct menu_entry *me) -{ - return me->action == MA_DISABLED; -} - -enum kernel_type { - /* Meta-types for internal use */ - KT_NONE, - KT_LOCALBOOT, - - /* The ones we can pass off to SYSLINUX, in order */ - KT_KERNEL, /* Undefined type */ - KT_LINUX, /* Linux kernel */ - KT_BOOT, /* Bootstrap program */ - KT_BSS, /* Boot sector with patch */ - KT_PXE, /* PXE NBP */ - KT_FDIMAGE, /* Floppy disk image */ - KT_COMBOOT, /* COMBOOT image */ - KT_COM32, /* COM32 image */ - KT_CONFIG, /* Configuration file */ -}; - -extern const char *const kernel_types[]; - -/* Configurable integer parameters */ -enum parameter_number { - P_WIDTH, - P_MARGIN, - P_PASSWD_MARGIN, - P_MENU_ROWS, - P_TABMSG_ROW, - P_CMDLINE_ROW, - P_END_ROW, - P_PASSWD_ROW, - P_TIMEOUT_ROW, - P_HELPMSG_ROW, - P_HELPMSGEND_ROW, - P_HSHIFT, - P_VSHIFT, - P_HIDDEN_ROW, - - NPARAMS -}; - -/* Configurable messages */ -enum message_number { - MSG_TITLE, - MSG_AUTOBOOT, - MSG_TAB, - MSG_NOTAB, - MSG_PASSPROMPT, - - MSG_COUNT -}; - -struct messages { - const char *name; /* Message configuration name */ - const char *defmsg; /* Default message text */ -}; - -struct menu_parameter { - const char *name; - int value; -}; - -extern const struct menu_parameter mparm[NPARAMS]; - -struct fkey_help { - const char *textname; - const char *background; -}; - -struct menu { - struct menu *next; /* Linked list of all menus */ - const char *label; /* Goto label for this menu */ - struct menu *parent; - struct menu_entry *parent_entry; /* Entry for self in parent */ - - struct menu_entry **menu_entries; - struct menu_entry *menu_hotkeys[256]; - - const char *messages[MSG_COUNT]; - int mparm[NPARAMS]; - - int nentries; - int nentries_space; - int defentry; - int timeout; - - bool allowedit; - bool save; /* MENU SAVE default for this menu */ - - int curentry; - int curtop; - - const char *title; - const char *ontimeout; - const char *onerror; - const char *menu_master_passwd; - const char *menu_background; - - struct color_table *color_table; - - struct fkey_help fkeyhelp[12]; -}; - -extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list; - -/* 2048 is the current definition inside syslinux */ -#define MAX_CMDLINE_LEN 2048 - -/* These are global parameters regardless of which menu we're displaying */ -extern int shiftkey; -extern int hiddenmenu; -extern long long totaltimeout; - -void parse_configs(char **argv); -int draw_background(const char *filename); - -static inline int my_isspace(char c) -{ - return (unsigned char)c <= ' '; -} - -int my_isxdigit(char c); -unsigned int hexval(char c); -unsigned int hexval2(const char *p); -uint32_t parse_argb(char **p); - -int menu_main(int argc, char *argv[]); -void console_prepare(void); -void console_cleanup(void); - -extern const int message_base_color, menu_color_table_size; -int mygetkey(clock_t timeout); -int show_message_file(const char *filename, const char *background); - -/* passwd.c */ -int passwd_compare(const char *passwd, const char *entry); - -/* colors.c */ -#define MSG_COLORS_DEF_FG 0x90ffffff -#define MSG_COLORS_DEF_BG 0x80ffffff -#define MSG_COLORS_DEF_SHADOW SHADOW_NORMAL -void set_msg_colors_global(struct color_table *tbl, - unsigned int fg, unsigned int bg, - enum color_table_shadow shadow); -struct color_table *default_color_table(void); -struct color_table *copy_color_table(const struct color_table *master); -extern const int message_base_color; - -/* background.c */ -extern const char *current_background; -void set_background(const char *new_background); - -/* execute.c */ -void execute(const char *cmdline, enum kernel_type type); - -/* drain.c */ -void drain_keyboard(void); - -#endif /* MENU_H */ diff --git a/com32/lib/sys/module/readconfig.c b/com32/lib/sys/module/readconfig.c deleted file mode 100644 index 0049c181..00000000 --- a/com32/lib/sys/module/readconfig.c +++ /dev/null @@ -1,1061 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved - * Copyright 2009 Intel Corporation; author: H. Peter Anvin - * - * 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, Inc., 51 Franklin St, Fifth Floor, - * Boston MA 02110-1301, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -#include <stdio.h> -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> -#include <minmax.h> -#include <alloca.h> -#include <inttypes.h> -#include <colortbl.h> -#include <com32.h> -#include <syslinux/adv.h> -#include <syslinux/config.h> -#include <sys/module.h> -#include <syslinux/config.h> - -#include "menu.h" - -/* Empty refstring */ -const char *empty_string; - -/* Root menu, starting menu, hidden menu, and list of all menus */ -struct menu *root_menu, *start_menu, *hide_menu, *menu_list; - -/* These are global parameters regardless of which menu we're displaying */ -int shiftkey = 0; /* Only display menu if shift key pressed */ -int hiddenmenu = 0; -long long totaltimeout = 0; - -/* Keep track of global default */ -static int has_ui = 0; /* DEFAULT only counts if UI is found */ -static const char *globaldefault = NULL; -static bool menusave = false; /* True if there is any "menu save" */ - -/* Linked list of all entires, hidden or not; used by unlabel() */ -static struct menu_entry *all_entries; -static struct menu_entry **all_entries_end = &all_entries; - -static const struct messages messages[MSG_COUNT] = { - [MSG_AUTOBOOT] = {"autoboot", "Automatic boot in # second{,s}..."}, - [MSG_TAB] = {"tabmsg", "Press [Tab] to edit options"}, - [MSG_NOTAB] = {"notabmsg", ""}, - [MSG_PASSPROMPT] = {"passprompt", "Password required"}, -}; - -#define astrdup(x) ({ char *__x = (x); \ - size_t __n = strlen(__x) + 1; \ - char *__p = alloca(__n); \ - if ( __p ) memcpy(__p, __x, __n); \ - __p; }) - -/* Must match enum kernel_type */ -const char *const kernel_types[] = { - "none", - "localboot", - "kernel", - "linux", - "boot", - "bss", - "pxe", - "fdimage", - "comboot", - "com32", - "config", - NULL -}; - -/* - * Search the list of all menus for a specific label - */ -static struct menu *find_menu(const char *label) -{ - struct menu *m; - - for (m = menu_list; m; m = m->next) { - if (!strcmp(label, m->label)) - return m; - } - - return NULL; -} - -#define MAX_LINE 4096 - -static char *skipspace(char *p) -{ - while (*p && my_isspace(*p)) - p++; - - return p; -} - -/* Strip ^ from a string, returning a new reference to the same refstring - if none present */ -static const char *strip_caret(const char *str) -{ - const char *p, *r; - char *q; - int carets = 0; - - p = str; - for (;;) { - p = strchr(p, '^'); - if (!p) - break; - carets++; - p++; - } - - if (!carets) - return refstr_get(str); - - r = q = refstr_alloc(strlen(str) - carets); - for (p = str; *p; p++) - if (*p != '^') - *q++ = *p; - - *q = '\0'; /* refstr_alloc() already did this... */ - - return r; -} - -/* Check to see if we are at a certain keyword (case insensitive) */ -/* Returns a pointer to the first character past the keyword */ -static char *looking_at(char *line, const char *kwd) -{ - char *p = line; - const char *q = kwd; - - while (*p && *q && ((*p ^ *q) & ~0x20) == 0) { - p++; - q++; - } - - if (*q) - return NULL; /* Didn't see the keyword */ - - return my_isspace(*p) ? p : NULL; /* Must be EOL or whitespace */ -} - -static struct menu *new_menu(struct menu *parent, - struct menu_entry *parent_entry, const char *label) -{ - struct menu *m = calloc(1, sizeof(struct menu)); - int i; - - m->label = label; - m->title = refstr_get(empty_string); - - if (parent) { - /* Submenu */ - m->parent = parent; - m->parent_entry = parent_entry; - parent_entry->action = MA_SUBMENU; - parent_entry->submenu = m; - - for (i = 0; i < MSG_COUNT; i++) - m->messages[i] = refstr_get(parent->messages[i]); - - memcpy(m->mparm, parent->mparm, sizeof m->mparm); - - m->allowedit = parent->allowedit; - m->timeout = parent->timeout; - m->save = parent->save; - - m->ontimeout = refstr_get(parent->ontimeout); - m->onerror = refstr_get(parent->onerror); - m->menu_master_passwd = refstr_get(parent->menu_master_passwd); - m->menu_background = refstr_get(parent->menu_background); - - m->color_table = copy_color_table(parent->color_table); - - for (i = 0; i < 12; i++) { - m->fkeyhelp[i].textname = refstr_get(parent->fkeyhelp[i].textname); - m->fkeyhelp[i].background = - refstr_get(parent->fkeyhelp[i].background); - } - } else { - /* Root menu */ - for (i = 0; i < MSG_COUNT; i++) - m->messages[i] = refstrdup(messages[i].defmsg); - for (i = 0; i < NPARAMS; i++) - m->mparm[i] = mparm[i].value; - - m->allowedit = true; /* Allow edits of the command line */ - m->color_table = default_color_table(); - } - - m->next = menu_list; - menu_list = m; - - return m; -} - -struct labeldata { - const char *label; - const char *kernel; - enum kernel_type type; - const char *append; - const char *initrd; - const char *menulabel; - const char *passwd; - char *helptext; - unsigned int ipappend; - unsigned int menuhide; - unsigned int menudefault; - unsigned int menuseparator; - unsigned int menudisabled; - unsigned int menuindent; - enum menu_action action; - int save; - struct menu *submenu; -}; - -/* Menu currently being parsed */ -static struct menu *current_menu; - -static void clear_label_data(struct labeldata *ld) -{ - refstr_put(ld->label); - refstr_put(ld->kernel); - refstr_put(ld->append); - refstr_put(ld->initrd); - refstr_put(ld->menulabel); - refstr_put(ld->passwd); - - memset(ld, 0, sizeof *ld); -} - -static struct menu_entry *new_entry(struct menu *m) -{ - struct menu_entry *me; - - if (m->nentries >= m->nentries_space) { - if (!m->nentries_space) - m->nentries_space = 1; - else - m->nentries_space <<= 1; - - m->menu_entries = realloc(m->menu_entries, m->nentries_space * - sizeof(struct menu_entry *)); - } - - me = calloc(1, sizeof(struct menu_entry)); - me->menu = m; - me->entry = m->nentries; - m->menu_entries[m->nentries++] = me; - *all_entries_end = me; - all_entries_end = &me->next; - - return me; -} - -static void consider_for_hotkey(struct menu *m, struct menu_entry *me) -{ - const char *p = strchr(me->displayname, '^'); - - if (me->action != MA_DISABLED) { - if (p && p[1]) { - unsigned char hotkey = p[1] & ~0x20; - if (!m->menu_hotkeys[hotkey]) { - me->hotkey = hotkey; - m->menu_hotkeys[hotkey] = me; - } - } - } -} - -static void record(struct menu *m, struct labeldata *ld, const char *append) -{ - int i; - struct menu_entry *me; - const struct syslinux_ipappend_strings *ipappend; - - if (!ld->label) - return; /* Nothing defined */ - - /* Hidden entries are recorded on a special "hidden menu" */ - if (ld->menuhide) - m = hide_menu; - - if (ld->label) { - char ipoptions[4096], *ipp; - const char *a; - char *s; - - me = new_entry(m); - - me->displayname = ld->menulabel - ? refstr_get(ld->menulabel) : refstr_get(ld->label); - me->label = refstr_get(ld->label); - me->passwd = refstr_get(ld->passwd); - me->helptext = ld->helptext; - me->hotkey = 0; - me->action = ld->action ? ld->action : MA_CMD; - me->save = ld->save ? (ld->save > 0) : m->save; - - if (ld->menuindent) { - const char *dn; - - rsprintf(&dn, "%*s%s", ld->menuindent, "", me->displayname); - refstr_put(me->displayname); - me->displayname = dn; - } - - if (ld->menuseparator) { - refstr_put(me->displayname); - me->displayname = refstr_get(empty_string); - } - - if (ld->menuseparator || ld->menudisabled) { - me->action = MA_DISABLED; - refstr_put(me->label); - me->label = NULL; - refstr_put(me->passwd); - me->passwd = NULL; - } - - if (ld->menulabel) - consider_for_hotkey(m, me); - - switch (me->action) { - case MA_CMD: - ipp = ipoptions; - *ipp = '\0'; - - if (ld->initrd) - ipp += sprintf(ipp, " initrd=%s", ld->initrd); - - if (ld->ipappend) { - ipappend = syslinux_ipappend_strings(); - for (i = 0; i < ipappend->count; i++) { - if ((ld->ipappend & (1U << i)) && ipappend->ptr[i]) - ipp += sprintf(ipp, " %s", ipappend->ptr[i]); - } - } - - a = ld->append; - if (!a) - a = append; - if (!a || (a[0] == '-' && !a[1])) - a = ""; - s = a[0] ? " " : ""; - if (ld->type == KT_KERNEL) { - rsprintf(&me->cmdline, "%s%s%s%s", ld->kernel, s, a, ipoptions); - } else { - rsprintf(&me->cmdline, ".%s %s%s%s%s", - kernel_types[ld->type], ld->kernel, s, a, ipoptions); - } - break; - - case MA_GOTO_UNRES: - case MA_EXIT_UNRES: - me->cmdline = refstr_get(ld->kernel); - break; - - case MA_GOTO: - case MA_EXIT: - me->submenu = ld->submenu; - break; - - default: - break; - } - - if (ld->menudefault && me->action == MA_CMD) - m->defentry = m->nentries - 1; - } - - clear_label_data(ld); -} - -static struct menu *begin_submenu(const char *tag) -{ - struct menu_entry *me; - - if (!tag[0]) - tag = NULL; - - me = new_entry(current_menu); - me->displayname = refstrdup(tag); - return new_menu(current_menu, me, refstr_get(me->displayname)); -} - -static struct menu *end_submenu(void) -{ - return current_menu->parent ? current_menu->parent : current_menu; -} - -static struct menu_entry *find_label(const char *str) -{ - const char *p; - struct menu_entry *me; - int pos; - - p = str; - while (*p && !my_isspace(*p)) - p++; - - /* p now points to the first byte beyond the kernel name */ - pos = p - str; - - for (me = all_entries; me; me = me->next) { - if (!strncmp(str, me->label, pos) && !me->label[pos]) - return me; - } - - return NULL; -} - -static const char *unlabel(const char *str) -{ - /* Convert a CLI-style command line to an executable command line */ - const char *p; - const char *q; - struct menu_entry *me; - int pos; - - p = str; - while (*p && !my_isspace(*p)) - p++; - - /* p now points to the first byte beyond the kernel name */ - pos = p - str; - - for (me = all_entries; me; me = me->next) { - if (!strncmp(str, me->label, pos) && !me->label[pos]) { - /* Found matching label */ - rsprintf(&q, "%s%s", me->cmdline, p); - refstr_put(str); - return q; - } - } - - return str; -} - -static const char *refdup_word(char **p) -{ - char *sp = *p; - char *ep = sp; - - while (*ep && !my_isspace(*ep)) - ep++; - - *p = ep; - return refstrndup(sp, ep - sp); -} - -int my_isxdigit(char c) -{ - unsigned int uc = c; - - return (uc - '0') < 10 || ((uc | 0x20) - 'a') < 6; -} - -unsigned int hexval(char c) -{ - unsigned char uc = c | 0x20; - unsigned int v; - - v = uc - '0'; - if (v < 10) - return v; - - return uc - 'a' + 10; -} - -unsigned int hexval2(const char *p) -{ - return (hexval(p[0]) << 4) + hexval(p[1]); -} - -uint32_t parse_argb(char **p) -{ - char *sp = *p; - char *ep; - uint32_t argb; - size_t len, dl; - - if (*sp == '#') - sp++; - - ep = sp; - - while (my_isxdigit(*ep)) - ep++; - - *p = ep; - len = ep - sp; - - switch (len) { - case 3: /* #rgb */ - argb = - 0xff000000 + - (hexval(sp[0]) * 0x11 << 16) + - (hexval(sp[1]) * 0x11 << 8) + (hexval(sp[2]) * 0x11); - break; - case 4: /* #argb */ - argb = - (hexval(sp[0]) * 0x11 << 24) + - (hexval(sp[1]) * 0x11 << 16) + - (hexval(sp[2]) * 0x11 << 8) + (hexval(sp[3]) * 0x11); - break; - case 6: /* #rrggbb */ - case 9: /* #rrrgggbbb */ - case 12: /* #rrrrggggbbbb */ - dl = len / 3; - argb = - 0xff000000 + - (hexval2(sp + 0) << 16) + - (hexval2(sp + dl) << 8) + hexval2(sp + dl * 2); - break; - case 8: /* #aarrggbb */ - /* #aaarrrgggbbb is indistinguishable from #rrrrggggbbbb, - assume the latter is a more common format */ - case 16: /* #aaaarrrrggggbbbb */ - dl = len / 4; - argb = - (hexval2(sp + 0) << 24) + - (hexval2(sp + dl) << 16) + - (hexval2(sp + dl * 2) << 8) + hexval2(sp + dl * 3); - break; - default: - argb = 0xffff0000; /* Bright red (error indication) */ - break; - } - - return argb; -} - -/* - * Parser state. This is global so that including multiple - * files work as expected, which is that everything works the - * same way as if the files had been concatenated together. - */ -static const char *append = NULL; -static unsigned int ipappend = 0; -static struct labeldata ld; - -static int parse_one_config(const char *filename); - -static char *is_kernel_type(char *cmdstr, enum kernel_type *type) -{ - const char *const *p; - char *q; - enum kernel_type t = KT_NONE; - - for (p = kernel_types; *p; p++, t++) { - if ((q = looking_at(cmdstr, *p))) { - *type = t; - return q; - } - } - - return NULL; -} - -static char *is_message_name(char *cmdstr, enum message_number *msgnr) -{ - char *q; - enum message_number i; - - for (i = 0; i < MSG_COUNT; i++) { - if ((q = looking_at(cmdstr, messages[i].name))) { - *msgnr = i; - return q; - } - } - - return NULL; -} - -static char *is_fkey(char *cmdstr, int *fkeyno) -{ - char *q; - int no; - - if ((cmdstr[0] | 0x20) != 'f') - return NULL; - - no = strtoul(cmdstr + 1, &q, 10); - if (!my_isspace(*q)) - return NULL; - - if (no < 0 || no > 12) - return NULL; - - *fkeyno = (no == 0) ? 10 : no - 1; - return q; -} - -static void parse_config_file(FILE * f) -{ - char line[MAX_LINE], *p, *ep, ch; - enum kernel_type type; - enum message_number msgnr; - int fkeyno; - struct menu *m = current_menu; - - while (fgets(line, sizeof line, f)) { - p = strchr(line, '\r'); - if (p) - *p = '\0'; - p = strchr(line, '\n'); - if (p) - *p = '\0'; - - p = skipspace(line); - - if (looking_at(p, "menu")) { - p = skipspace(p + 4); - - if (looking_at(p, "label")) { - if (ld.label) { - refstr_put(ld.menulabel); - ld.menulabel = refstrdup(skipspace(p + 5)); - } else if (m->parent_entry) { - refstr_put(m->parent_entry->displayname); - m->parent_entry->displayname = refstrdup(skipspace(p + 5)); - consider_for_hotkey(m->parent, m->parent_entry); - if (!m->title[0]) { - /* MENU LABEL -> MENU TITLE on submenu */ - refstr_put(m->title); - m->title = strip_caret(m->parent_entry->displayname); - } - } - } else if (looking_at(p, "title")) { - refstr_put(m->title); - m->title = refstrdup(skipspace(p + 5)); - if (m->parent_entry) { - /* MENU TITLE -> MENU LABEL on submenu */ - if (m->parent_entry->displayname == m->label) { - refstr_put(m->parent_entry->displayname); - m->parent_entry->displayname = refstr_get(m->title); - } - } - } else if (looking_at(p, "default")) { - if (ld.label) { - ld.menudefault = 1; - } else if (m->parent_entry) { - m->parent->defentry = m->parent_entry->entry; - } - } else if (looking_at(p, "hide")) { - ld.menuhide = 1; - } else if (looking_at(p, "passwd")) { - if (ld.label) { - refstr_put(ld.passwd); - ld.passwd = refstrdup(skipspace(p + 6)); - } else if (m->parent_entry) { - refstr_put(m->parent_entry->passwd); - m->parent_entry->passwd = refstrdup(skipspace(p + 6)); - } - } else if (looking_at(p, "shiftkey")) { - shiftkey = 1; - } else if (looking_at(p, "save")) { - menusave = true; - if (ld.label) - ld.save = 1; - else - m->save = true; - } else if (looking_at(p, "nosave")) { - if (ld.label) - ld.save = -1; - else - m->save = false; - } else if (looking_at(p, "onerror")) { - refstr_put(m->onerror); - m->onerror = refstrdup(skipspace(p + 7)); - } else if (looking_at(p, "master")) { - p = skipspace(p + 6); - if (looking_at(p, "passwd")) { - refstr_put(m->menu_master_passwd); - m->menu_master_passwd = refstrdup(skipspace(p + 6)); - } - } else if ((ep = looking_at(p, "include"))) { - goto do_include; - } else if ((ep = looking_at(p, "background"))) { - p = skipspace(ep); - refstr_put(m->menu_background); - m->menu_background = refdup_word(&p); - } else if ((ep = looking_at(p, "hidden"))) { - hiddenmenu = 1; - } else if ((ep = is_message_name(p, &msgnr))) { - refstr_put(m->messages[msgnr]); - m->messages[msgnr] = refstrdup(skipspace(ep)); - } else if ((ep = looking_at(p, "color")) || - (ep = looking_at(p, "colour"))) { - int i; - struct color_table *cptr; - p = skipspace(ep); - cptr = m->color_table; - for (i = 0; i < menu_color_table_size; i++) { - if ((ep = looking_at(p, cptr->name))) { - p = skipspace(ep); - if (*p) { - if (looking_at(p, "*")) { - p++; - } else { - refstr_put(cptr->ansi); - cptr->ansi = refdup_word(&p); - } - - p = skipspace(p); - if (*p) { - if (looking_at(p, "*")) - p++; - else - cptr->argb_fg = parse_argb(&p); - - p = skipspace(p); - if (*p) { - if (looking_at(p, "*")) - p++; - else - cptr->argb_bg = parse_argb(&p); - - /* Parse a shadow mode */ - p = skipspace(p); - ch = *p | 0x20; - if (ch == 'n') /* none */ - cptr->shadow = SHADOW_NONE; - else if (ch == 's') /* std, standard */ - cptr->shadow = SHADOW_NORMAL; - else if (ch == 'a') /* all */ - cptr->shadow = SHADOW_ALL; - else if (ch == 'r') /* rev, reverse */ - cptr->shadow = SHADOW_REVERSE; - } - } - } - break; - } - cptr++; - } - } else if ((ep = looking_at(p, "msgcolor")) || - (ep = looking_at(p, "msgcolour"))) { - unsigned int fg_mask = MSG_COLORS_DEF_FG; - unsigned int bg_mask = MSG_COLORS_DEF_BG; - enum color_table_shadow shadow = MSG_COLORS_DEF_SHADOW; - - p = skipspace(ep); - if (*p) { - if (!looking_at(p, "*")) - fg_mask = parse_argb(&p); - - p = skipspace(p); - if (*p) { - if (!looking_at(p, "*")) - bg_mask = parse_argb(&p); - - p = skipspace(p); - switch (*p | 0x20) { - case 'n': - shadow = SHADOW_NONE; - break; - case 's': - shadow = SHADOW_NORMAL; - break; - case 'a': - shadow = SHADOW_ALL; - break; - case 'r': - shadow = SHADOW_REVERSE; - break; - default: - /* go with default */ - break; - } - } - } - set_msg_colors_global(m->color_table, fg_mask, bg_mask, shadow); - } else if (looking_at(p, "separator")) { - record(m, &ld, append); - ld.label = refstr_get(empty_string); - ld.menuseparator = 1; - record(m, &ld, append); - } else if (looking_at(p, "disable") || looking_at(p, "disabled")) { - ld.menudisabled = 1; - } else if (looking_at(p, "indent")) { - ld.menuindent = atoi(skipspace(p + 6)); - } else if (looking_at(p, "begin")) { - record(m, &ld, append); - m = current_menu = begin_submenu(skipspace(p + 5)); - } else if (looking_at(p, "end")) { - record(m, &ld, append); - m = current_menu = end_submenu(); - } else if (looking_at(p, "quit")) { - if (ld.label) - ld.action = MA_QUIT; - } else if (looking_at(p, "goto")) { - if (ld.label) { - ld.action = MA_GOTO_UNRES; - refstr_put(ld.kernel); - ld.kernel = refstrdup(skipspace(p + 4)); - } - } else if (looking_at(p, "exit")) { - p = skipspace(p + 4); - if (ld.label && m->parent) { - if (*p) { - /* This is really just a goto, except for the marker */ - ld.action = MA_EXIT_UNRES; - refstr_put(ld.kernel); - ld.kernel = refstrdup(p); - } else { - ld.action = MA_EXIT; - ld.submenu = m->parent; - } - } - } else if (looking_at(p, "start")) { - start_menu = m; - } else { - /* Unknown, check for layout parameters */ - enum parameter_number mp; - for (mp = 0; mp < NPARAMS; mp++) { - if ((ep = looking_at(p, mparm[mp].name))) { - m->mparm[mp] = atoi(skipspace(ep)); - break; - } - } - } - } else if (looking_at(p, "text")) { - enum text_cmd { - TEXT_UNKNOWN, - TEXT_HELP - } cmd = TEXT_UNKNOWN; - int len = ld.helptext ? strlen(ld.helptext) : 0; - int xlen; - - p = skipspace(p + 4); - - if (looking_at(p, "help")) - cmd = TEXT_HELP; - - while (fgets(line, sizeof line, f)) { - p = skipspace(line); - if (looking_at(p, "endtext")) - break; - - xlen = strlen(line); - - switch (cmd) { - case TEXT_UNKNOWN: - break; - case TEXT_HELP: - ld.helptext = realloc(ld.helptext, len + xlen + 1); - memcpy(ld.helptext + len, line, xlen + 1); - len += xlen; - break; - } - } - } else if ((ep = is_fkey(p, &fkeyno))) { - p = skipspace(ep); - if (m->fkeyhelp[fkeyno].textname) { - refstr_put(m->fkeyhelp[fkeyno].textname); - m->fkeyhelp[fkeyno].textname = NULL; - } - if (m->fkeyhelp[fkeyno].background) { - refstr_put(m->fkeyhelp[fkeyno].background); - m->fkeyhelp[fkeyno].background = NULL; - } - - refstr_put(m->fkeyhelp[fkeyno].textname); - m->fkeyhelp[fkeyno].textname = refdup_word(&p); - if (*p) { - p = skipspace(p); - m->fkeyhelp[fkeyno].background = refdup_word(&p); - } - } else if ((ep = looking_at(p, "include"))) { -do_include: - { - const char *file; - p = skipspace(ep); - file = refdup_word(&p); - p = skipspace(p); - if (*p) { - record(m, &ld, append); - m = current_menu = begin_submenu(p); - parse_one_config(file); - record(m, &ld, append); - m = current_menu = end_submenu(); - } else { - parse_one_config(file); - } - refstr_put(file); - } - } else if (looking_at(p, "append")) { - const char *a = refstrdup(skipspace(p + 6)); - if (ld.label) { - refstr_put(ld.append); - ld.append = a; - } else { - refstr_put(append); - append = a; - } - } else if (looking_at(p, "initrd")) { - const char *a = refstrdup(skipspace(p + 6)); - if (ld.label) { - refstr_put(ld.initrd); - ld.initrd = a; - } else { - /* Ignore */ - } - } else if (looking_at(p, "label")) { - p = skipspace(p + 5); - record(m, &ld, append); - ld.label = refstrdup(p); - ld.kernel = refstrdup(p); - ld.type = KT_KERNEL; - ld.passwd = NULL; - ld.append = NULL; - ld.initrd = NULL; - ld.menulabel = NULL; - ld.helptext = NULL; - ld.ipappend = ipappend; - ld.menudefault = ld.menuhide = ld.menuseparator = - ld.menudisabled = ld.menuindent = 0; - } else if ((ep = is_kernel_type(p, &type))) { - if (ld.label) { - refstr_put(ld.kernel); - ld.kernel = refstrdup(skipspace(ep)); - ld.type = type; - } - } else if (looking_at(p, "timeout")) { - m->timeout = (atoi(skipspace(p + 7)) * CLK_TCK + 9) / 10; - } else if (looking_at(p, "totaltimeout")) { - totaltimeout = (atoll(skipspace(p + 13)) * CLK_TCK + 9) / 10; - } else if (looking_at(p, "ontimeout")) { - m->ontimeout = refstrdup(skipspace(p + 9)); - } else if (looking_at(p, "allowoptions")) { - m->allowedit = !!atoi(skipspace(p + 12)); - } else if (looking_at(p, "ipappend")) { - if (ld.label) - ld.ipappend = atoi(skipspace(p + 8)); - else - ipappend = atoi(skipspace(p + 8)); - } else if (looking_at(p, "default")) { - refstr_put(globaldefault); - globaldefault = refstrdup(skipspace(p + 7)); - } else if (looking_at(p, "ui")) { - has_ui = 1; - } - } -} - -static int parse_one_config(const char *filename) -{ - FILE *f; - - if (!strcmp(filename, "~")) - filename = syslinux_config_file(); - - f = fopen(filename, "r"); - if (!f) - return -1; - - parse_config_file(f); - fclose(f); - - return 0; -} - -static void resolve_gotos(void) -{ - struct menu_entry *me; - struct menu *m; - - for (me = all_entries; me; me = me->next) { - if (me->action == MA_GOTO_UNRES || me->action == MA_EXIT_UNRES) { - m = find_menu(me->cmdline); - refstr_put(me->cmdline); - me->cmdline = NULL; - if (m) { - me->submenu = m; - me->action--; /* Drop the _UNRES */ - } else { - me->action = MA_DISABLED; - } - } - } -} - -void parse_configs(char **argv) -{ - const char *filename; - struct menu *m; - struct menu_entry *me; - - empty_string = refstrdup(""); - - /* Initialize defaults for the root and hidden menus */ - hide_menu = new_menu(NULL, NULL, refstrdup(".hidden")); - root_menu = new_menu(NULL, NULL, refstrdup(".top")); - start_menu = root_menu; - - /* Other initialization */ - memset(&ld, 0, sizeof(struct labeldata)); - - /* Actually process the files */ - current_menu = root_menu; - if (!*argv) { - parse_one_config("~"); - } else { - while ((filename = *argv++)) - parse_one_config(filename); - } - - /* On final EOF process the last label statement */ - record(current_menu, &ld, append); - - /* Common postprocessing */ - resolve_gotos(); - - /* Handle global default */ - if (has_ui && globaldefault) { - me = find_label(globaldefault); - if (me && me->menu != hide_menu) { - me->menu->defentry = me->entry; - start_menu = me->menu; - } - } - - /* If "menu save" is active, let the ADV override the global default */ - if (menusave) { - size_t len; - const char *lbl = syslinux_getadv(ADV_MENUSAVE, &len); - char *lstr; - if (lbl && len) { - lstr = refstr_alloc(len); - memcpy(lstr, lbl, len); /* refstr_alloc() adds the final null */ - me = find_label(lstr); - if (me && me->menu != hide_menu) { - me->menu->defentry = me->entry; - start_menu = me->menu; - } - refstr_put(lstr); - } - } - - /* Final per-menu initialization, with all labels known */ - for (m = menu_list; m; m = m->next) { - m->curentry = m->defentry; /* All menus start at their defaults */ - - if (m->ontimeout) - m->ontimeout = unlabel(m->ontimeout); - if (m->onerror) - m->onerror = unlabel(m->onerror); - } -} - diff --git a/com32/lib/sys/module/refstr.c b/com32/lib/sys/module/refstr.c deleted file mode 100644 index 97ab1edb..00000000 --- a/com32/lib/sys/module/refstr.c +++ /dev/null @@ -1,105 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2008 H. Peter Anvin - All Rights Reserved - * - * 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, Inc., 51 Franklin St, Fifth Floor, - * Boston MA 02110-1301, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -/* - * refstr.c - * - * Simple reference-counted strings - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include "refstr.h" - -/* Allocate space for a refstring of len bytes, plus final null */ -/* The final null is inserted in the string; the rest is uninitialized. */ -char *refstr_alloc(size_t len) -{ - char *r = malloc(sizeof(unsigned int) + len + 1); - if (!r) - return NULL; - *(unsigned int *)r = 1; - r += sizeof(unsigned int); - r[len] = '\0'; - return r; -} - -const char *refstrndup(const char *str, size_t len) -{ - char *r; - - if (!str) - return NULL; - - len = strnlen(str, len); - r = refstr_alloc(len); - if (r) - memcpy(r, str, len); - return r; -} - -const char *refstrdup(const char *str) -{ - char *r; - size_t len; - - if (!str) - return NULL; - - len = strlen(str); - r = refstr_alloc(len); - if (r) - memcpy(r, str, len); - return r; -} - -int vrsprintf(const char **bufp, const char *fmt, va_list ap) -{ - va_list ap1; - int len; - char *p; - - va_copy(ap1, ap); - len = vsnprintf(NULL, 0, fmt, ap1); - va_end(ap1); - - *bufp = p = refstr_alloc(len); - if (!p) - return -1; - - return vsnprintf(p, len + 1, fmt, ap); -} - -int rsprintf(const char **bufp, const char *fmt, ...) -{ - int rv; - va_list ap; - - va_start(ap, fmt); - rv = vrsprintf(bufp, fmt, ap); - va_end(ap); - - return rv; -} - -void refstr_put(const char *r) -{ - unsigned int *ref; - - if (r) { - ref = (unsigned int *)r - 1; - - if (!--*ref) - free(ref); - } -} diff --git a/com32/lib/sys/module/refstr.h b/com32/lib/sys/module/refstr.h deleted file mode 100644 index 7001d407..00000000 --- a/com32/lib/sys/module/refstr.h +++ /dev/null @@ -1,40 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2008 H. Peter Anvin - All Rights Reserved - * - * 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, Inc., 51 Franklin St, Fifth Floor, - * Boston MA 02110-1301, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -/* - * refstr.h - * - * Simple reference-counted strings - */ - -#ifndef REFSTR_H -#define REFSTR_H - -#include <stddef.h> -#include <stdarg.h> - -static inline __attribute__ ((always_inline)) -const char *refstr_get(const char *r) -{ - if (r) - ((unsigned int *)r)[-1]++; - return r; -} - -void refstr_put(const char *); -char *refstr_alloc(size_t); -const char *refstrdup(const char *); -const char *refstrndup(const char *, size_t); -int rsprintf(const char **, const char *, ...); -int vrsprintf(const char **, const char *, va_list); - -#endif diff --git a/core/elflink/cli.c b/core/elflink/cli.c index 11359ea8..e58d6948 100644 --- a/core/elflink/cli.c +++ b/core/elflink/cli.c @@ -10,6 +10,8 @@ #include <limits.h> #include <minmax.h> #include <linux/list.h> +#include <sys/exec.h> +#include <sys/module.h> #include "getkey.h" #include "common.h" @@ -58,7 +60,7 @@ int mygetkey(clock_t timeout) const char *edit_cmdline(const char *input, int top /*, int width */,int (*pDraw_Menu)(int, int, int),void (*show_fkey)(int)) { static char cmdline[MAX_CMDLINE_LEN]; - char temp_cmdline[MAX_CMDLINE_LEN]; + char temp_cmdline[MAX_CMDLINE_LEN]={}; int key, len, prev_len, cursor; int redraw = 1; /* We enter with the menu already drawn */ int x, y; @@ -66,7 +68,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */,int (*pDraw const char *ret; int width = 0; struct cli_command *comm_counter; - comm_counter=list_entry(cli_history_head.next, typeof(*comm_counter),list); + comm_counter=list_entry(cli_history_head.next->prev, typeof(*comm_counter),list); if (!width) { int height; @@ -74,7 +76,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */,int (*pDraw width = 80; } - printf("width = %d\n", width); + //printf("width = %d\n", width); strncpy(cmdline, input, MAX_CMDLINE_LEN); cmdline[MAX_CMDLINE_LEN - 1] = '\0'; @@ -273,7 +275,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */,int (*pDraw redraw = 1; } break; - case KEY_DOWN: + case KEY_UP: { if(!list_empty(&cli_history_head)) { @@ -291,7 +293,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */,int (*pDraw } } break; - case KEY_UP: + case KEY_DOWN: { if(!list_empty(&cli_history_head)) { @@ -343,3 +345,71 @@ const char *edit_cmdline(const char *input, int top /*, int width */,int (*pDraw return ret; } +void process_command(const char *cmd) +{ + char **cmd_line = malloc((MAX_COMMAND_ARGS+1)*sizeof(char*)); + char *temp_cmd=(char*)malloc(sizeof(char)*(strlen(cmd)+1)); + int argc = 0, len_mn; + char *crt_arg,*module_name; + + strcpy(temp_cmd,cmd); + module_name = strtok(cmd, COMMAND_DELIM); + len_mn=strlen(module_name); + + if(!strcmp(module_name+len_mn-4,".c32")) + { + if(module_find(module_name) != NULL) goto cleanup; + do + { + crt_arg = strtok(NULL, COMMAND_DELIM); + if (crt_arg != NULL && strlen(crt_arg) > 0) + { + cmd_line[argc] = crt_arg; + argc++; + } + else + { + break; + } + }while (argc < MAX_COMMAND_ARGS); + cmd_line[argc] = NULL; + /*int i; + for(i=0;i<argc;i++) + { + printf("%s\n",cmd_line[i]); + }*/ + spawn_load(module_name,cmd_line); + } + else if(!strcmp(module_name+len_mn-2,".0")) + { + //printf("%s\n",temp_cmd); + execute(cmd,KT_PXE); + } + else if(!strcmp(module_name+len_mn-3,".bs")) + { + //printf("%s\n",temp_cmd); + } + else if(!strcmp(module_name+len_mn-4,".img")) + { + //printf("%s\n",temp_cmd); + execute(cmd,KT_FDIMAGE); + } + else if(!strcmp(module_name+len_mn-4,".bin")) + { + printf("%s\n",temp_cmd); + } + else if(!strcmp(module_name+len_mn-4,".bss")) + { + //printf("%s\n",temp_cmd); + execute(cmd,KT_BSS); + } + else if(!strcmp(module_name+len_mn-4,".com") || !strcmp(module_name+len_mn-4,".cbt")) + { + //printf("%s\n",temp_cmd); + execute(cmd,KT_COMBOOT); + } +cleanup: + free(cmd_line); + free(temp_cmd); +} + diff --git a/core/elflink/cli.h b/core/elflink/cli.h index b71c894d..c810539f 100644 --- a/core/elflink/cli.h +++ b/core/elflink/cli.h @@ -2,11 +2,13 @@ #define CLI_H #define MAX_CMD_HISTORY 64 +#define COMMAND_DELIM " \t\n" // Whitespace delimiters +#define MAX_COMMAND_ARGS 40 struct cli_command { struct list_head list; - char command[MAX_CMDLINE_LEN]; + char *command; }; struct list_head cli_history_head; @@ -14,5 +16,6 @@ struct list_head cli_history_head; extern void clear_screen(void); extern int mygetkey(clock_t timeout); extern const char *edit_cmdline(const char *input, int top /*, int width */,int (*pDraw_Menu)(int, int, int),void (*show_fkey)(int)); +extern void process_command(const char *cmd); #endif diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c index 9e022c69..a4c81396 100644 --- a/core/elflink/load_env32.c +++ b/core/elflink/load_env32.c @@ -72,22 +72,10 @@ void load_env32(com32sys_t * regs) { call_constr(); char *cmdline; - struct cli_command c1,c2,c3,*aux; + struct cli_command c1,c2,c3,*comm,*aux; openconsole(&dev_rawcon_r, &dev_ansiserial_w); INIT_LIST_HEAD(&cli_history_head); - strcpy(c1.command,"command 1"); - strcpy(c2.command,"command 2"); - strcpy(c3.command,"command 3"); - list_add(&(c1.list),&cli_history_head); - list_add(&(c2.list),&cli_history_head); - list_add(&(c3.list),&cli_history_head); - - list_for_each_entry(aux, &cli_history_head, list) - { - printf("%s\n",aux->command); - } - printf("Calling initilization constructor procedures...\n"); printf("Starting 32 bit elf module subsystem...\n"); init_module_subsystem(&core_module); @@ -97,10 +85,36 @@ void load_env32(com32sys_t * regs) printf("Str table size: %d\n",core_module.strtable_size); printf("Sym table size: %d\n",core_module.symtable_size); - cmdline=edit_cmdline("",1,NULL,NULL); - printf("\n%s\n",cmdline); - //fgets(cmdline,100,stdin); + c1.command=(char*)malloc(sizeof(char)*16); + c2.command=(char*)malloc(sizeof(char)*16); + c3.command=(char*)malloc(sizeof(char)*16); + strcpy(c1.command,"command 1"); + strcpy(c2.command,"command 2"); + strcpy(c3.command,"command 3"); + list_add(&(c1.list),&cli_history_head); + list_add(&(c2.list),&cli_history_head); + list_add(&(c3.list),&cli_history_head); + + + /*list_for_each_entry(aux,&cli_history_head,list) + { + printf("%s\n",aux->command); + }*/ + + while(1) + { + cmdline=edit_cmdline("",1,NULL,NULL); + aux=list_entry(cli_history_head.next, typeof(*aux),list); + if(strcmp(aux->command,cmdline)) + { + comm=(struct cli_command*)malloc(sizeof(struct cli_command*)); + comm->command=(char*)malloc(sizeof(char)*(strlen(cmdline)+1)); + strcpy(comm->command,cmdline); + list_add(&(comm->list),&cli_history_head); + process_command(cmdline); + } + } int i,n=5; char **argv; @@ -124,13 +138,15 @@ void load_env32(com32sys_t * regs) printf("Loading crypt-md5.c32\n%d\n",load_library("dyn/crypt-md5.c32")); printf("Loading passwd.c32\n%d\n",load_library("dyn/passwd.c32")); printf("Loading get_key.c32\n%d\n",load_library("dyn/get_key.c32")); - printf("Loading menumain.c32\n%d\n",load_library("dyn/menumain.c32")); + //printf("Loading menumain.c32\n%d\n",load_library("dyn/menumain.c32")); + spawn_load("dyn/menumain.c32",0); /*printf("\n\nTrying to spawn 'dyn/hello.dyn'\n\n"); spawnv("dyn/hello.dyn",0); printf("\nTest done\n");*/ //printf("%d\n",spawnv("mytest.c32",argv)); - spawnl("mytest.c32", "mytest",(regs->edi.w[0]), NULL); + spawn_load("mytest.c32",argv); + //spawnl("mytest.c32", "mytest",(regs->edi.w[0]), NULL); //printf("Done\n"); while(1) 1; /* we don't have anything better to do so hang around for a bit */ |