aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MCONFIG3
-rw-r--r--NEWS7
-rw-r--r--com32/cmenu/adv_menu.tpl45
-rw-r--r--com32/cmenu/complex.c109
-rw-r--r--com32/cmenu/libmenu/com32io.c69
-rw-r--r--com32/cmenu/libmenu/com32io.h69
-rw-r--r--com32/cmenu/libmenu/help.c147
-rw-r--r--com32/cmenu/libmenu/help.h6
-rw-r--r--com32/cmenu/libmenu/menu.c1371
-rw-r--r--com32/cmenu/libmenu/menu.h23
-rw-r--r--com32/cmenu/libmenu/scancodes.h86
-rw-r--r--com32/cmenu/libmenu/tui.c235
-rw-r--r--com32/cmenu/libmenu/tui.h56
-rw-r--r--com32/gplinclude/cpuid.h8
-rw-r--r--com32/gplinclude/disk/bootloaders.h18
-rw-r--r--com32/gplinclude/disk/common.h6
-rw-r--r--com32/gplinclude/disk/error.h4
-rw-r--r--com32/gplinclude/disk/mbrs.h18
-rw-r--r--com32/gplinclude/disk/util.h1
-rw-r--r--com32/gplinclude/dmi/dmi.h3
-rw-r--r--com32/gpllib/cpuid.c2
-rw-r--r--com32/gpllib/disk/ata.c1
-rw-r--r--com32/gpllib/disk/bootloaders.c46
-rw-r--r--com32/gpllib/disk/error.c2
-rw-r--r--com32/gpllib/disk/mbrs.c91
-rw-r--r--com32/gpllib/dmi/dmi.c114
-rw-r--r--com32/gpllib/dmi/dmi_memory.c10
-rw-r--r--com32/hdt/Makefile47
-rw-r--r--com32/hdt/README19
-rw-r--r--com32/hdt/floppy/hdt.cfg7
-rw-r--r--com32/hdt/floppy/mtools.conf2
-rw-r--r--com32/hdt/hdt-cli-cpu.c4
-rw-r--r--com32/hdt/hdt-cli-disk.c55
-rw-r--r--com32/hdt/hdt-cli-dmi.c223
-rw-r--r--com32/hdt/hdt-cli-hdt.c40
-rw-r--r--com32/hdt/hdt-cli-kernel.c8
-rw-r--r--com32/hdt/hdt-cli-memory.c2
-rw-r--r--com32/hdt/hdt-cli-pci.c55
-rw-r--r--com32/hdt/hdt-cli-pxe.c17
-rw-r--r--com32/hdt/hdt-cli-syslinux.c13
-rw-r--r--com32/hdt/hdt-cli-vesa.c29
-rw-r--r--com32/hdt/hdt-cli-vpd.c4
-rw-r--r--com32/hdt/hdt-cli.c52
-rw-r--r--com32/hdt/hdt-cli.h2
-rw-r--r--com32/hdt/hdt-common.c71
-rw-r--r--com32/hdt/hdt-common.h47
-rw-r--r--com32/hdt/hdt-menu-about.c19
-rw-r--r--com32/hdt/hdt-menu-disk.c41
-rw-r--r--com32/hdt/hdt-menu-kernel.c2
-rw-r--r--com32/hdt/hdt-menu-pci.c2
-rw-r--r--com32/hdt/hdt-menu-processor.c4
-rw-r--r--com32/hdt/hdt-menu-summary.c2
-rw-r--r--com32/hdt/hdt-menu-syslinux.c3
-rw-r--r--com32/hdt/hdt-menu.c57
-rw-r--r--com32/hdt/hdt-menu.h5
-rw-r--r--com32/hdt/hdt.c27
-rw-r--r--com32/hdt/hdt.h6
-rw-r--r--com32/hdt/lib-ansi.c104
-rw-r--r--com32/include/cpufeature.h2
-rw-r--r--com32/include/libansi.h (renamed from com32/hdt/lib-ansi.h)75
-rw-r--r--com32/lib/Makefile2
-rw-r--r--com32/lib/sys/ansi.c67
-rw-r--r--com32/lib/sys/ansi.h37
-rw-r--r--com32/lib/sys/ansicon_write.c18
-rw-r--r--com32/lib/sys/libansi.c237
-rw-r--r--com32/mboot/map.c2
-rw-r--r--com32/modules/Makefile8
-rw-r--r--com32/modules/chain.c140
-rw-r--r--com32/modules/cpuidtest.c4
-rw-r--r--com32/modules/dmitest.c2
-rw-r--r--com32/modules/gpxecmd.c137
-rw-r--r--core/localboot.inc2
-rw-r--r--core/pxelinux.asm69
-rw-r--r--core/runkernel.inc2
-rw-r--r--core/serirq.inc28
-rw-r--r--modules/Makefile2
-rw-r--r--modules/int18.asm16
-rw-r--r--utils/Makefile3
-rwxr-xr-xutils/pxelinux-options499
79 files changed, 3029 insertions, 1842 deletions
diff --git a/MCONFIG b/MCONFIG
index b5c2dd4b..0d70a33e 100644
--- a/MCONFIG
+++ b/MCONFIG
@@ -54,6 +54,9 @@ NM = nm
RANLIB = ranlib
GZIPPROG = gzip
PNGTOPNM = pngtopnm
+MCOPY = mcopy
+MFORMAT = mformat
+MKISOFS = mkisofs
com32 = $(topdir)/com32
diff --git a/NEWS b/NEWS
index 594cf755..c934a3e3 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,13 @@ Changes in 3.83:
* Simple menu: fix Ctrl-W (word erase) in command-line edit.
* Simple menu: fix crash on some platforms.
* Gfxboot: fixes to the configuration file parsing.
+ * PXELINUX: add a tool to override specific DHCP options via
+ values hardcoded in the pxelinux.0 file. These hardcoded
+ values can be either "before DHCP" (defaults if DHCP do not
+ provide values), or "after DHCP" (overrides DHCP). The tool
+ pxelinux-options can be used to set these options. This
+ feature does not apply to gpxelinux.0; when used with gPXE
+ this is better handled by modifying the embedded script.
Changes in 3.82:
* isohybrid: fix the -partok logic for loading from a partition.
diff --git a/com32/cmenu/adv_menu.tpl b/com32/cmenu/adv_menu.tpl
index 6ce4acf8..be3c558e 100644
--- a/com32/cmenu/adv_menu.tpl
+++ b/com32/cmenu/adv_menu.tpl
@@ -40,6 +40,7 @@ modify this template to suit your needs
#include "com32io.h"
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
#define MAX_CMD_LINE_LENGTH 514
@@ -192,51 +193,61 @@ TIMEOUTCODE ontotaltimeout()
return timeout(totaltimeoutcmd);
}
-void keys_handler(t_menusystem *ms, t_menuitem *mi,unsigned int scancode)
+void keys_handler(t_menusystem * ms __attribute__ (( unused )), t_menuitem * mi, int scancode)
{
- char nc;
+ int nc, nr;
- if ( ((scancode >> 8) == F1) && (mi->helpid != 0xFFFF) ) { // If scancode of F1 and non-trivial helpid
+ if (getscreensize(1, &nr, &nc)) {
+ /* Unknown screen size? */
+ nc = 80;
+ nr = 24;
+ }
+
+ if ( (scancode == KEY_F1) && (mi->helpid != 0xFFFF) ) { // If scancode of F1 and non-trivial helpid
runhelpsystem(mi->helpid);
}
// If user hit TAB, and item is an "executable" item
// and user has privileges to edit it, edit it in place.
- if (((scancode & 0xFF) == 0x09) && (mi->action == OPT_RUN) &&
- (EDIT_ROW < getnumrows()) && (EDIT_ROW > 0) &&
+ if ((scancode == KEY_TAB) && (mi->action == OPT_RUN) &&
+ (EDIT_ROW < nr) && (EDIT_ROW > 0) &&
(isallowed(username,"editcmd") || isallowed(username,"root"))) {
- nc = getnumcols();
// User typed TAB and has permissions to edit command line
- gotoxy(EDIT_ROW,1,ms->menupage);
+ gotoxy(EDIT_ROW,1);
csprint("Command line:",0x07);
editstring(mi->data,ACTIONLEN);
- gotoxy(EDIT_ROW,1,ms->menupage);
- cprint(' ',0x07,nc-1,ms->menupage);
+ gotoxy(EDIT_ROW,1);
+ cprint(' ',0x07,nc-1);
}
}
-t_handler_return login_handler(t_menusystem *ms, t_menuitem *mi)
+t_handler_return login_handler(t_menuitem *mi)
{
(void)mi; // Unused
char pwd[40];
char login[40];
- char nc;
+ int nc, nr;
t_handler_return rv;
rv = ACTION_INVALID;
if (PWD_ROW < 0) return rv; // No need to authenticate
if (mi->item == loginstr) { /* User wants to login */
- nc = getnumcols();
- gotoxy(PWD_ROW,1,ms->menupage);
+ if (getscreensize(1, &nr, &nc)) {
+ /* Unknown screen size? */
+ nc = 80;
+ nr = 24;
+ }
+
+ gotoxy(PWD_ROW,1);
csprint("Enter Username: ",0x07);
getstring(login, sizeof username);
- gotoxy(PWD_ROW,1,ms->menupage);
- cprint(' ',0x07,nc,ms->menupage);
+ gotoxy(PWD_ROW,1);
+ cprint(' ',0x07,nc);
csprint("Enter Password: ",0x07);
getpwd(pwd, sizeof pwd);
- gotoxy(PWD_ROW,1,ms->menupage);
- cprint(' ',0x07,nc,ms->menupage);
+ gotoxy(PWD_ROW,1);
+ cprint(' ',0x07,nc);
if (authenticate_user(login,pwd))
{
diff --git a/com32/cmenu/complex.c b/com32/cmenu/complex.c
index 063125d6..1ac51997 100644
--- a/com32/cmenu/complex.c
+++ b/com32/cmenu/complex.c
@@ -21,6 +21,8 @@
#include "des.h"
#include <stdlib.h>
#include <stdio.h>
+#include <unistd.h>
+#include <getkey.h>
/* Global variables */
char infoline[160];
@@ -65,46 +67,54 @@ TIMEOUTCODE ontimeout()
#define PWDATTR 0x74
#define EDITPROMPT 21
-void keys_handler(t_menusystem * ms, t_menuitem * mi, unsigned int scancode)
+void keys_handler(t_menusystem * ms __attribute__ (( unused )), t_menuitem * mi, int scancode)
{
- char nc;
+ int nc, nr;
- if ((scancode >> 8) == F1) { // If scancode of F1
+ if ((scancode) == KEY_F1 && mi->helpid != 0xFFFF) { // If scancode of F1
runhelpsystem(mi->helpid);
}
// If user hit TAB, and item is an "executable" item
// and user has privileges to edit it, edit it in place.
- if (((scancode & 0xFF) == 0x09) && (mi->action == OPT_RUN) &&
+ if ((scancode == KEY_TAB) && (mi->action == OPT_RUN) &&
(isallowed(username, "editcmd") || isallowed(username, "root"))) {
- nc = getnumcols();
+ if (getscreensize(1, &nr, &nc)) {
+ /* Unknown screen size? */
+ nc = 80;
+ nr = 24;
+ }
// User typed TAB and has permissions to edit command line
- gotoxy(EDITPROMPT, 1, ms->menupage);
+ gotoxy(EDITPROMPT, 1);
csprint("Command line:", 0x07);
editstring(mi->data, ACTIONLEN);
- gotoxy(EDITPROMPT, 1, ms->menupage);
- cprint(' ', 0x07, nc - 1, ms->menupage);
+ gotoxy(EDITPROMPT, 1);
+ clear_line();
}
}
-t_handler_return login_handler(t_menusystem * ms, t_menuitem * mi)
+t_handler_return login_handler(t_menuitem * mi)
{
(void)mi; // Unused
char pwd[40];
char login[40];
- char nc;
+ int nc, nr;
t_handler_return rv;
if (mi->item == loginstr) { /* User wants to login */
- nc = getnumcols();
- gotoxy(PWDPROMPT, 1, ms->menupage);
+ if (getscreensize(1, &nr, &nc)) {
+ /* Unknown screen size? */
+ nc = 80;
+ nr = 24;
+ }
+ gotoxy(PWDPROMPT, 1);
csprint("Enter Username: ", 0x07);
getstring(login, sizeof username);
- gotoxy(PWDPROMPT, 1, ms->menupage);
- cprint(' ', 0x07, nc, ms->menupage);
+ gotoxy(PWDPROMPT, 1);
+ clear_line();
csprint("Enter Password: ", 0x07);
getpwd(pwd, sizeof pwd);
- gotoxy(PWDPROMPT, 1, ms->menupage);
- cprint(' ', 0x07, nc, ms->menupage);
+ gotoxy(PWDPROMPT, 1);
+ clear_line();
if (authenticate_user(login, pwd)) {
strcpy(username, login);
@@ -133,22 +143,27 @@ t_handler_return login_handler(t_menusystem * ms, t_menuitem * mi)
void msys_handler(t_menusystem * ms, t_menuitem * mi)
{
- char nc;
+ int nc, nr;
void *v;
- nc = getnumcols(); // Get number of columns
- gotoxy(PWDLINE, PWDCOLUMN, ms->menupage);
+ if (getscreensize(1, &nr, &nc)) {
+ /* Unknown screen size? */
+ nc = 80;
+ nr = 24;
+ }
+ gotoxy(PWDLINE, PWDCOLUMN);
csprint("User: ", PWDATTR);
- cprint(ms->fillchar, ms->fillattr, sizeof username, ms->menupage);
- gotoxy(PWDLINE, PWDCOLUMN + 6, ms->menupage);
+ cprint(ms->fillchar, ms->fillattr, sizeof username);
+ gotoxy(PWDLINE, PWDCOLUMN + 6);
csprint(username, PWDATTR);
if (mi->parindex != PREPMENU) // If we are not in the PREP MENU
{
- gotoxy(INFLINE, 0, ms->menupage);
- cprint(' ', 0x07, nc, ms->menupage);
- gotoxy(INFLINE + 1, 0, ms->menupage);
- cprint(' ', 0x07, nc, ms->menupage);
+ gotoxy(INFLINE, 0);
+ reset_colors();
+ clear_line();
+ gotoxy(INFLINE + 1, 0);
+ clear_line();
return;
}
strcpy(infoline, " ");
@@ -167,13 +182,14 @@ void msys_handler(t_menusystem * ms, t_menuitem * mi)
if (flags.linrep)
strcat(infoline, "repair=lin ");
- gotoxy(INFLINE, 0, ms->menupage);
- cprint(' ', 0x07, nc, ms->menupage);
- gotoxy(INFLINE + 1, 0, ms->menupage);
- cprint(' ', 0x07, nc, ms->menupage);
- gotoxy(INFLINE, 0, ms->menupage);
+ gotoxy(INFLINE, 0);
+ reset_colors();
+ clear_line();
+ gotoxy(INFLINE + 1, 0);
+ clear_line();
+ gotoxy(INFLINE, 0);
csprint("Kernel Arguments:", 0x07);
- gotoxy(INFLINE, 17, ms->menupage);
+ gotoxy(INFLINE, 17);
csprint(infoline, 0x07);
}
@@ -195,6 +211,8 @@ t_handler_return checkbox_handler(t_menusystem * ms, t_menuitem * mi)
{
(void)ms; /* Unused */
+ t_handler_return rv;
+
if (mi->action != OPT_CHECKBOX)
return ACTION_INVALID;
@@ -220,26 +238,10 @@ t_handler_return checkbox_handler(t_menusystem * ms, t_menuitem * mi)
}
if (strcmp(mi->data, "mountcd") == 0)
flags.mountcd = (mi->itemdata.checked ? 1 : 0);
- return ACTION_VALID;
-}
-/*
- Clears keyboard buffer and then
- wait for stepsize*numsteps milliseconds for user to press any key
- checks for keypress every stepsize milliseconds.
- Returns: 1 if user pressed a key (not read from the buffer),
- 0 if time elapsed
-*/
-int checkkeypress(int stepsize, int numsteps)
-{
- int i;
- clearkbdbuf();
- for (i = 0; i < numsteps; i++) {
- if (checkkbdbuf())
- return 1;
- sleep(stepsize);
- }
- return 0;
+ rv.valid = 0;
+ rv.refresh = 1;
+ return rv;
}
int main()
@@ -271,7 +273,7 @@ int main()
reg_handler(HDLR_SCREEN, &msys_handler);
reg_handler(HDLR_KEYS, &keys_handler);
// Register the ontimeout handler, with a time out of 10 seconds
- reg_ontimeout(ontimeout, 1000, 0);
+ reg_ontimeout(ontimeout, 10, 0);
NETMENU = add_menu(" Init Network ", -1);
none = add_item("<N>one", "Dont start network", OPT_RADIOITEM, "no ", 0);
@@ -401,12 +403,11 @@ int main()
0);
set_item_options(-1, 30);
csprint("Press any key within 5 seconds to show menu...", 0x07);
- if (!checkkeypress(100, 50)) // Granularity of 100 milliseconds
+ if (get_key(stdin, 50) == KEY_NONE) // Granularity of 100 milliseconds
{
csprint("Sorry! Time's up.\r\n", 0x07);
return 1;
- } else
- clearkbdbuf(); // Just in case user pressed something important
+ }
curr = showmenus(MAIN);
if (curr) {
if (curr->action == OPT_RUN) {
diff --git a/com32/cmenu/libmenu/com32io.c b/com32/cmenu/libmenu/com32io.c
index d99eb87f..6a27d1a1 100644
--- a/com32/cmenu/libmenu/com32io.c
+++ b/com32/cmenu/libmenu/com32io.c
@@ -13,35 +13,11 @@
#include <string.h>
#include <com32.h>
#include "com32io.h"
+#include "tui.h"
#include "syslnx.h"
com32sys_t inreg, outreg; // Global register sets for use
-/* Print character and attribute at cursor */
-void cprint(char chr, char attr, unsigned int times, char disppage)
-{
- REG_AH(inreg) = 0x09;
- REG_AL(inreg) = chr;
- REG_BH(inreg) = disppage;
- REG_BL(inreg) = attr;
- REG_CX(inreg) = times;
- __intcall(0x10, &inreg, &outreg);
-}
-
-void setdisppage(char num) // Set the display page to specified number
-{
- REG_AH(inreg) = 0x05;
- REG_AL(inreg) = num;
- __intcall(0x10, &inreg, &outreg);
-}
-
-char getdisppage() // Get current display page
-{
- REG_AH(inreg) = 0x0f;
- __intcall(0x10, &inreg, &outreg);
- return REG_BH(outreg);
-}
-
void getpos(char *row, char *col, char page)
{
REG_AH(inreg) = 0x03;
@@ -51,14 +27,6 @@ void getpos(char *row, char *col, char page)
*col = REG_DL(outreg);
}
-void gotoxy(char row, char col, char page)
-{
- REG_AH(inreg) = 0x02;
- REG_BH(inreg) = page;
- REG_DX(inreg) = (row << 8) + col;
- __intcall(0x10, &inreg, &outreg);
-}
-
unsigned char sleep(unsigned int msec)
{
unsigned long micro = 1000 * msec;
@@ -70,25 +38,6 @@ unsigned char sleep(unsigned int msec)
return REG_AH(outreg);
}
-void beep()
-{
- REG_AH(inreg) = 0x0E;
- REG_AL(inreg) = 0x07;
- REG_BH(inreg) = 0;
- __intcall(0x10, &inreg, &outreg);
-}
-
-void scrollupwindow(char top, char left, char bot, char right, char attr,
- char numlines)
-{
- REG_AH(inreg) = 0x06;
- REG_AL(inreg) = numlines;
- REG_BH(inreg) = attr; // Attribute to write blanks lines
- REG_DX(inreg) = (bot << 8) + right; // BOT RIGHT corner of window
- REG_CX(inreg) = (top << 8) + left; // TOP LEFT of window
- __intcall(0x10, &inreg, &outreg);
-}
-
char inputc(char *scancode)
{
syslinux_idle(); /* So syslinux can perform periodic activity */
@@ -101,7 +50,7 @@ char inputc(char *scancode)
void getcursorshape(char *start, char *end)
{
- char page = getdisppage();
+ char page = 0; // XXX TODO
REG_AH(inreg) = 0x03;
REG_BH(inreg) = page;
__intcall(0x10, &inreg, &outreg);
@@ -117,13 +66,6 @@ void setcursorshape(char start, char end)
__intcall(0x10, &inreg, &outreg);
}
-char getchar(void)
-{
- REG_AH(inreg) = 0x08;
- __intcall(0x21, &inreg, &outreg);
- return REG_AL(outreg);
-}
-
void setvideomode(char mode)
{
REG_AH(inreg) = 0x00;
@@ -131,13 +73,6 @@ void setvideomode(char mode)
__intcall(0x10, &inreg, &outreg);
}
-unsigned char checkkbdbuf()
-{
- REG_AH(inreg) = 0x11;
- __intcall(0x16, &inreg, &outreg);
- return !(outreg.eflags.l & EFLAGS_ZF);
-}
-
// Get char displayed at current position
unsigned char getcharat(char page)
{
diff --git a/com32/cmenu/libmenu/com32io.h b/com32/cmenu/libmenu/com32io.h
index cdaf0a84..6ff6857e 100644
--- a/com32/cmenu/libmenu/com32io.h
+++ b/com32/cmenu/libmenu/com32io.h
@@ -14,71 +14,41 @@
#define __COM32IO_H__
#include <com32.h>
+#include <stdio.h>
+#include <libansi.h>
#ifndef NULL
#define NULL ((void *)0)
#endif
-/* BIOS Assisted output routines */
-
-void cswprint(const char *str, char attr, char left);
-// Print a C str (NUL-terminated) respecting the left edge of window
-// i.e. \n in str will move cursor to column left
-// Print a C str (NUL-terminated)
-
-static inline void csprint(const char *str, char attr)
-{
- cswprint(str, attr, 0);
-}
-
-void cprint(char chr, char attr, unsigned int times, char disppage); // Print a char
+/* Bits representing ShiftFlags, See Int16/Function 2 or Mem[0x417] to get this info */
-void setdisppage(char num); // Set the display page to specified number
+#define INSERT_ON (1<<7)
+#define CAPSLOCK_ON (1<<6)
+#define NUMLOCK_ON (1<<5)
+#define SCRLLOCK_ON (1<<4)
+#define ALT_PRESSED (1<<3)
+#define CTRL_PRESSED (1<<2)
+// actually 1<<1 is Left Shift, 1<<0 is right shift
+#define SHIFT_PRESSED (1<<1 | 1 <<0)
-char getdisppage(); // Get current display page
-
-void gotoxy(char row, char col, char page);
+/* BIOS Assisted output routines */
void getpos(char *row, char *col, char page);
char inputc(char *scancode); // Return ASCII char by val, and scancode by reference
-static inline void putch(char x, char attr, char page)
-{
- cprint(x, attr, 1, page);
-}
-
void setcursorshape(char start, char end); // Set cursor shape
void getcursorshape(char *start, char *end); // Get shape for current page
// Get char displayed at current position in specified page
unsigned char getcharat(char page);
-static inline void cursoroff(void)
-{ /* Turns off cursor */
- setcursorshape(32, 33);
-}
-
-static inline void cursoron(void)
-{ /* Turns on cursor */
- setcursorshape(6, 7);
-}
-
static inline unsigned char readbiosb(unsigned int ofs)
{
return *((unsigned char *)MK_PTR(0, ofs));
}
-static inline char getnumrows()
-{
- return readbiosb(0x484)+1; // Actually numrows - 1
-}
-
-static inline char getnumcols(void)
-{
- return readbiosb(0x44a); // Actually numcols
-}
-
static inline char getshiftflags(void)
{
return readbiosb(0x417);
@@ -86,11 +56,6 @@ static inline char getshiftflags(void)
void scrollupwindow(char top, char left, char bot, char right, char attr, char numlines); //Scroll up given window
-static inline void scrollup(void) //Scroll up display screen by one line
-{
- scrollupwindow(0, 0, getnumrows(), getnumcols(), 0x07, 1);
-}
-
void setvideomode(char mode); // Set the video mode.
static inline char getvideomode(void) // Get the current video mode
@@ -100,14 +65,4 @@ static inline char getvideomode(void) // Get the current video mode
unsigned char sleep(unsigned int msec); // Sleep for specified time
-void beep(); // A Bell
-
-unsigned char checkkbdbuf(); // Check to see if there is kbd buffer is non-empty?
-
-static inline void clearkbdbuf() // Clear the kbd buffer (how many chars removed?)
-{
- while (checkkbdbuf())
- inputc(NULL);
-}
-
#endif
diff --git a/com32/cmenu/libmenu/help.c b/com32/cmenu/libmenu/help.c
index a635bd21..0df1e103 100644
--- a/com32/cmenu/libmenu/help.c
+++ b/com32/cmenu/libmenu/help.c
@@ -16,10 +16,11 @@
#include "com32io.h"
#include <syslinux/loadfile.h> // to read entire file into memory
+int nc, nr; // Number of columns/rows of the screen
char helpbasedir[HELPDIRLEN]; // name of help directory limited to HELPDIRLEN
// Find the occurence of the count'th \n in buffer (or NULL) if not found
-char *findline(char *buffer, int count)
+static char *findline(char *buffer, int count)
{
int ctr;
char *p = buffer - 1;
@@ -35,7 +36,7 @@ char *findline(char *buffer, int count)
}
// return the number of lines in buffer
-int countlines(char *buffer)
+static int countlines(char *buffer)
{
int ans;
const char *p;
@@ -50,34 +51,45 @@ int countlines(char *buffer)
}
// Print numlines of text starting from buf
-void printtext(char *buf, int from)
+static void printtext(char *buf, int from)
{
- char *p, *f;
- char right, bot, nlines;
+ char *f, *t;
+ int right, nlines, i;
// clear window to print
- right = getnumcols() - HELP_RIGHT_MARGIN;
- bot = getnumrows() - HELP_BOTTOM_MARGIN;
- nlines = bot - HELP_BODY_ROW + 1;
- scrollupwindow(HELP_BODY_ROW, HELP_LEFT_MARGIN, bot, right, 0x07, nlines);
+ right = nc - HELP_RIGHT_MARGIN;
+ nlines = nr - HELP_BODY_ROW - HELP_BOTTOM_MARGIN - 1;
f = findline(buf, from);
if (!f)
return; // nothing to print
if (*f == '\n')
f++; // start of from+1st line
- p = findline(f, nlines);
- if (p && (*p == '\n'))
- *p = '\0'; // change to NUL
- gotoxy(HELP_BODY_ROW, HELP_LEFT_MARGIN, HELPPAGE);
- cswprint(f, 0x07, HELP_LEFT_MARGIN);
- if (p)
- *p = '\n'; // set it back
+ t = f;
+ while (i < nlines) {
+ gotoxy(HELP_BODY_ROW + i, HELP_LEFT_MARGIN);
+ clear_end_of_line();
+ putchar(SO);
+ gotoxy(HELP_BODY_ROW + i, nc - 1);
+ putch(LEFT_BORDER, 0x07);
+ putchar(SI);
+
+ gotoxy(HELP_BODY_ROW + i, HELP_LEFT_MARGIN);
+ while (*t != '\n') {
+ if (*t == '\0')
+ return;
+ putchar(*t);
+ t++;
+ }
+ putchar('\n');
+ t++;
+ i++;
+ }
}
void showhelp(const char *filename)
{
- char nc, nr, ph;
+ char ph;
char *title, *text;
union {
char *buffer;
@@ -86,41 +98,29 @@ void showhelp(const char *filename)
char line[512];
size_t size;
- char scan;
+ int scan;
int rv, numlines, curr_line;
- nc = getnumcols();
- nr = getnumrows();
- ph = nr - HELP_BOTTOM_MARGIN - HELP_BODY_ROW - 1;
+ if (getscreensize(1, &nr, &nc)) {
+ /* Unknown screen size? */
+ nc = 80;
+ nr = 24;
+ }
+ ph = nr - HELP_BODY_ROW;
cls();
- drawbox(0, 0, nr, nc - 1, HELPPAGE, 0x07, HELPBOX);
- drawhorizline(2, 0, nc - 1, HELPPAGE, 0x07, HELPBOX, 0); // dumb==0
+ /* Turn autowrap off, to avoid scrolling the menu */
+ printf(CSI "?7l");
+
if (filename == NULL) { // print file contents
- gotoxy(HELP_BODY_ROW, HELP_LEFT_MARGIN, HELPPAGE);
- cswprint("Filename not given", 0x07, HELP_LEFT_MARGIN);
- while (1) {
- inputc(&scan);
- if (scan == ESCAPE)
- break;
- }
- cls();
- return;
+ strcpy(line, "Filename not given");
+ goto puke;
}
rv = loadfile(filename, (void **)&buf.vbuf, &size); // load entire file into memory
if (rv < 0) { // Error reading file or no such file
- sprintf(line, "Error reading file or file not found\n file=%s",
- filename);
- gotoxy(HELP_BODY_ROW, HELP_LEFT_MARGIN, HELPPAGE);
- cswprint(line, 0x07, HELP_LEFT_MARGIN);
- while (1) {
- inputc(&scan);
- if (scan == ESCAPE)
- break;
- }
- cls();
- return;
+ sprintf(line, "Error reading file or file not found\n file=%s", filename);
+ goto puke;
}
title = buf.buffer;
@@ -128,44 +128,49 @@ void showhelp(const char *filename)
*text++ = '\0'; // end the title string and increment text
// Now we have a file just print it.
- gotoxy(1, (nc - strlen(title)) / 2, HELPPAGE);
- csprint(title, 0x07);
numlines = countlines(text);
curr_line = 0;
- scan = ESCAPE + 1; // anything except ESCAPE
-
- while (scan != ESCAPE) {
+ scan = KEY_ESC + 1; // anything except ESCAPE
+
+ /* top, left, bottom, right, attr */
+ drawbox(0, 0, nr - 1, nc - 1, 0x07);
+ while (scan != KEY_ESC) {
+ /* Title */
+ gotoxy(1, (nc - strlen(title)) / 2);
+ fputs(title, stdout);
+ drawhorizline(2, HELP_LEFT_MARGIN - 1, nc - HELP_RIGHT_MARGIN, 0x07, 0); // dumb==0
+ /* Text */
printtext(text, curr_line);
- gotoxy(HELP_BODY_ROW - 1, nc - HELP_RIGHT_MARGIN, HELPPAGE);
+ gotoxy(HELP_BODY_ROW - 1, nc - HELP_RIGHT_MARGIN);
if (curr_line > 0)
- putch(HELP_MORE_ABOVE, 0x07, HELPPAGE);
+ putchar(HELP_MORE_ABOVE);
else
- putch(' ', 0x07, HELPPAGE);
- gotoxy(nr - HELP_BOTTOM_MARGIN + 1, nc - HELP_RIGHT_MARGIN, HELPPAGE);
+ putchar(' ');
+ gotoxy(nr - HELP_BOTTOM_MARGIN - 1, nc - HELP_RIGHT_MARGIN);
if (curr_line < numlines - ph)
- putch(HELP_MORE_BELOW, 0x07, HELPPAGE);
+ putchar(HELP_MORE_BELOW);
else
- putch(' ', 0x07, HELPPAGE);
+ putchar(' ');
- inputc(&scan); // wait for user keypress
+ scan = get_key(stdout, 0); // wait for user keypress
switch (scan) {
- case HOMEKEY:
+ case KEY_HOME:
curr_line = 0;
break;
- case ENDKEY:
+ case KEY_END:
curr_line = numlines;
break;
- case UPARROW:
+ case KEY_UP:
curr_line--;
break;
- case DNARROW:
+ case KEY_DOWN:
curr_line++;
break;
- case PAGEUP:
+ case KEY_PGUP:
curr_line -= ph;
break;
- case PAGEDN:
+ case KEY_PGDN:
curr_line += ph;
break;
default:
@@ -176,18 +181,26 @@ void showhelp(const char *filename)
if (curr_line < 0)
curr_line = 0;
}
+out:
cls();
return;
+
+puke:
+ gotoxy(HELP_BODY_ROW, HELP_LEFT_MARGIN);
+ fputs(line, stdout);
+ while (1) {
+ scan = get_key(stdin, 0);
+ if (scan == KEY_ESC)
+ break;
+ }
+ goto out;
}
void runhelp(const char *filename)
{
- char dp;
char fullname[HELPDIRLEN + 16];
- dp = getdisppage();
- if (dp != HELPPAGE)
- setdisppage(HELPPAGE);
+ cls();
cursoroff();
if (helpbasedir[0] != 0) {
strcpy(fullname, helpbasedir);
@@ -196,15 +209,13 @@ void runhelp(const char *filename)
showhelp(fullname);
} else
showhelp(filename); // Assume filename is absolute
- if (dp != HELPPAGE)
- setdisppage(dp);
}
void runhelpsystem(unsigned int helpid)
{
char filename[15];
- sprintf(filename, "hlp%5d.txt", helpid);
+ sprintf(filename, "hlp%05d.txt", helpid);
runhelp(filename);
}
diff --git a/com32/cmenu/libmenu/help.h b/com32/cmenu/libmenu/help.h
index 0fff524f..de01b46e 100644
--- a/com32/cmenu/libmenu/help.h
+++ b/com32/cmenu/libmenu/help.h
@@ -23,14 +23,14 @@
#define HELP_BODY_ROW (HELP_TITLE_HEIGHT+3)
#define HELP_LEFT_MARGIN 2
#define HELP_RIGHT_MARGIN 2 // Assume all lines dont cross this
-#define HELP_BOTTOM_MARGIN 2 // Number of lines not use from bottom of screen
+#define HELP_BOTTOM_MARGIN 1 // Number of lines not use from bottom of screen
#define HELPBOX BOX_SINSIN
#define HELPDIRLEN 64
#define HELPPAGE 2
-#define HELP_MORE_ABOVE 24 // to print when more is available above
-#define HELP_MORE_BELOW 25 // same as above but for below
+#define HELP_MORE_ABOVE '^' // to print when more is available above
+#define HELP_MORE_BELOW 'v' // same as above but for below
// Display one screen of help information
void showhelp(const char *filename);
diff --git a/com32/cmenu/libmenu/menu.c b/com32/cmenu/libmenu/menu.c
index cfe8f39f..de4a1ee2 100644
--- a/com32/cmenu/libmenu/menu.c
+++ b/com32/cmenu/libmenu/menu.c
@@ -13,9 +13,10 @@
#include "menu.h"
#include "com32io.h"
#include <stdlib.h>
+#include <console.h>
// Local Variables
-static pt_menusystem ms; // Pointer to the menusystem
+static pt_menusystem ms; // Pointer to the menusystem
char TITLESTR[] =
"COMBOOT Menu System for SYSLINUX developed by Murali Krishnan Ganapathy";
char TITLELONG[] = " TITLE too long ";
@@ -39,92 +40,45 @@ int isvisible(pt_menu menu, int first, int curr);
// This is same as inputc except it honors the ontimeout handler
// and calls it when needed. For the callee, there is no difference
// as this will not return unless a key has been pressed.
-char getch(char *scan)
+static int getch()
{
- unsigned long i;
- TIMEOUTCODE c;
t_timeout_handler th;
+ int key;
+ unsigned long i;
// Wait until keypress if no handler specified
if ((ms->ontimeout == NULL) && (ms->ontotaltimeout == NULL))
- return inputc(scan);
+ return get_key(stdin, 0);
th = ms->ontimeout;
- while (1) // Forever do
- {
- for (i = 0; i < ms->tm_numsteps; i++) {
- if (checkkbdbuf())
- return inputc(scan);
- sleep(ms->tm_stepsize);
- if ((ms->tm_total_timeout == 0) || (ms->ontotaltimeout == NULL))
- continue; // Dont bother with calculations if no handler
- ms->tm_sofar_timeout += ms->tm_stepsize;
- if (ms->tm_sofar_timeout >= ms->tm_total_timeout) {
- th = ms->ontotaltimeout;
- ms->tm_sofar_timeout = 0;
- break; // Get out of the for loop
- }
- }
- if (!th)
- continue; // no handler dont call
- c = th();
- switch (c) {
- case CODE_ENTER: // Pretend user hit enter
- *scan = ENTERA;
- return '\015'; // \015 octal = 13
- case CODE_ESCAPE: // Pretend user hit escape
- *scan = ESCAPE;
- return '\033'; // \033 octal = 27
- default:
- break;
- }
- }
- return 0;
-}
-
-/* Print a menu item */
-/* attr[0] is non-hilite attr, attr[1] is highlight attr */
-void printmenuitem(const char *str, uchar * attr)
-{
- uchar page = getdisppage();
- uchar row, col;
- int hlite = NOHLITE; // Initially no highlighting
-
- getpos(&row, &col, page);
- while (*str) {
- switch (*str) {
- case '\b':
- --col;
- break;
- case '\n':
- ++row;
- break;
- case '\r':
- col = 0;
- break;
- case BELL: // No Bell Char
- break;
- case ENABLEHLITE: // Switch on highlighting
- hlite = HLITE;
- break;
- case DISABLEHLITE: // Turn off highlighting
- hlite = NOHLITE;
- break;
- default:
- putch(*str, attr[hlite], page);
- ++col;
- }
- if (col > getnumcols()) {
- ++row;
- col = 0;
- }
- if (row > getnumrows()) {
- scrollup();
- row = getnumrows();
- }
- gotoxy(row, col, page);
- str++;
+ for (;;) {
+ for (i = 0; i < ms->tm_numsteps; i++) {
+ key = get_key(stdin, ms->tm_stepsize);
+ if (key != KEY_NONE)
+ return key;
+
+ if ((ms->tm_total_timeout == 0) || (ms->ontotaltimeout == NULL))
+ continue; // Dont bother with calculations if no handler
+ ms->tm_sofar_timeout += ms->tm_stepsize;
+ if (ms->tm_sofar_timeout >= ms->tm_total_timeout) {
+ th = ms->ontotaltimeout;
+ ms->tm_sofar_timeout = 0;
+ break; // Get out of the for loop
+ }
+ }
+ if (!th)
+ continue; // no handler
+ key = th();
+ switch (key) {
+ case CODE_ENTER: // Pretend user hit enter
+ return KEY_ENTER;
+ case CODE_ESCAPE: // Pretend user hit escape
+ return KEY_ESC;
+ default:
+ break;
+ }
}
+ return KEY_NONE;
}
int find_shortcut(pt_menu menu, uchar shortcut, int index)
@@ -135,481 +89,427 @@ int find_shortcut(pt_menu menu, uchar shortcut, int index)
// Garbage in garbage out
if ((index < 0) || (index >= menu->numitems))
- return index;
+ return index;
ans = index + 1;
// Go till end of menu
while (ans < menu->numitems) {
- mi = menu->items[ans];
- if ((mi->action == OPT_INVISIBLE) || (mi->action == OPT_SEP)
- || (mi->shortcut != shortcut))
- ans++;
- else
- return ans;
+ mi = menu->items[ans];
+ if ((mi->action == OPT_INVISIBLE) || (mi->action == OPT_SEP)
+ || (mi->shortcut != shortcut))
+ ans++;
+ else
+ return ans;
}
// Start at the beginning and try again
ans = 0;
while (ans < index) {
- mi = menu->items[ans];
- if ((mi->action == OPT_INVISIBLE) || (mi->action == OPT_SEP)
- || (mi->shortcut != shortcut))
- ans++;
- else
- return ans;
+ mi = menu->items[ans];
+ if ((mi->action == OPT_INVISIBLE) || (mi->action == OPT_SEP)
+ || (mi->shortcut != shortcut))
+ ans++;
+ else
+ return ans;
}
- return index; // Sorry not found
+ return index; // Sorry not found
}
-// print the menu starting from FIRST
-// will print a maximum of menu->menuheight items
-void printmenu(pt_menu menu, int curr, uchar top, uchar left, uchar first)
+/* Redraw background and title */
+static void reset_ui(void)
+{
+ uchar tpos;
+
+ cls();
+ clearwindow(ms->minrow, ms->mincol, ms->maxrow, ms->maxcol,
+ ms->fillchar, ms->fillattr);
+
+ tpos = (ms->numcols - strlen(ms->title) - 1) >> 1; // center it on line
+ gotoxy(ms->minrow, ms->mincol);
+ cprint(ms->tfillchar, ms->titleattr, ms->numcols);
+ gotoxy(ms->minrow, ms->mincol + tpos);
+ csprint(ms->title, ms->titleattr);
+
+ cursoroff();
+}
+
+/*
+ * Print a menu item
+ *
+ * attr[0] is non-hilite attr, attr[1] is highlight attr
+ */
+void printmenuitem(const char *str, uchar * attr)
+{
+ int hlite = NOHLITE; // Initially no highlighting
+
+ while (*str) {
+ switch (*str) {
+ case BELL: // No Bell Char
+ break;
+ case ENABLEHLITE: // Switch on highlighting
+ hlite = HLITE;
+ break;
+ case DISABLEHLITE: // Turn off highlighting
+ hlite = NOHLITE;
+ break;
+ default:
+ putch(*str, attr[hlite]);
+ }
+ str++;
+ }
+}
+
+
+/**
+ * print_line - Print a whole line in a menu
+ * @menu: current menu to handle
+ * @curr: index of the current entry highlighted
+ * @top: top coordinate of the @menu
+ * @left: left coordinate of the @menu
+ * @x: index in the menu of curr
+ * @row: row currently displayed
+ * @radio: radio item?
+ **/
+static void print_line(pt_menu menu, int curr, uchar top, uchar left,
+ int x, int row, bool radio)
{
- int x, row; // x = index, row = position from top
- int numitems, menuwidth;
- char fchar[5], lchar[5]; // The first and last char in for each entry
- const char *str; // and inbetween the item or a seperator is printed
- uchar *attr; // attribute attr
- char sep[MENULEN]; // and inbetween the item or a seperator is printed
pt_menuitem ci;
+ char fchar[6], lchar[6]; // The first and last char in for each entry
+ const char *str; // Item string (cf printmenuitem)
+ char sep[MENULEN]; // Separator (OPT_SEP)
+ uchar *attr; // Attribute
+ int menuwidth = menu->menuwidth + 3;
- numitems = calc_visible(menu, first);
- if (numitems > menu->menuheight)
- numitems = menu->menuheight;
+ if (row >= menu->menuheight)
+ return;
- menuwidth = menu->menuwidth + 3;
- clearwindow(top, left - 2, top + numitems + 1, left + menuwidth + 1,
- ms->menupage, ms->fillchar, ms->shadowattr);
- drawbox(top - 1, left - 3, top + numitems, left + menuwidth,
- ms->menupage, ms->normalattr[NOHLITE], ms->menubt);
- memset(sep, ms->box_horiz, menuwidth); // String containing the seperator string
+ ci = menu->items[x];
+
+ memset(sep, ms->box_horiz, menuwidth);
sep[menuwidth - 1] = 0;
- // Menu title
- x = (menuwidth - strlen(menu->title) - 1) >> 1;
- gotoxy(top - 1, left + x, ms->menupage);
- printmenuitem(menu->title, ms->normalattr);
- row = -1; // 1 less than inital value of x
- for (x = first; x < menu->numitems; x++) {
- ci = menu->items[x];
- if (ci->action == OPT_INVISIBLE)
- continue;
- row++;
- if (row >= numitems)
- break; // Already have enough number of items
- // Setup the defaults now
- lchar[0] = fchar[0] = ' ';
- lchar[1] = fchar[1] = '\0'; // fchar and lchar are just spaces
- str = ci->item; // Pointer to item string
- attr = (x == curr ? ms->reverseattr : ms->normalattr); // Normal attributes
- switch (ci->action) // set up attr,str,fchar,lchar for everything
- {
- case OPT_INACTIVE:
- attr = (x == curr ? ms->revinactattr : ms->inactattr);
- break;
- case OPT_SUBMENU:
- lchar[0] = SUBMENUCHAR;
- lchar[1] = 0;
- break;
- case OPT_RADIOMENU:
- lchar[0] = RADIOMENUCHAR;
- lchar[1] = 0;
- break;
- case OPT_CHECKBOX:
- lchar[0] = (ci->itemdata.checked ? CHECKED : UNCHECKED);
- lchar[1] = 0;
- break;
- case OPT_SEP:
- fchar[0] = '\b';
- fchar[1] = ms->box_ltrt;
- fchar[2] = ms->box_horiz;
- fchar[3] = ms->box_horiz;
- fchar[4] = 0;
- lchar[0] = ms->box_horiz;
- lchar[1] = ms->box_rtlt;
- lchar[2] = 0;
- str = sep;
- break;
- case OPT_EXITMENU:
- fchar[0] = EXITMENUCHAR;
- fchar[1] = 0;
- break;
- default: // Just to keep the compiler happy
- break;
- }
- gotoxy(top + row, left - 2, ms->menupage);
- cprint(ms->spacechar, attr[NOHLITE], menuwidth + 2, ms->menupage); // Wipe area with spaces
- gotoxy(top + row, left - 2, ms->menupage);
- csprint(fchar, attr[NOHLITE]); // Print first part
- gotoxy(top + row, left, ms->menupage);
- printmenuitem(str, attr); // Print main part
- gotoxy(top + row, left + menuwidth - 1, ms->menupage); // Last char if any
- csprint(lchar, attr[NOHLITE]); // Print last part
- }
- // Check if we need to MOREABOVE and MOREBELOW to be added
- // reuse x
- row = 0;
- x = next_visible_sep(menu, 0); // First item
- if (!isvisible(menu, first, x)) // There is more above
- {
- row = 1;
- gotoxy(top, left + menuwidth, ms->menupage);
- cprint(MOREABOVE, ms->normalattr[NOHLITE], 1, ms->menupage);
+
+ // Setup the defaults now
+ if (radio) {
+ fchar[0] = '\b';
+ fchar[1] = SO;
+ fchar[2] = (x == curr ? RADIOSEL : RADIOUNSEL);
+ fchar[3] = SI;
+ fchar[4] = '\0'; // Unselected ( )
+ lchar[0] = '\0'; // Nothing special after
+ attr = ms->normalattr; // Always same attribute
+ } else {
+ lchar[0] = fchar[0] = ' ';
+ lchar[1] = fchar[1] = '\0'; // fchar and lchar are just spaces
+ attr = (x == curr ? ms->reverseattr : ms->normalattr); // Normal attributes
}
- x = prev_visible_sep(menu, menu->numitems); // last item
- if (!isvisible(menu, first, x)) // There is more above
+ str = ci->item; // Pointer to item string
+ switch (ci->action) // set up attr,str,fchar,lchar for everything
{
- row = 1;
- gotoxy(top + numitems - 1, left + menuwidth, ms->menupage);
- cprint(MOREBELOW, ms->normalattr[NOHLITE], 1, ms->menupage);
- }
- // Add a scroll box
- x = ((numitems - 1) * curr) / (menu->numitems);
- if ((x > 0) && (row == 1)) {
- gotoxy(top + x, left + menuwidth, ms->menupage);
- cprint(SCROLLBOX, ms->normalattr[NOHLITE], 1, ms->menupage);
+ case OPT_INACTIVE:
+ if (radio)
+ attr = ms->inactattr;
+ else
+ attr = (x == curr ? ms->revinactattr : ms->inactattr);
+ break;
+ case OPT_SUBMENU:
+ if (radio)
+ break; // Not supported for radio menu
+ lchar[0] = '>';
+ lchar[1] = 0;
+ break;
+ case OPT_RADIOMENU:
+ if (radio)
+ break; // Not supported for radio menu
+ lchar[0] = RADIOMENUCHAR;
+ lchar[1] = 0;
+ break;
+ case OPT_CHECKBOX:
+ if (radio)
+ break; // Not supported for radio menu
+ lchar[0] = '\b';
+ lchar[1] = SO;
+ lchar[2] = (ci->itemdata.checked ? CHECKED : UNCHECKED);
+ lchar[3] = SI;
+ lchar[4] = 0;
+ break;
+ case OPT_SEP:
+ fchar[0] = '\b';
+ fchar[1] = SO;
+ fchar[2] = LEFT_MIDDLE_BORDER;
+ fchar[3] = MIDDLE_BORDER;
+ fchar[4] = MIDDLE_BORDER;
+ fchar[5] = 0;
+ memset(sep, MIDDLE_BORDER, menuwidth);
+ sep[menuwidth - 1] = 0;
+ str = sep;
+ lchar[0] = MIDDLE_BORDER;
+ lchar[1] = RIGHT_MIDDLE_BORDER;
+ lchar[2] = SI;
+ lchar[3] = 0;
+ break;
+ case OPT_EXITMENU:
+ if (radio)
+ break; // Not supported for radio menu
+ fchar[0] = '<';
+ fchar[1] = 0;
+ break;
+ default: // Just to keep the compiler happy
+ break;
}
- if (ms->handler)
- ms->handler(ms, menu->items[curr]);
+
+ // Wipe area with spaces
+ gotoxy(top + row, left - 2);
+ cprint(ms->spacechar, attr[NOHLITE], menuwidth + 2);
+
+ // Print first part
+ gotoxy(top + row, left - 2);
+ csprint(fchar, attr[NOHLITE]);
+
+ // Print main part
+ gotoxy(top + row, left);
+ printmenuitem(str, attr);
+
+ // Print last part
+ gotoxy(top + row, left + menuwidth - 1);
+ csprint(lchar, attr[NOHLITE]);
}
-// Difference between this and regular menu, is that only
-// OPT_INVISIBLE, OPT_SEP are honoured
-void printradiomenu(pt_menu menu, int curr, uchar top, uchar left, int first)
+// print the menu starting from FIRST
+// will print a maximum of menu->menuheight items
+static void printmenu(pt_menu menu, int curr, uchar top, uchar left, uchar first, bool radio)
{
- int x, row; // x = index, row = position from top
+ int x, row; // x = index, row = position from top
int numitems, menuwidth;
- char fchar[5], lchar[5]; // The first and last char in for each entry
- const char *str; // and inbetween the item or a seperator is printed
- uchar *attr; // all in the attribute attr
- char sep[MENULEN]; // and inbetween the item or a seperator is printed
pt_menuitem ci;
numitems = calc_visible(menu, first);
if (numitems > menu->menuheight)
- numitems = menu->menuheight;
+ numitems = menu->menuheight;
menuwidth = menu->menuwidth + 3;
clearwindow(top, left - 2, top + numitems + 1, left + menuwidth + 1,
- ms->menupage, ms->fillchar, ms->shadowattr);
+ ms->fillchar, ms->shadowattr);
drawbox(top - 1, left - 3, top + numitems, left + menuwidth,
- ms->menupage, ms->normalattr[NOHLITE], ms->menubt);
- memset(sep, ms->box_horiz, menuwidth); // String containing the seperator string
- sep[menuwidth - 1] = 0;
+ ms->normalattr[NOHLITE]);
+
// Menu title
x = (menuwidth - strlen(menu->title) - 1) >> 1;
- gotoxy(top - 1, left + x, ms->menupage);
+ gotoxy(top - 1, left + x);
printmenuitem(menu->title, ms->normalattr);
- row = -1; // 1 less than inital value of x
+
+ // All lines in the menu
+ row = -1; // 1 less than inital value of x
for (x = first; x < menu->numitems; x++) {
- ci = menu->items[x];
- if (ci->action == OPT_INVISIBLE)
- continue;
- row++;
- if (row > numitems)
- break;
- // Setup the defaults now
- fchar[0] = RADIOUNSEL;
- fchar[1] = '\0'; // Unselected ( )
- lchar[0] = '\0'; // Nothing special after
- str = ci->item; // Pointer to item string
- attr = ms->normalattr; // Always same attribute
- fchar[0] = (x == curr ? RADIOSEL : RADIOUNSEL);
- switch (ci->action) // set up attr,str,fchar,lchar for everything
- {
- case OPT_INACTIVE:
- attr = ms->inactattr;
- break;
- case OPT_SEP:
- fchar[0] = '\b';
- fchar[1] = ms->box_ltrt;
- fchar[2] = ms->box_horiz;
- fchar[3] = ms->box_horiz;
- fchar[4] = 0;
- lchar[0] = ms->box_horiz;
- lchar[1] = ms->box_rtlt;
- lchar[3] = 0;
- str = sep;
- break;
- default: // To keep the compiler happy
- break;
- }
- gotoxy(top + row, left - 2, ms->menupage);
- cprint(ms->spacechar, attr[NOHLITE], menuwidth + 2, ms->menupage); // Wipe area with spaces
- gotoxy(top + row, left - 2, ms->menupage);
- csprint(fchar, attr[NOHLITE]); // Print first part
- gotoxy(top + row, left, ms->menupage);
- printmenuitem(str, attr); // Print main part
- gotoxy(top + row, left + menuwidth - 1, ms->menupage); // Last char if any
- csprint(lchar, attr[NOHLITE]); // Print last part
+ ci = menu->items[x];
+ if (ci->action == OPT_INVISIBLE)
+ continue;
+ row++;
+ if (row >= numitems)
+ break; // Already have enough number of items
+ print_line(menu, curr, top, left, x, row, radio);
}
// Check if we need to MOREABOVE and MOREBELOW to be added
// reuse x
row = 0;
- x = next_visible_sep(menu, 0); // First item
- if (!isvisible(menu, first, x)) // There is more above
+ x = next_visible_sep(menu, 0); // First item
+ if (!isvisible(menu, first, x)) // There is more above
{
- row = 1;
- gotoxy(top, left + menuwidth, ms->menupage);
- cprint(MOREABOVE, ms->normalattr[NOHLITE], 1, ms->menupage);
+ row = 1;
+ gotoxy(top, left + menuwidth);
+ cprint(MOREABOVE, ms->normalattr[NOHLITE], 1);
}
- x = prev_visible_sep(menu, menu->numitems); // last item
- if (!isvisible(menu, first, x)) // There is more above
+ x = prev_visible_sep(menu, menu->numitems); // last item
+ if (!isvisible(menu, first, x)) // There is more above
{
- row = 1;
- gotoxy(top + numitems - 1, left + menuwidth, ms->menupage);
- cprint(MOREBELOW, ms->normalattr[NOHLITE], 1, ms->menupage);
+ row = 1;
+ gotoxy(top + numitems - 1, left + menuwidth);
+ cprint(MOREBELOW, ms->normalattr[NOHLITE], 1);
}
// Add a scroll box
x = ((numitems - 1) * curr) / (menu->numitems);
if ((x > 0) && (row == 1)) {
- gotoxy(top + x, left + menuwidth, ms->menupage);
- cprint(SCROLLBOX, ms->normalattr[NOHLITE], 1, ms->menupage);
+ gotoxy(top + x, left + menuwidth);
+ csprint("\016\141\017", ms->normalattr[NOHLITE]);
}
if (ms->handler)
- ms->handler(ms, menu->items[curr]);
+ ms->handler(ms, menu->items[curr]);
}
void cleanupmenu(pt_menu menu, uchar top, uchar left, int numitems)
{
if (numitems > menu->menuheight)
- numitems = menu->menuheight;
- clearwindow(top, left - 2, top + numitems + 1, left + menu->menuwidth + 4, ms->menupage, ms->fillchar, ms->fillattr); // Clear the shadow
- clearwindow(top - 1, left - 3, top + numitems, left + menu->menuwidth + 3, ms->menupage, ms->fillchar, ms->fillattr); // main window
+ numitems = menu->menuheight;
+ clearwindow(top, left - 2, top + numitems + 1, left + menu->menuwidth + 4, ms->fillchar, ms->fillattr); // Clear the shadow
+ clearwindow(top - 1, left - 3, top + numitems, left + menu->menuwidth + 3, ms->fillchar, ms->fillattr); // main window
}
-/* Handle a radio menu */
-pt_menuitem getradiooption(pt_menu menu, uchar top, uchar left, uchar startopt)
- // Return item chosen or NULL if ESC was hit.
-{
- int curr, i, first, tmp;
- uchar asc, scan;
- uchar numitems;
- pt_menuitem ci; // Current item
-
- numitems = calc_visible(menu, 0);
- // Setup status line
- gotoxy(ms->minrow + ms->statline, ms->mincol, ms->menupage);
- cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols, ms->menupage);
-
- // Initialise current menu item
- curr = next_visible(menu, startopt);
-
- gotoxy(ms->minrow + ms->statline, ms->mincol, ms->menupage);
- cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols, 1);
- gotoxy(ms->minrow + ms->statline, ms->mincol, ms->menupage);
- printmenuitem(menu->items[curr]->status, ms->statusattr);
- first = calc_first_early(menu, curr);
- while (1) // Forever
- {
- printradiomenu(menu, curr, top, left, first);
- ci = menu->items[curr];
-
- asc = getch(&scan);
- switch (scan) {
- case HOMEKEY:
- curr = next_visible(menu, 0);
- first = calc_first_early(menu, curr);
- break;
- case ENDKEY:
- curr = prev_visible(menu, numitems - 1);
- first = calc_first_late(menu, curr);
- break;
- case PAGEDN:
- for (i = 0; i < 5; i++)
- curr = next_visible(menu, curr + 1);
- first = calc_first_late(menu, curr);
- break;
- case PAGEUP:
- for (i = 0; i < 5; i++)
- curr = prev_visible(menu, curr - 1);
- first = calc_first_early(menu, curr);
- break;
- case UPARROW:
- curr = prev_visible(menu, curr - 1);
- if (curr < first)
- first = calc_first_early(menu, curr);
- break;
- case DNARROW:
- curr = next_visible(menu, curr + 1);
- if (!isvisible(menu, first, curr))
- first = calc_first_late(menu, curr);
- break;
- case LTARROW:
- case ESCAPE:
- return NULL;
- break;
- case RTARROW:
- case ENTERA:
- case ENTERB:
- if (ci->action == OPT_INACTIVE)
- break;
- if (ci->action == OPT_SEP)
- break;
- return ci;
- break;
- default:
- // Check if this is a shortcut key
- if (((asc >= 'A') && (asc <= 'Z')) ||
- ((asc >= 'a') && (asc <= 'z')) ||
- ((asc >= '0') && (asc <= '9'))) {
- tmp = find_shortcut(menu, asc, curr);
- if ((tmp > curr) && (!isvisible(menu, first, tmp)))
- first = calc_first_late(menu, tmp);
- if (tmp < curr)
- first = calc_first_early(menu, tmp);
- curr = tmp;
- } else {
- if (ms->keys_handler) // Call extra keys handler
- ms->keys_handler(ms, menu->items[curr], (scan << 8) | asc);
- }
- break;
- }
- // Update status line
- gotoxy(ms->minrow + ms->statline, ms->mincol, ms->menupage);
- cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols,
- ms->menupage);
- printmenuitem(menu->items[curr]->status, ms->statusattr);
- }
- return NULL; // Should never come here
-}
/* Handle one menu */
-pt_menuitem getmenuoption(pt_menu menu, uchar top, uchar left, uchar startopt)
+static pt_menuitem getmenuoption(pt_menu menu, uchar top, uchar left, uchar startopt, bool radio)
// Return item chosen or NULL if ESC was hit.
{
- int curr, i, first, tmp;
- uchar asc, scan;
+ int prev, prev_first, curr, i, first, tmp;
+ int asc = 0;
+ bool redraw = true; // Need to draw the menu the first time
uchar numitems;
- pt_menuitem ci; // Current item
- t_handler_return hr; // Return value of handler
+ pt_menuitem ci; // Current item
+ t_handler_return hr; // Return value of handler
numitems = calc_visible(menu, 0);
// Setup status line
- gotoxy(ms->minrow + ms->statline, ms->mincol, ms->menupage);
- cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols, ms->menupage);
+ gotoxy(ms->minrow + ms->statline, ms->mincol);
+ cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols);
// Initialise current menu item
curr = next_visible(menu, startopt);
+ prev = curr;
- gotoxy(ms->minrow + ms->statline, ms->mincol, ms->menupage);
- cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols, 1);
- gotoxy(ms->minrow + ms->statline, ms->mincol, ms->menupage);
+ gotoxy(ms->minrow + ms->statline, ms->mincol);
+ cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols);
+ gotoxy(ms->minrow + ms->statline, ms->mincol);
printmenuitem(menu->items[curr]->status, ms->statusattr);
first = calc_first_early(menu, curr);
- while (1) // Forever
+ prev_first = first;
+ while (1) // Forever
{
- printmenu(menu, curr, top, left, first);
- ci = menu->items[curr];
- asc = getch(&scan);
- switch (scan) {
- case HOMEKEY:
- curr = next_visible(menu, 0);
- first = calc_first_early(menu, curr);
- break;
- case ENDKEY:
- curr = prev_visible(menu, numitems - 1);
- first = calc_first_late(menu, curr);
- break;
- case PAGEDN:
- for (i = 0; i < 5; i++)
- curr = next_visible(menu, curr + 1);
- first = calc_first_late(menu, curr);
- break;
- case PAGEUP:
- for (i = 0; i < 5; i++)
- curr = prev_visible(menu, curr - 1);
- first = calc_first_early(menu, curr);
- break;
- case UPARROW:
- curr = prev_visible(menu, curr - 1);
- if (curr < first)
- first = calc_first_early(menu, curr);
- break;
- case DNARROW:
- curr = next_visible(menu, curr + 1);
- if (!isvisible(menu, first, curr))
- first = calc_first_late(menu, curr);
- break;
- case LTARROW:
- case ESCAPE:
- return NULL;
- break;
- case RTARROW:
- case ENTERA:
- case ENTERB:
- if (ci->action == OPT_INACTIVE)
- break;
- if (ci->action == OPT_CHECKBOX)
- break;
- if (ci->action == OPT_SEP)
- break;
- if (ci->action == OPT_EXITMENU)
- return NULL; // As if we hit Esc
- // If we are going into a radio menu, dont call handler, return ci
- if (ci->action == OPT_RADIOMENU)
- return ci;
- if (ci->handler != NULL) // Do we have a handler
- {
- hr = ci->handler(ms, ci);
- if (hr.refresh) // Do we need to refresh
- {
- // Cleanup menu using old number of items
- cleanupmenu(menu, top, left, numitems);
- // Recalculate the number of items
- numitems = calc_visible(menu, 0);
- // Reprint the menu
- printmenu(menu, curr, top, left, first);
- }
- if (hr.valid)
- return ci;
- } else
- return ci;
- break;
- case SPACEKEY:
- if (ci->action != OPT_CHECKBOX)
- break;
- ci->itemdata.checked = !ci->itemdata.checked;
- if (ci->handler != NULL) // Do we have a handler
- {
- hr = ci->handler(ms, ci);
- if (hr.refresh) // Do we need to refresh
- {
- // Cleanup menu using old number of items
- cleanupmenu(menu, top, left, numitems);
- // Recalculate the number of items
- numitems = calc_visible(menu, 0);
- // Reprint the menu
- printmenu(menu, curr, top, left, first);
- }
- }
- break;
- default:
- // Check if this is a shortcut key
- if (((asc >= 'A') && (asc <= 'Z')) ||
- ((asc >= 'a') && (asc <= 'z')) ||
- ((asc >= '0') && (asc <= '9'))) {
- tmp = find_shortcut(menu, asc, curr);
- if ((tmp > curr) && (!isvisible(menu, first, tmp)))
- first = calc_first_late(menu, tmp);
- if (tmp < curr)
- first = calc_first_early(menu, tmp);
- curr = tmp;
- } else {
- if (ms->keys_handler) // Call extra keys handler
- ms->keys_handler(ms, menu->items[curr], (scan << 8) | asc);
- }
- break;
- }
- // Update status line
- gotoxy(ms->minrow + ms->statline, ms->mincol, ms->menupage);
- cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols,
- ms->menupage);
- printmenuitem(menu->items[curr]->status, ms->statusattr);
+ /* Redraw everything if:
+ * + we need to scroll (take care of scroll bars, ...)
+ * + menuoption
+ */
+ if (prev_first != first || redraw) {
+ printmenu(menu, curr, top, left, first, radio);
+ } else {
+ /* Redraw only the highlighted entry */
+ print_line(menu, curr, top, left, prev, prev - first, radio);
+ print_line(menu, curr, top, left, curr, curr - first, radio);
+ }
+ redraw = false;
+ prev = curr;
+ prev_first = first;
+ ci = menu->items[curr];
+ asc = getch();
+ switch (asc) {
+ case KEY_CTRL('L'):
+ redraw = true;
+ break;
+ case KEY_HOME:
+ curr = next_visible(menu, 0);
+ first = calc_first_early(menu, curr);
+ break;
+ case KEY_END:
+ curr = prev_visible(menu, numitems - 1);
+ first = calc_first_late(menu, curr);
+ break;
+ case KEY_PGDN:
+ for (i = 0; i < 5; i++)
+ curr = next_visible(menu, curr + 1);
+ first = calc_first_late(menu, curr);
+ break;
+ case KEY_PGUP:
+ for (i = 0; i < 5; i++)
+ curr = prev_visible(menu, curr - 1);
+ first = calc_first_early(menu, curr);
+ break;
+ case KEY_UP:
+ curr = prev_visible(menu, curr - 1);
+ if (curr < first)
+ first = calc_first_early(menu, curr);
+ break;
+ case KEY_DOWN:
+ curr = next_visible(menu, curr + 1);
+ if (!isvisible(menu, first, curr))
+ first = calc_first_late(menu, curr);
+ break;
+ case KEY_LEFT:
+ case KEY_ESC:
+ return NULL;
+ break;
+ case KEY_RIGHT:
+ case KEY_ENTER:
+ if (ci->action == OPT_INACTIVE)
+ break;
+ if (ci->action == OPT_CHECKBOX)
+ break;
+ if (ci->action == OPT_SEP)
+ break;
+ if (ci->action == OPT_EXITMENU)
+ return NULL; // As if we hit Esc
+ // If we are going into a radio menu, dont call handler, return ci
+ if (ci->action == OPT_RADIOMENU)
+ return ci;
+ if (ci->handler != NULL) // Do we have a handler
+ {
+ hr = ci->handler(ms, ci);
+ if (hr.refresh) // Do we need to refresh
+ {
+ // Cleanup menu using old number of items
+ cleanupmenu(menu, top, left, numitems);
+ // Recalculate the number of items
+ numitems = calc_visible(menu, 0);
+ // Reprint the menu
+ printmenu(menu, curr, top, left, first, radio);
+ }
+ if (hr.valid)
+ return ci;
+ } else
+ return ci;
+ break;
+ case SPACECHAR:
+ if (ci->action != OPT_CHECKBOX)
+ break;
+ ci->itemdata.checked = !ci->itemdata.checked;
+ if (ci->handler != NULL) // Do we have a handler
+ {
+ hr = ci->handler(ms, ci);
+ if (hr.refresh) // Do we need to refresh
+ {
+ // Cleanup menu using old number of items
+ cleanupmenu(menu, top, left, numitems);
+ // Recalculate the number of items
+ numitems = calc_visible(menu, 0);
+ // Reprint the menu
+ printmenu(menu, curr, top, left, first, radio);
+ }
+ }
+ break;
+ default:
+ // Check if this is a shortcut key
+ if (((asc >= 'A') && (asc <= 'Z')) ||
+ ((asc >= 'a') && (asc <= 'z')) ||
+ ((asc >= '0') && (asc <= '9'))) {
+ tmp = find_shortcut(menu, asc, curr);
+ if ((tmp > curr) && (!isvisible(menu, first, tmp)))
+ first = calc_first_late(menu, tmp);
+ if (tmp < curr)
+ first = calc_first_early(menu, tmp);
+ curr = tmp;
+ } else {
+ if (ms->keys_handler) // Call extra keys handler
+ ms->keys_handler(ms, menu->items[curr], asc);
+
+ /* The handler may have changed the UI, reset it on exit */
+ reset_ui();
+ // Cleanup menu using old number of items
+ cleanupmenu(menu, top, left, numitems);
+ // Recalculate the number of items
+ numitems = calc_visible(menu, 0);
+ // Reprint the menu
+ printmenu(menu, curr, top, left, first, radio);
+ }
+ break;
+ }
+ // Update status line
+ /* Erase the previous status */
+ gotoxy(ms->minrow + ms->statline, ms->mincol);
+ cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols);
+ /* Print the new status */
+ gotoxy(ms->minrow + ms->statline, ms->mincol);
+ printmenuitem(menu->items[curr]->status, ms->statusattr);
}
- return NULL; // Should never come here
+ return NULL; // Should never come here
}
/* Handle the entire system of menu's. */
pt_menuitem runmenusystem(uchar top, uchar left, pt_menu cmenu, uchar startopt,
- uchar menutype)
+ uchar menutype)
/*
* cmenu
* Which menu should be currently displayed
@@ -629,36 +529,37 @@ pt_menuitem runmenusystem(uchar top, uchar left, pt_menu cmenu, uchar startopt,
uchar row, col;
if (cmenu == NULL)
- return NULL;
+ return NULL;
+
startover:
// Set the menu height
cmenu->menuheight = ms->maxrow - top - 3;
if (cmenu->menuheight > ms->maxmenuheight)
- cmenu->menuheight = ms->maxmenuheight;
+ cmenu->menuheight = ms->maxmenuheight;
if (menutype == NORMALMENU)
- opt = getmenuoption(cmenu, top, left, startopt);
- else // menutype == RADIOMENU
- opt = getradiooption(cmenu, top, left, startopt);
+ opt = getmenuoption(cmenu, top, left, startopt, false);
+ else // menutype == RADIOMENU
+ opt = getmenuoption(cmenu, top, left, startopt, true);
if (opt == NULL) {
- // User hit Esc
- cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
- return NULL;
+ // User hit Esc
+ cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
+ return NULL;
}
// Are we done with the menu system?
if ((opt->action != OPT_SUBMENU) && (opt->action != OPT_RADIOMENU)) {
- cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
- return opt; // parent cleanup other menus
+ cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
+ return opt; // parent cleanup other menus
}
// Either radiomenu or submenu
// Do we have a valid menu number? The next hack uses the fact that
// itemdata.submenunum = itemdata.radiomenunum (since enum data type)
- if (opt->itemdata.submenunum >= ms->nummenus) // This is Bad....
+ if (opt->itemdata.submenunum >= ms->nummenus) // This is Bad....
{
- gotoxy(12, 12, ms->menupage); // Middle of screen
- csprint("ERROR: Invalid submenu requested.", 0x07);
- cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
- return NULL; // Pretend user hit esc
+ gotoxy(12, 12); // Middle of screen
+ csprint("ERROR: Invalid submenu requested.", 0x07);
+ cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
+ return NULL; // Pretend user hit esc
}
// Call recursively for submenu
// Position the submenu below the current item,
@@ -666,32 +567,32 @@ startover:
row = ms->menus[(unsigned int)opt->itemdata.submenunum]->row;
col = ms->menus[(unsigned int)opt->itemdata.submenunum]->col;
if (row == 0xFF)
- row = top + opt->index + 2;
+ row = top + opt->index + 2;
if (col == 0xFF)
- col = left + 3 + (cmenu->menuwidth >> 1);
+ col = left + 3 + (cmenu->menuwidth >> 1);
mt = (opt->action == OPT_SUBMENU ? NORMALMENU : RADIOMENU);
startat = 0;
if ((opt->action == OPT_RADIOMENU) && (opt->data != NULL))
- startat = ((t_menuitem *) opt->data)->index;
+ startat = ((t_menuitem *) opt->data)->index;
choice = runmenusystem(row, col,
- ms->menus[(unsigned int)opt->itemdata.submenunum],
- startat, mt);
+ ms->menus[(unsigned int)opt->itemdata.submenunum],
+ startat, mt);
if (opt->action == OPT_RADIOMENU) {
- if (choice != NULL)
- opt->data = (void *)choice; // store choice in data field
- if (opt->handler != NULL)
- opt->handler(ms, opt);
- choice = NULL; // Pretend user hit esc
+ if (choice != NULL)
+ opt->data = (void *)choice; // store choice in data field
+ if (opt->handler != NULL)
+ opt->handler(ms, opt);
+ choice = NULL; // Pretend user hit esc
}
- if (choice == NULL) // User hit Esc in submenu
+ if (choice == NULL) // User hit Esc in submenu
{
- // Startover
- startopt = opt->index;
- goto startover;
+ // Startover
+ startopt = opt->index;
+ goto startover;
} else {
- cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
- return choice;
+ cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
+ return choice;
}
}
@@ -702,11 +603,11 @@ uchar find_menu_num(const char *name)
pt_menu m;
if (name == NULL)
- return (uchar) (-1);
+ return (uchar) (-1);
for (i = 0; i < ms->nummenus; i++) {
- m = ms->menus[i];
- if ((m->name) && (strcmp(m->name, name) == 0))
- return i;
+ m = ms->menus[i];
+ if ((m->name) && (strcmp(m->name, name) == 0))
+ return i;
}
return (uchar) (-1);
}
@@ -722,16 +623,16 @@ void fix_submenus()
i = 0;
for (i = 0; i < ms->nummenus; i++) {
- m = ms->menus[i];
- for (j = 0; j < m->numitems; j++) {
- mi = m->items[j];
- // if item is a submenu and has non-empty non-trivial data string
- if (mi->data && strlen(mi->data) > 0 &&
- ((mi->action == OPT_SUBMENU)
- || (mi->action == OPT_RADIOMENU))) {
- mi->itemdata.submenunum = find_menu_num(mi->data);
- }
- }
+ m = ms->menus[i];
+ for (j = 0; j < m->numitems; j++) {
+ mi = m->items[j];
+ // if item is a submenu and has non-empty non-trivial data string
+ if (mi->data && strlen(mi->data) > 0 &&
+ ((mi->action == OPT_SUBMENU)
+ || (mi->action == OPT_RADIOMENU))) {
+ mi->itemdata.submenunum = find_menu_num(mi->data);
+ }
+ }
}
}
@@ -740,34 +641,23 @@ void fix_submenus()
pt_menuitem showmenus(uchar startmenu)
{
pt_menuitem rv;
- uchar oldpage, tpos;
- fix_submenus(); // Fix submenu numbers incase nick names were used
+ fix_submenus(); // Fix submenu numbers incase nick names were used
- // Setup screen for menusystem
- oldpage = getdisppage();
- setdisppage(ms->menupage);
- cls();
- clearwindow(ms->minrow, ms->mincol, ms->maxrow, ms->maxcol,
- ms->menupage, ms->fillchar, ms->fillattr);
- tpos = (ms->numcols - strlen(ms->title) - 1) >> 1; // center it on line
- gotoxy(ms->minrow, ms->mincol, ms->menupage);
- cprint(ms->tfillchar, ms->titleattr, ms->numcols, ms->menupage);
- gotoxy(ms->minrow, ms->mincol + tpos, ms->menupage);
- csprint(ms->title, ms->titleattr);
+ /* Turn autowrap off, to avoid scrolling the menu */
+ printf(CSI "?7l");
- cursoroff(); // Doesn't seem to work?
+ // Setup screen for menusystem
+ reset_ui();
// Go, main menu cannot be a radio menu
rv = runmenusystem(ms->minrow + MENUROW, ms->mincol + MENUCOL,
- ms->menus[(unsigned int)startmenu], 0, NORMALMENU);
+ ms->menus[(unsigned int)startmenu], 0, NORMALMENU);
// Hide the garbage we left on the screen
cursoron();
- if (oldpage == ms->menupage)
- cls();
- else
- setdisppage(oldpage);
+ cls();
+ gotoxy(ms->minrow, ms->mincol);
// Return user choice
return rv;
@@ -780,17 +670,17 @@ pt_menusystem init_menusystem(const char *title)
ms = NULL;
ms = (pt_menusystem) malloc(sizeof(t_menusystem));
if (ms == NULL)
- return NULL;
+ return NULL;
ms->nummenus = 0;
// Initialise all menu pointers
for (i = 0; i < MAXMENUS; i++)
- ms->menus[i] = NULL;
+ ms->menus[i] = NULL;
ms->title = (char *)malloc(TITLELEN + 1);
if (title == NULL)
- strcpy(ms->title, TITLESTR); // Copy string
+ strcpy(ms->title, TITLESTR); // Copy string
else
- strcpy(ms->title, title);
+ strcpy(ms->title, title);
// Timeout settings
ms->tm_stepsize = TIMEOUTSTEPSIZE;
@@ -820,12 +710,12 @@ pt_menusystem init_menusystem(const char *title)
ms->spacechar = SPACECHAR;
ms->shadowattr = SHADOWATTR;
- ms->menupage = MENUPAGE; // Usually no need to change this at all
+ ms->menupage = MENUPAGE; // Usually no need to change this at all
// Initialise all handlers
ms->handler = NULL;
ms->keys_handler = NULL;
- ms->ontimeout = NULL; // No timeout handler
+ ms->ontimeout = NULL; // No timeout handler
ms->tm_total_timeout = 0;
ms->tm_sofar_timeout = 0;
ms->ontotaltimeout = NULL;
@@ -838,110 +728,107 @@ pt_menusystem init_menusystem(const char *title)
// Figure out the size of the screen we are in now.
// By default we use the whole screen for our menu
+ if (getscreensize(1, &ms->numrows, &ms->numcols)) {
+ /* Unknown screen size? */
+ ms->numcols = 80;
+ ms->numrows = 24;
+ }
ms->minrow = ms->mincol = 0;
- ms->numcols = getnumcols();
- ms->numrows = getnumrows();
ms->maxcol = ms->numcols - 1;
ms->maxrow = ms->numrows - 1;
// How many entries per menu can we display at a time
ms->maxmenuheight = ms->maxrow - ms->minrow - 3;
if (ms->maxmenuheight > MAXMENUHEIGHT)
- ms->maxmenuheight = MAXMENUHEIGHT;
+ ms->maxmenuheight = MAXMENUHEIGHT;
+
+ console_ansi_raw();
- // Set up the look of the box
- set_box_type(MENUBOXTYPE);
return ms;
}
void set_normal_attr(uchar normal, uchar selected, uchar inactivenormal,
- uchar inactiveselected)
+ uchar inactiveselected)
{
if (normal != 0xFF)
- ms->normalattr[0] = normal;
+ ms->normalattr[0] = normal;
if (selected != 0xFF)
- ms->reverseattr[0] = selected;
+ ms->reverseattr[0] = selected;
if (inactivenormal != 0xFF)
- ms->inactattr[0] = inactivenormal;
+ ms->inactattr[0] = inactivenormal;
if (inactiveselected != 0xFF)
- ms->revinactattr[0] = inactiveselected;
+ ms->revinactattr[0] = inactiveselected;
}
void set_normal_hlite(uchar normal, uchar selected, uchar inactivenormal,
- uchar inactiveselected)
+ uchar inactiveselected)
{
if (normal != 0xFF)
- ms->normalattr[1] = normal;
+ ms->normalattr[1] = normal;
if (selected != 0xFF)
- ms->reverseattr[1] = selected;
+ ms->reverseattr[1] = selected;
if (inactivenormal != 0xFF)
- ms->inactattr[1] = inactivenormal;
+ ms->inactattr[1] = inactivenormal;
if (inactiveselected != 0xFF)
- ms->revinactattr[1] = inactiveselected;
+ ms->revinactattr[1] = inactiveselected;
}
void set_status_info(uchar statusattr, uchar statushlite, uchar statline)
{
if (statusattr != 0xFF)
- ms->statusattr[NOHLITE] = statusattr;
+ ms->statusattr[NOHLITE] = statusattr;
if (statushlite != 0xFF)
- ms->statusattr[HLITE] = statushlite;
+ ms->statusattr[HLITE] = statushlite;
// statline is relative to minrow
if (statline >= ms->numrows)
- statline = ms->numrows - 1;
- ms->statline = statline; // relative to ms->minrow, 0 based
+ statline = ms->numrows - 1;
+ ms->statline = statline; // relative to ms->minrow, 0 based
}
void set_title_info(uchar tfillchar, uchar titleattr)
{
if (tfillchar != 0xFF)
- ms->tfillchar = tfillchar;
+ ms->tfillchar = tfillchar;
if (titleattr != 0xFF)
- ms->titleattr = titleattr;
+ ms->titleattr = titleattr;
}
void set_misc_info(uchar fillchar, uchar fillattr, uchar spacechar,
- uchar shadowattr)
+ uchar shadowattr)
{
if (fillchar != 0xFF)
- ms->fillchar = fillchar;
+ ms->fillchar = fillchar;
if (fillattr != 0xFF)
- ms->fillattr = fillattr;
+ ms->fillattr = fillattr;
if (spacechar != 0xFF)
- ms->spacechar = spacechar;
+ ms->spacechar = spacechar;
if (shadowattr != 0xFF)
- ms->shadowattr = shadowattr;
-}
-
-void set_box_type(boxtype bt)
-{
- uchar *bxc;
- ms->menubt = bt;
- bxc = getboxchars(bt);
- ms->box_horiz = bxc[BOX_HORIZ]; // The char used to draw top line
- ms->box_ltrt = bxc[BOX_LTRT];
- ms->box_rtlt = bxc[BOX_RTLT];
+ ms->shadowattr = shadowattr;
}
void set_menu_options(uchar maxmenuheight)
{
if (maxmenuheight != 0xFF)
- ms->maxmenuheight = maxmenuheight;
+ ms->maxmenuheight = maxmenuheight;
}
// Set the window which menusystem should use
void set_window_size(uchar top, uchar left, uchar bot, uchar right)
{
+ int nr, nc;
- uchar nr, nc;
if ((top > bot) || (left > right))
- return; // Sorry no change will happen here
- nr = getnumrows();
- nc = getnumcols();
+ return; // Sorry no change will happen here
+
+ if (getscreensize(1, &nr, &nc)) {
+ /* Unknown screen size? */
+ nr = 80;
+ nc = 24;
+ }
if (bot >= nr)
- bot = nr - 1;
+ bot = nr - 1;
if (right >= nc)
- right = nc - 1;
+ right = nc - 1;
ms->minrow = top;
ms->mincol = left;
ms->maxrow = bot;
@@ -949,7 +836,7 @@ void set_window_size(uchar top, uchar left, uchar bot, uchar right)
ms->numcols = right - left + 1;
ms->numrows = bot - top + 1;
if (ms->statline >= ms->numrows)
- ms->statline = ms->numrows - 1; // Clip statline if need be
+ ms->statline = ms->numrows - 1; // Clip statline if need be
}
void reg_handler(t_handler htype, void *handler)
@@ -957,11 +844,11 @@ void reg_handler(t_handler htype, void *handler)
// If bad value set to default screen handler
switch (htype) {
case HDLR_KEYS:
- ms->keys_handler = (t_keys_handler) handler;
- break;
+ ms->keys_handler = (t_keys_handler) handler;
+ break;
default:
- ms->handler = (t_menusystem_handler) handler;
- break;
+ ms->handler = (t_menusystem_handler) handler;
+ break;
}
}
@@ -969,22 +856,22 @@ void unreg_handler(t_handler htype)
{
switch (htype) {
case HDLR_KEYS:
- ms->keys_handler = NULL;
- break;
+ ms->keys_handler = NULL;
+ break;
default:
- ms->handler = NULL;
- break;
+ ms->handler = NULL;
+ break;
}
}
void reg_ontimeout(t_timeout_handler handler, unsigned int numsteps,
- unsigned int stepsize)
+ unsigned int stepsize)
{
ms->ontimeout = handler;
if (numsteps != 0)
- ms->tm_numsteps = numsteps;
+ ms->tm_numsteps = numsteps;
if (stepsize != 0)
- ms->tm_stepsize = stepsize;
+ ms->tm_stepsize = stepsize;
}
void unreg_ontimeout()
@@ -993,12 +880,12 @@ void unreg_ontimeout()
}
void reg_ontotaltimeout(t_timeout_handler handler,
- unsigned long numcentiseconds)
+ unsigned long numcentiseconds)
{
if (numcentiseconds != 0) {
- ms->ontotaltimeout = handler;
- ms->tm_total_timeout = numcentiseconds * 10; // to convert to milliseconds
- ms->tm_sofar_timeout = 0;
+ ms->ontotaltimeout = handler;
+ ms->tm_total_timeout = numcentiseconds * 10; // to convert to milliseconds
+ ms->tm_sofar_timeout = 0;
}
}
@@ -1011,31 +898,31 @@ int next_visible(pt_menu menu, int index)
{
int ans;
if (index < 0)
- ans = 0;
+ ans = 0;
else if (index >= menu->numitems)
- ans = menu->numitems - 1;
+ ans = menu->numitems - 1;
else
- ans = index;
+ ans = index;
while ((ans < menu->numitems - 1) &&
- ((menu->items[ans]->action == OPT_INVISIBLE) ||
- (menu->items[ans]->action == OPT_SEP)))
- ans++;
+ ((menu->items[ans]->action == OPT_INVISIBLE) ||
+ (menu->items[ans]->action == OPT_SEP)))
+ ans++;
return ans;
}
-int prev_visible(pt_menu menu, int index) // Return index of prev visible
+int prev_visible(pt_menu menu, int index) // Return index of prev visible
{
int ans;
if (index < 0)
- ans = 0;
+ ans = 0;
else if (index >= menu->numitems)
- ans = menu->numitems - 1;
+ ans = menu->numitems - 1;
else
- ans = index;
+ ans = index;
while ((ans > 0) &&
- ((menu->items[ans]->action == OPT_INVISIBLE) ||
- (menu->items[ans]->action == OPT_SEP)))
- ans--;
+ ((menu->items[ans]->action == OPT_INVISIBLE) ||
+ (menu->items[ans]->action == OPT_SEP)))
+ ans--;
return ans;
}
@@ -1043,28 +930,28 @@ int next_visible_sep(pt_menu menu, int index)
{
int ans;
if (index < 0)
- ans = 0;
+ ans = 0;
else if (index >= menu->numitems)
- ans = menu->numitems - 1;
+ ans = menu->numitems - 1;
else
- ans = index;
+ ans = index;
while ((ans < menu->numitems - 1) &&
- (menu->items[ans]->action == OPT_INVISIBLE))
- ans++;
+ (menu->items[ans]->action == OPT_INVISIBLE))
+ ans++;
return ans;
}
-int prev_visible_sep(pt_menu menu, int index) // Return index of prev visible
+int prev_visible_sep(pt_menu menu, int index) // Return index of prev visible
{
int ans;
if (index < 0)
- ans = 0;
+ ans = 0;
else if (index >= menu->numitems)
- ans = menu->numitems - 1;
+ ans = menu->numitems - 1;
else
- ans = index;
+ ans = index;
while ((ans > 0) && (menu->items[ans]->action == OPT_INVISIBLE))
- ans--;
+ ans--;
return ans;
}
@@ -1073,11 +960,11 @@ int calc_visible(pt_menu menu, int first)
int ans, i;
if (menu == NULL)
- return 0;
+ return 0;
ans = 0;
for (i = first; i < menu->numitems; i++)
- if (menu->items[i]->action != OPT_INVISIBLE)
- ans++;
+ if (menu->items[i]->action != OPT_INVISIBLE)
+ ans++;
return ans;
}
@@ -1085,9 +972,9 @@ int calc_visible(pt_menu menu, int first)
int isvisible(pt_menu menu, int first, int curr)
{
if (curr < first)
- return 0;
+ return 0;
return (calc_visible(menu, first) - calc_visible(menu, curr) <
- menu->menuheight);
+ menu->menuheight);
}
// Calculate the first entry to be displayed
@@ -1098,11 +985,11 @@ int calc_first_late(pt_menu menu, int curr)
nv = calc_visible(menu, 0);
if (nv <= menu->menuheight)
- return 0;
+ return 0;
// Start with curr and go back menu->menuheight times
ans = curr + 1;
for (i = 0; i < menu->menuheight; i++)
- ans = prev_visible_sep(menu, ans - 1);
+ ans = prev_visible_sep(menu, ans - 1);
return ans;
}
@@ -1114,13 +1001,13 @@ int calc_first_early(pt_menu menu, int curr)
nv = calc_visible(menu, 0);
if (nv <= menu->menuheight)
- return 0;
+ return 0;
// Start with curr and go back till >= menu->menuheight
// items are visible
- nv = calc_visible(menu, curr); // Already nv of them are visible
+ nv = calc_visible(menu, curr); // Already nv of them are visible
ans = curr;
for (i = 0; i < menu->menuheight - nv; i++)
- ans = prev_visible_sep(menu, ans - 1);
+ ans = prev_visible_sep(menu, ans - 1);
return ans;
}
@@ -1132,51 +1019,51 @@ uchar add_menu(const char *title, int maxmenusize)
num = ms->nummenus;
if (num >= MAXMENUS)
- return -1;
+ return -1;
m = NULL;
m = (pt_menu) malloc(sizeof(t_menu));
if (m == NULL)
- return -1;
+ return -1;
ms->menus[num] = m;
m->numitems = 0;
m->name = NULL;
m->row = 0xFF;
m->col = 0xFF;
if (maxmenusize < 1)
- m->maxmenusize = MAXMENUSIZE;
+ m->maxmenusize = MAXMENUSIZE;
else
- m->maxmenusize = maxmenusize;
+ m->maxmenusize = maxmenusize;
m->items = (pt_menuitem *) malloc(sizeof(pt_menuitem) * (m->maxmenusize));
for (i = 0; i < m->maxmenusize; i++)
- m->items[i] = NULL;
+ m->items[i] = NULL;
m->title = (char *)malloc(MENULEN + 1);
if (title) {
- if (strlen(title) > MENULEN - 2)
- strcpy(m->title, TITLELONG);
- else
- strcpy(m->title, title);
+ if (strlen(title) > MENULEN - 2)
+ strcpy(m->title, TITLELONG);
+ else
+ strcpy(m->title, title);
} else
- strcpy(m->title, EMPTYSTR);
+ strcpy(m->title, EMPTYSTR);
m->menuwidth = strlen(m->title);
ms->nummenus++;
return ms->nummenus - 1;
}
-void set_menu_name(const char *name) // Set the "name" of this menu
+void set_menu_name(const char *name) // Set the "name" of this menu
{
pt_menu m;
m = ms->menus[ms->nummenus - 1];
- if (m->name) // Free up previous name
+ if (m->name) // Free up previous name
{
- free(m->name);
- m->name = NULL;
+ free(m->name);
+ m->name = NULL;
}
if (name) {
- m->name = (char *)malloc(strlen(name) + 1);
- strcpy(m->name, name);
+ m->name = (char *)malloc(strlen(name) + 1);
+ strcpy(m->name, name);
}
}
@@ -1188,7 +1075,7 @@ uchar add_named_menu(const char *name, const char *title, int maxmenusize)
return ms->nummenus - 1;
}
-void set_menu_pos(uchar row, uchar col) // Set the position of this menu.
+void set_menu_pos(uchar row, uchar col) // Set the position of this menu.
{
pt_menu m;
@@ -1197,7 +1084,7 @@ void set_menu_pos(uchar row, uchar col) // Set the position of this menu.
m->col = col;
}
-pt_menuitem add_sep() // Add a separator to current menu
+pt_menuitem add_sep() // Add a separator to current menu
{
pt_menuitem mi;
pt_menu m;
@@ -1206,9 +1093,9 @@ pt_menuitem add_sep() // Add a separator to current menu
mi = NULL;
mi = (pt_menuitem) malloc(sizeof(t_menuitem));
if (mi == NULL)
- return NULL;
+ return NULL;
m->items[(unsigned int)m->numitems] = mi;
- mi->handler = NULL; // No handler
+ mi->handler = NULL; // No handler
mi->item = mi->status = mi->data = NULL;
mi->action = OPT_SEP;
mi->index = m->numitems++;
@@ -1220,20 +1107,20 @@ pt_menuitem add_sep() // Add a separator to current menu
// Add item to the "current" menu
pt_menuitem add_item(const char *item, const char *status, t_action action,
- const char *data, uchar itemdata)
+ const char *data, uchar itemdata)
{
pt_menuitem mi;
pt_menu m;
const char *str;
- uchar inhlite = 0; // Are we inside hlite area
+ uchar inhlite = 0; // Are we inside hlite area
m = (ms->menus[ms->nummenus - 1]);
mi = NULL;
mi = (pt_menuitem) malloc(sizeof(t_menuitem));
if (mi == NULL)
- return NULL;
+ return NULL;
m->items[(unsigned int)m->numitems] = mi;
- mi->handler = NULL; // No handler
+ mi->handler = NULL; // No handler
// Allocate space to store stuff
mi->item = (char *)malloc(MENULEN + 1);
@@ -1241,74 +1128,74 @@ pt_menuitem add_item(const char *item, const char *status, t_action action,
mi->data = (char *)malloc(ACTIONLEN + 1);
if (item) {
- if (strlen(item) > MENULEN) {
- strcpy(mi->item, ITEMLONG);
- } else {
- strcpy(mi->item, item);
- }
- if (strlen(mi->item) > m->menuwidth)
- m->menuwidth = strlen(mi->item);
+ if (strlen(item) > MENULEN) {
+ strcpy(mi->item, ITEMLONG);
+ } else {
+ strcpy(mi->item, item);
+ }
+ if (strlen(mi->item) > m->menuwidth)
+ m->menuwidth = strlen(mi->item);
} else
- strcpy(mi->item, EMPTYSTR);
+ strcpy(mi->item, EMPTYSTR);
if (status) {
- if (strlen(status) > STATLEN) {
- strcpy(mi->status, STATUSLONG);
- } else {
- strcpy(mi->status, status);
- }
+ if (strlen(status) > STATLEN) {
+ strcpy(mi->status, STATUSLONG);
+ } else {
+ strcpy(mi->status, status);
+ }
} else
- strcpy(mi->status, EMPTYSTR);
+ strcpy(mi->status, EMPTYSTR);
mi->action = action;
str = mi->item;
mi->shortcut = 0;
mi->helpid = 0xFFFF;
- inhlite = 0; // We have not yet seen an ENABLEHLITE char
+ inhlite = 0; // We have not yet seen an ENABLEHLITE char
// Find the first char in [A-Za-z0-9] after ENABLEHLITE and not arg to control char
while (*str) {
- if (*str == ENABLEHLITE) {
- inhlite = 1;
- }
- if (*str == DISABLEHLITE) {
- inhlite = 0;
- }
- if ((inhlite == 1) &&
- (((*str >= 'A') && (*str <= 'Z')) ||
- ((*str >= 'a') && (*str <= 'z')) ||
- ((*str >= '0') && (*str <= '9')))) {
- mi->shortcut = *str;
- break;
- }
- ++str;
+ if (*str == ENABLEHLITE) {
+ inhlite = 1;
+ }
+ if (*str == DISABLEHLITE) {
+ inhlite = 0;
+ }
+ if ((inhlite == 1) &&
+ (((*str >= 'A') && (*str <= 'Z')) ||
+ ((*str >= 'a') && (*str <= 'z')) ||
+ ((*str >= '0') && (*str <= '9')))) {
+ mi->shortcut = *str;
+ break;
+ }
+ ++str;
}
- if ((mi->shortcut >= 'A') && (mi->shortcut <= 'Z')) // Make lower case
- mi->shortcut = mi->shortcut - 'A' + 'a';
+ if ((mi->shortcut >= 'A') && (mi->shortcut <= 'Z')) // Make lower case
+ mi->shortcut = mi->shortcut - 'A' + 'a';
if (data) {
- if (strlen(data) > ACTIONLEN) {
- strcpy(mi->data, ACTIONLONG);
- } else {
- strcpy(mi->data, data);
- }
+ if (strlen(data) > ACTIONLEN) {
+ strcpy(mi->data, ACTIONLONG);
+ } else {
+ strcpy(mi->data, data);
+ }
} else
- strcpy(mi->data, EMPTYSTR);
+ strcpy(mi->data, EMPTYSTR);
switch (action) {
case OPT_SUBMENU:
- mi->itemdata.submenunum = itemdata;
- break;
+ mi->itemdata.submenunum = itemdata;
+ break;
case OPT_CHECKBOX:
- mi->itemdata.checked = itemdata;
- break;
+ mi->itemdata.checked = itemdata;
+ break;
case OPT_RADIOMENU:
- mi->itemdata.radiomenunum = itemdata;
- if (mi->data)
- free(mi->data);
- mi->data = NULL; // No selection made
- break;
- default: // to keep the compiler happy
- break;
+ mi->itemdata.radiomenunum = itemdata;
+ if (mi->data)
+ free(mi->data);
+ mi->data = NULL; // No selection made
+ break;
+ default: // to keep the compiler happy
+ break;
}
mi->index = m->numitems++;
mi->parindex = ms->nummenus - 1;
@@ -1323,13 +1210,13 @@ void set_item_options(uchar shortcut, int helpid)
m = (ms->menus[ms->nummenus - 1]);
if (m->numitems <= 0)
- return;
+ return;
mi = m->items[(unsigned int)m->numitems - 1];
if (shortcut != 0xFF)
- mi->shortcut = shortcut;
+ mi->shortcut = shortcut;
if (helpid != 0xFFFF)
- mi->helpid = helpid;
+ mi->helpid = helpid;
}
// Free internal datasutructures
@@ -1344,34 +1231,32 @@ void append_line_helper(int menunum, char *line)
pt_menuitem mi, ri;
char *app;
int ctr;
- char dp;
- dp = getdisppage();
menu = ms->menus[menunum];
for (ctr = 0; ctr < (int)menu->numitems; ctr++) {
- mi = menu->items[ctr];
- app = NULL; //What to append
- switch (mi->action) {
- case OPT_CHECKBOX:
- if (mi->itemdata.checked)
- app = mi->data;
- break;
- case OPT_RADIOMENU:
- if (mi->data) { // Some selection has been made
- ri = (pt_menuitem) (mi->data);
- app = ri->data;
- }
- break;
- case OPT_SUBMENU:
- append_line_helper(mi->itemdata.submenunum, line);
- break;
- default:
- break;
- }
- if (app) {
- strcat(line, " ");
- strcat(line, app);
- }
+ mi = menu->items[ctr];
+ app = NULL; //What to append
+ switch (mi->action) {
+ case OPT_CHECKBOX:
+ if (mi->itemdata.checked)
+ app = mi->data;
+ break;
+ case OPT_RADIOMENU:
+ if (mi->data) { // Some selection has been made
+ ri = (pt_menuitem) (mi->data);
+ app = ri->data;
+ }
+ break;
+ case OPT_SUBMENU:
+ append_line_helper(mi->itemdata.submenunum, line);
+ break;
+ default:
+ break;
+ }
+ if (app) {
+ strcat(line, " ");
+ strcat(line, app);
+ }
}
}
@@ -1383,6 +1268,6 @@ void gen_append_line(const char *menu_name, char *line)
menunum = find_menu_num(menu_name);
if (menunum < 0)
- return; // No such menu
+ return; // No such menu
append_line_helper(menunum, line);
}
diff --git a/com32/cmenu/libmenu/menu.h b/com32/cmenu/libmenu/menu.h
index 68adf278..44acb122 100644
--- a/com32/cmenu/libmenu/menu.h
+++ b/com32/cmenu/libmenu/menu.h
@@ -22,8 +22,8 @@
#include "com32io.h"
#include "tui.h"
#include "syslnx.h"
-#include "scancodes.h"
#include <string.h>
+#include <unistd.h>
// TIMEOUT PARAMETERS
/* If no key is pressed within TIMEOUTNUMSTEPS * TIMEOUTSTEPSIZE milliseconds
@@ -59,8 +59,8 @@
#define STATUSATTR 0x74
#define STATUSHLITE 0x7B // Status highlight
-#define FILLCHAR 177
-#define FILLATTR 0x01
+#define FILLCHAR ' '
+#define FILLATTR NORMALATTR
#define SHADOWATTR 0x00
#define SPACECHAR ' '
@@ -72,9 +72,8 @@
#define NOHLITE 0 // The offset into attrib array for non-hilite
#define HLITE 1 // The offset for Hlite attrib
-#define MOREABOVE 24 // char to print when more menu items available above
-#define MOREBELOW 25 // more items available below
-#define SCROLLBOX 176 // Filled char to display
+#define MOREABOVE '^' // char to print when more menu items available above
+#define MOREBELOW 'v' // more items available below
// Attributes of the menu system
#define MAXMENUS 150 // Maximum number of menu's allowed
@@ -99,11 +98,9 @@
#define DEBUGLINE 23 // debugging info goes here
// Other Chars
-#define SUBMENUCHAR 175 // This is >> symbol
#define RADIOMENUCHAR '>' // > symbol for radio menu?
-#define EXITMENUCHAR 174 // This is << symbol
-#define CHECKED 251 // Check mark
-#define UNCHECKED 250 // Light bullet
+#define CHECKED '\140' // Check mark
+#define UNCHECKED '\146' // Light bullet
#define RADIOSEL '.' // Current Radio Selection
#define RADIOUNSEL ' ' // Radio option not selected
@@ -214,11 +211,10 @@ typedef struct s_menusystem {
uchar shadowattr;
uchar statline;
uchar menupage;
- uchar maxrow, minrow, numrows; // Number of rows in the window
- uchar maxcol, mincol, numcols; // Number of columns in the window
+ int maxrow, minrow, numrows; // Number of rows in the window
+ int maxcol, mincol, numcols; // Number of columns in the window
// Menu box look
- boxtype menubt; // What type of boxes should be drawn
char box_horiz, box_ltrt, box_rtlt; // Some chars of the box, for redrawing portions of the box
} t_menusystem;
@@ -243,7 +239,6 @@ void set_title_info(uchar tfillchar, uchar titleattr);
void set_misc_info(uchar fillchar, uchar fillattr, uchar spacechar,
uchar shadowattr);
-void set_box_type(boxtype bt);
void set_window_size(uchar top, uchar left, uchar bot, uchar right); // Set the window which menusystem should use
diff --git a/com32/cmenu/libmenu/scancodes.h b/com32/cmenu/libmenu/scancodes.h
deleted file mode 100644
index b70f6c67..00000000
--- a/com32/cmenu/libmenu/scancodes.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- c -*- ------------------------------------------------------------- *
- *
- * Copyright 2004-2005 Murali Krishnan Ganapathy - 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., 53 Temple Place Ste 330,
- * Boston MA 02111-1307, USA; either version 2 of the License, or
- * (at your option) any later version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
-#ifndef __SCANCODES_H__
-#define __SCANCODES_H__
-
-// Scancodes of some keys
-#define ESCAPE 1
-#define ENTERA 28
-#define ENTERB 224
-
-#define HOMEKEY 71
-#define UPARROW 72
-#define PAGEUP 73
-#define LTARROW 75
-#define RTARROW 77
-#define ENDKEY 79
-#define DNARROW 80
-#define PAGEDN 81
-#define INSERT 82
-#define DELETE 83
-#define SPACEKEY 57 // Scan code for SPACE
-
-#define CTRLLT 0x73
-#define CTRLRT 0x74
-
-#define F1 0x3B
-#define F2 0x3C
-#define F3 0x3D
-#define F4 0x3E
-#define F5 0x3F
-#define F6 0x40
-#define F7 0x41
-#define F8 0x42
-#define F9 0x43
-#define F10 0x44
-#define F11 0x85
-#define F12 0x86
-
-#define CTRLF1 0x5E
-#define CTRLF2 0x5F
-#define CTRLF3 0x60
-#define CTRLF4 0x61
-#define CTRLF5 0x62
-#define CTRLF6 0x63
-#define CTRLF7 0x64
-#define CTRLF8 0x65
-#define CTRLF9 0x66
-#define CTRLF10 0x67
-#define CTRLF11 0x89
-#define CTRLF12 0x8A
-
-#define ALTF1 0x68
-#define ALTF2 0x69
-#define ALTF3 0x6A
-#define ALTF4 0x6B
-#define ALTF5 0x6C
-#define ALTF6 0x6D
-#define ALTF7 0x6E
-#define ALTF8 0x6F
-#define ALTF9 0x70
-#define ALTF10 0x71
-#define ALTF11 0x8B
-#define ALTF12 0x8C
-
-/* Bits representing ShiftFlags, See Int16/Function 2 or Mem[0x417] to get this info */
-
-#define INSERT_ON (1<<7)
-#define CAPSLOCK_ON (1<<6)
-#define NUMLOCK_ON (1<<5)
-#define SCRLLOCK_ON (1<<4)
-#define ALT_PRESSED (1<<3)
-#define CTRL_PRESSED (1<<2)
-// actually 1<<1 is Left Shift, 1<<0 is right shift
-#define SHIFT_PRESSED (1<<1 | 1 <<0)
-
-#endif
diff --git a/com32/cmenu/libmenu/tui.c b/com32/cmenu/libmenu/tui.c
index 81e40793..dd69277a 100644
--- a/com32/cmenu/libmenu/tui.c
+++ b/com32/cmenu/libmenu/tui.c
@@ -14,12 +14,12 @@
#include <string.h>
#include <com32.h>
#include <stdlib.h>
+#include "com32io.h"
com32sys_t inreg, outreg; // Global register sets for use
char bkspstr[] = " \b$";
char eolstr[] = "\n$";
-#define GETSTRATTR 0x07
// Reads a line of input from stdin. Replace CR with NUL byte
// password <> 0 implies not echoed on screen
@@ -29,18 +29,16 @@ char eolstr[] = "\n$";
void getuserinput(char *stra, unsigned int size, unsigned int password,
unsigned int showoldvalue)
{
- unsigned char c, scan;
+ unsigned int c;
char *p, *q; // p = current char of string, q = tmp
char *last; // The current last char of string
char *str; // pointer to string which is going to be allocated
- char page;
char row, col;
char start, end; // Cursor shape
char fudge; // How many chars should be removed from output
char insmode; // Are we in insert or overwrite
- page = getdisppage();
- getpos(&row, &col, page); // Get current position
+ getpos(&row, &col, 0); // Get current position
getcursorshape(&start, &end);
insmode = 1;
@@ -67,14 +65,14 @@ void getuserinput(char *stra, unsigned int size, unsigned int password,
// col is the corresponding column on the screen
if (password == 0) // Not a password, print initial value
{
- gotoxy(row, col, page);
+ gotoxy(row, col);
csprint(str, GETSTRATTR);
}
while (1) { // Do forever
- c = inputc(&scan);
- if (c == '\r')
+ c = get_key(stdin, 0);
+ if (c == KEY_ENTER)
break; // User hit Enter getout of loop
- if (scan == ESCAPE) // User hit escape getout and nullify string
+ if (c == KEY_ESC) // User hit escape getout and nullify string
{
*str = 0;
break;
@@ -83,18 +81,18 @@ void getuserinput(char *stra, unsigned int size, unsigned int password,
// if scan code is regognized do something
// else if char code is recognized do something
// else ignore
- switch (scan) {
- case HOMEKEY:
+ switch (c) {
+ case KEY_HOME:
p = str;
break;
- case ENDKEY:
+ case KEY_END:
p = last;
break;
- case LTARROW:
+ case KEY_LEFT:
if (p > str)
p--;
break;
- case CTRLLT:
+ case KEY_CTRL(KEY_LEFT):
if (p == str)
break;
if (*p == ' ')
@@ -110,11 +108,11 @@ void getuserinput(char *stra, unsigned int size, unsigned int password,
while ((p > str) && ((*p == ' ') || (*(p - 1) != ' ')))
p--;
break;
- case RTARROW:
+ case KEY_RIGHT:
if (p < last)
p++;
break;
- case CTRLRT:
+ case KEY_CTRL(KEY_RIGHT):
if (*p == 0)
break; // At end of string
if (*p != ' ')
@@ -125,7 +123,8 @@ void getuserinput(char *stra, unsigned int size, unsigned int password,
if (*p == ' ')
p++;
break;
- case DELETE:
+ case KEY_DEL:
+ case KEY_DELETE:
q = p;
while (*(q + 1)) {
*q = *(q + 1);
@@ -135,17 +134,14 @@ void getuserinput(char *stra, unsigned int size, unsigned int password,
last--;
fudge = 1;
break;
- case INSERT:
+ case KEY_INSERT:
insmode = 1 - insmode; // Switch mode
if (insmode == 0)
setcursorshape(1, 7); // Block cursor
else
setcursorshape(6, 7); // Normal cursor
break;
-
- default: // Unrecognized scan code, look at the ascii value
- switch (c) {
- case '\b': // Move over by one
+ case KEY_BACKSPACE: // Move over by one
q = p;
while (q <= last) {
*(q - 1) = *q;
@@ -157,7 +153,7 @@ void getuserinput(char *stra, unsigned int size, unsigned int password,
p--;
fudge = 1;
break;
- case '\x15': /* Ctrl-U: kill input */
+ case KEY_CTRL('U'): /* Ctrl-U: kill input */
fudge = last - str;
while (p > str)
*p-- = 0;
@@ -165,7 +161,7 @@ void getuserinput(char *stra, unsigned int size, unsigned int password,
*p = 0;
last = str;
break;
- default: // Handle insert and overwrite mode
+ default: // Handle insert and overwrite mode
if ((c >= ' ') && (c < 128) &&
((unsigned int)(p - str) < size - 1)) {
if (insmode == 0) { // Overwrite mode
@@ -189,190 +185,59 @@ void getuserinput(char *stra, unsigned int size, unsigned int password,
}
} else
beep();
- }
break;
}
// Now the string has been modified, print it
if (password == 0) {
- gotoxy(row, col, page);
+ gotoxy(row, col);
csprint(str, GETSTRATTR);
if (fudge > 0)
- cprint(' ', GETSTRATTR, fudge, page);
- gotoxy(row, col + (p - str), page);
+ cprint(' ', GETSTRATTR, fudge);
+ gotoxy(row, col + (p - str));
}
- }
+ } /* while */
*p = '\0';
if (password == 0)
csprint("\r\n", GETSTRATTR);
setcursorshape(start, end); // Block cursor
// If user hit ESCAPE so return without any changes
- if (scan != ESCAPE)
+ if (c != KEY_ESC)
strcpy(stra, str);
free(str);
}
-/* Print a C string (NUL-terminated) */
-void cswprint(const char *str, char attr, char left)
-{
- char page = getdisppage();
- char newattr = 0, cha, chb;
- char row, col;
- char nr, nc;
-
- nr = getnumrows();
- nc = getnumcols();
- getpos(&row, &col, page);
- while (*str) {
- switch (*str) {
- case '\b':
- --col;
- break;
- case '\n':
- ++row;
- col = left;
- break;
- case '\r':
- //col=left;
- break;
- case BELL: // Bell Char
- beep();
- break;
- case CHRELATTR: // change attribute (relatively)
- case CHABSATTR: // change attribute (absolute)
- cha = *(str + 1);
- chb = *(str + 2);
- if ((((cha >= '0') && (cha <= '9')) || ((cha >= 'A') && (cha <= 'F'))) && (((chb >= '0') && (chb <= '9')) || ((chb >= 'A') && (chb <= 'F')))) // Next two chars are legal
- {
- if ((cha >= 'A') && (cha <= 'F'))
- cha = cha - 'A' + 10;
- else
- cha = cha - '0';
- if ((chb >= 'A') && (chb <= 'F'))
- chb = chb - 'A' + 10;
- else
- chb = chb - '0';
- newattr = (cha << 4) + chb;
- attr = (*str == CHABSATTR ? newattr : attr ^ newattr);
- str += 2; // Will be incremented again later
- }
- break;
- default:
- putch(*str, attr, page);
- ++col;
- }
- if (col >= nc) {
- ++row;
- col = left;
- }
- if (row > nr) {
- scrollup();
- row = nr;
- }
- gotoxy(row, col, page);
- str++;
- }
-}
-
-void clearwindow(char top, char left, char bot, char right, char page,
- char fillchar, char fillattr)
-{
- char x;
- for (x = top; x < bot + 1; x++) {
- gotoxy(x, left, page);
- cprint(fillchar, fillattr, right - left + 1, page);
- }
-}
-
-void cls(void)
-{
- unsigned char dp = getdisppage();
- gotoxy(0, 0, dp);
- cprint(' ', GETSTRATTR, (1 + getnumrows()) * getnumcols(), dp);
-}
-
//////////////////////////////Box Stuff
-// This order of numbers must match
-// the values of BOX_TOPLEFT,... in the header file
-
-unsigned char SINSIN_CHARS[] = { 218, 192, 191, 217, //Corners
- 196, 179, // Horiz and Vertical
- 195, 180, 194, 193, 197
-}; // Connectors & Middle
-
-unsigned char DBLDBL_CHARS[] = { 201, 200, 187, 188, // Corners
- 205, 186, // Horiz and Vertical
- 199, 182, 203, 202, 206
-}; // Connectors & Middle
-
-unsigned char SINDBL_CHARS[] = { 214, 211, 183, 189, // Corners
- 196, 186, // Horiz & Vert
- 199, 182, 210, 208, 215
-}; // Connectors & Middle
-
-unsigned char DBLSIN_CHARS[] = { 213, 212, 184, 190, // Corners
- 205, 179, // Horiz & Vert
- 198, 181, 209, 207, 216
-}; // Connectors & Middle
-
-unsigned char *getboxchars(boxtype bt)
-{
- switch (bt) {
- case BOX_SINSIN:
- return SINSIN_CHARS;
- break;
- case BOX_DBLDBL:
- return DBLDBL_CHARS;
- break;
- case BOX_SINDBL:
- return SINDBL_CHARS;
- break;
- case BOX_DBLSIN:
- return DBLSIN_CHARS;
- break;
- default:
- return SINSIN_CHARS;
- break;
- }
- return SINSIN_CHARS;
-}
-
// Draw box and lines
-void drawbox(char top, char left, char bot, char right,
- char page, char attr, boxtype bt)
+void drawbox(const char top, const char left, const char bot,
+ const char right, const char attr)
{
- unsigned char *box_chars; // pointer to array of box chars
unsigned char x;
-
- box_chars = getboxchars(bt);
+ putchar(SO);
// Top border
- gotoxy(top, left, page);
- cprint(box_chars[BOX_TOPLEFT], attr, 1, page);
- gotoxy(top, left + 1, page);
- cprint(box_chars[BOX_TOP], attr, right - left, page);
- gotoxy(top, right, page);
- cprint(box_chars[BOX_TOPRIGHT], attr, 1, page);
+ gotoxy(top, left);
+ putch(TOP_LEFT_CORNER_BORDER, attr);
+ cprint(TOP_BORDER, attr, right - left - 1);
+ putch(TOP_RIGHT_CORNER_BORDER, attr);
// Bottom border
- gotoxy(bot, left, page);
- cprint(box_chars[BOX_BOTLEFT], attr, 1, page);
- gotoxy(bot, left + 1, page);
- cprint(box_chars[BOX_BOT], attr, right - left, page);
- gotoxy(bot, right, page);
- cprint(box_chars[BOX_BOTRIGHT], attr, 1, page);
+ gotoxy(bot, left);
+ putch(BOTTOM_LEFT_CORNER_BORDER, attr);
+ cprint(BOTTOM_BORDER, attr, right - left - 1);
+ putch(BOTTOM_RIGHT_CORNER_BORDER, attr);
// Left & right borders
for (x = top + 1; x < bot; x++) {
- gotoxy(x, left, page);
- cprint(box_chars[BOX_LEFT], attr, 1, page);
- gotoxy(x, right, page);
- cprint(box_chars[BOX_RIGHT], attr, 1, page);
+ gotoxy(x, left);
+ putch(LEFT_BORDER, attr);
+ gotoxy(x, right);
+ putch(RIGHT_BORDER, attr);
}
+ putchar(SI);
}
-void drawhorizline(char top, char left, char right, char page, char attr,
- boxtype bt, char dumb)
+void drawhorizline(const char top, const char left, const char right,
+ const char attr, char dumb)
{
unsigned char start, end;
- unsigned char *box_chars = getboxchars(bt);
if (dumb == 0) {
start = left + 1;
end = right - 1;
@@ -380,12 +245,14 @@ void drawhorizline(char top, char left, char right, char page, char attr,
start = left;
end = right;
}
- gotoxy(top, start, page);
- cprint(box_chars[BOX_HORIZ], attr, end - start + 1, page);
+ gotoxy(top, start);
+ putchar(SO);
+ cprint(MIDDLE_BORDER, attr, end - start + 1);
if (dumb == 0) {
- gotoxy(top, left, page);
- cprint(box_chars[BOX_LTRT], attr, 1, page);
- gotoxy(top, right, page);
- cprint(box_chars[BOX_RTLT], attr, 1, page);
+ gotoxy(top, left);
+ putch(MIDDLE_BORDER, attr);
+ gotoxy(top, right);
+ putch(MIDDLE_BORDER, attr);
}
+ putchar(SI);
}
diff --git a/com32/cmenu/libmenu/tui.h b/com32/cmenu/libmenu/tui.h
index 4df15327..ed554878 100644
--- a/com32/cmenu/libmenu/tui.h
+++ b/com32/cmenu/libmenu/tui.h
@@ -14,23 +14,32 @@
#define __TUI_H__
#include <com32.h>
+#include <getkey.h>
+#include <consoles.h>
#include "syslnx.h"
#include "com32io.h"
-#include "scancodes.h"
#ifndef NULL
#define NULL ((void *)0)
#endif
-#define BELL 0x07
-// CHRELATTR = ^N, CHABSATTR = ^O
-#define CHABSATTR 15
-#define CHRELATTR 14
-
-void clearwindow(char top, char left, char bot, char right,
- char page, char fillchar, char fillattr);
+#define SO '\016'
+#define SI '\017'
+
+#define TOP_LEFT_CORNER_BORDER '\154'
+#define TOP_BORDER '\161'
+#define TOP_RIGHT_CORNER_BORDER '\153'
+#define BOTTOM_LEFT_CORNER_BORDER '\155'
+#define BOTTOM_BORDER '\161'
+#define BOTTOM_RIGHT_CORNER_BORDER '\152'
+#define LEFT_BORDER '\170'
+#define RIGHT_BORDER '\170'
+#define LEFT_MIDDLE_BORDER '\164'
+#define MIDDLE_BORDER '\161'
+#define RIGHT_MIDDLE_BORDER '\165'
-void cls(void); /* Clears the entire current screen page */
+#define BELL 0x07
+#define GETSTRATTR 0x07
// Generic user input,
// password = 0 iff chars echoed on screen
@@ -53,35 +62,14 @@ static inline void getpwd(char *str, unsigned int size)
getuserinput(str, size, 1, 0);
}
-// Box drawing Chars offsets into array
-#define BOX_TOPLEFT 0x0
-#define BOX_BOTLEFT 0x1
-#define BOX_TOPRIGHT 0x2
-#define BOX_BOTRIGHT 0x3
-#define BOX_TOP 0x4 // TOP = BOT = HORIZ
-#define BOX_BOT 0x4
-#define BOX_HORIZ 0x4
-#define BOX_LEFT 0x5
-#define BOX_RIGHT 0x5
-#define BOX_VERT 0x5 // LEFT=RIGHT=VERT
-#define BOX_LTRT 0x6
-#define BOX_RTLT 0x7
-#define BOX_TOPBOT 0x8
-#define BOX_BOTTOP 0x9
-#define BOX_MIDDLE 0xA
-
-typedef enum { BOX_SINSIN, BOX_DBLDBL, BOX_SINDBL, BOX_DBLSIN } boxtype;
-
-unsigned char *getboxchars(boxtype bt);
-
-void drawbox(char top, char left, char bot, char right,
- char page, char attr, boxtype bt);
+void drawbox(const char, const char, const char, const char,
+ const char);
// Draw a horizontal line
// dumb == 1, means just draw the line
// dumb == 0 means check the first and last positions and depending on what is
// currently on the screen make it a LTRT and/or RTLT appropriately.
-void drawhorizline(char top, char left, char right, char page, char attr,
- boxtype bt, char dumb);
+void drawhorizline(const char, const char, const char, const char,
+ const char dumb);
#endif
diff --git a/com32/gplinclude/cpuid.h b/com32/gplinclude/cpuid.h
index 95d66e99..f85e6ab3 100644
--- a/com32/gplinclude/cpuid.h
+++ b/com32/gplinclude/cpuid.h
@@ -65,6 +65,8 @@ typedef struct {
bool nowext; /* AMD 3DNow! extensions */
bool now; /* 3DNow! */
bool smp; /* A smp configuration has been found */
+ bool vmx; /* Hardware virtualization */
+ bool svm; /* Secure virtual machine */
} s_cpu_flags;
typedef struct {
@@ -159,7 +161,6 @@ struct cpuinfo_x86 {
unsigned char x86_clflush_size;
} __attribute__ ((__packed__));
-#endif
struct cpu_model_info {
int vendor;
@@ -169,10 +170,10 @@ struct cpu_model_info {
/* attempt to consolidate cpu attributes */
struct cpu_dev {
- char *c_vendor;
+ const char *c_vendor;
/* some have two possibilities for cpuid string */
- char *c_ident[2];
+ const char *c_ident[2];
struct cpu_model_info c_models[4];
@@ -208,3 +209,4 @@ struct intel_mp_floating {
extern void get_cpu_vendor(struct cpuinfo_x86 *c);
extern void detect_cpu(s_cpu * cpu);
+#endif
diff --git a/com32/gplinclude/disk/bootloaders.h b/com32/gplinclude/disk/bootloaders.h
new file mode 100644
index 00000000..6aec9b3d
--- /dev/null
+++ b/com32/gplinclude/disk/bootloaders.h
@@ -0,0 +1,18 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef __BOOTLOADERS_H_
+#define __BOOTLOADERS_H_
+
+#include <stdint.h>
+#include <disk/geom.h>
+#include <disk/partition.h>
+
+int get_bootloader_string(const struct driveinfo *, const struct part_entry *, char*, const int);
+#endif /* __BOOTLOADERS_H_ */
diff --git a/com32/gplinclude/disk/common.h b/com32/gplinclude/disk/common.h
index c6df2f4e..627e94ec 100644
--- a/com32/gplinclude/disk/common.h
+++ b/com32/gplinclude/disk/common.h
@@ -17,10 +17,10 @@
#include <stdint.h>
-#define SECTOR 512 /* bytes/sector */
+/* For PAGE_SIZE */
+#include <cpuid.h>
-#undef PAGE_SIZE
-#define PAGE_SIZE (1<<12)
+#define SECTOR 512 /* bytes/sector */
struct ebios_dapa {
uint16_t len;
diff --git a/com32/gplinclude/disk/error.h b/com32/gplinclude/disk/error.h
index f9e319c4..27683572 100644
--- a/com32/gplinclude/disk/error.h
+++ b/com32/gplinclude/disk/error.h
@@ -9,5 +9,5 @@
#ifndef _ERROR_H_
#define _ERROR_H_
-void get_error(void*);
-#endif /* _UTIL_H_ */
+void get_error(const char*);
+#endif /* _ERROR_H_ */
diff --git a/com32/gplinclude/disk/mbrs.h b/com32/gplinclude/disk/mbrs.h
new file mode 100644
index 00000000..ad104ff7
--- /dev/null
+++ b/com32/gplinclude/disk/mbrs.h
@@ -0,0 +1,18 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef __MBRS_H_
+#define __MBRS_H_
+
+#include <stdint.h>
+#include <disk/geom.h>
+
+void get_mbr_string(const uint32_t, void *, const int);
+uint32_t get_mbr_id(const struct driveinfo *);
+#endif /* __MBRS_H_ */
diff --git a/com32/gplinclude/disk/util.h b/com32/gplinclude/disk/util.h
index df2eadda..20a9428f 100644
--- a/com32/gplinclude/disk/util.h
+++ b/com32/gplinclude/disk/util.h
@@ -18,5 +18,4 @@
#include <com32.h>
int int13_retry(const com32sys_t *inreg, com32sys_t *outreg);
-void get_error(const int, char**);
#endif /* _UTIL_H_ */
diff --git a/com32/gplinclude/dmi/dmi.h b/com32/gplinclude/dmi/dmi.h
index def0a8ea..72bc8dc4 100644
--- a/com32/gplinclude/dmi/dmi.h
+++ b/com32/gplinclude/dmi/dmi.h
@@ -13,6 +13,7 @@
#ifndef DMI_H
#define DMI_H
#include <inttypes.h>
+#define DMI_BUFFER_SIZE 16
#define MAX_DMI_MEMORY_ITEMS 32
#define MAX_DMI_CACHE_ITEMS 32
#define OEM_STRINGS_SIZE 512
@@ -86,7 +87,7 @@ typedef struct {
void to_dmi_header(struct dmi_header *h, uint8_t * data);
void dmi_bios_runtime_size(uint32_t code, s_dmi * dmi);
const char *dmi_string(struct dmi_header *dm, uint8_t s);
-int dmi_checksum(uint8_t * buf);
+int dmi_checksum(uint8_t * buf, int len);
void parse_dmitable(s_dmi * dmi);
void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi);
int dmi_iterate(s_dmi * dmi);
diff --git a/com32/gpllib/cpuid.c b/com32/gpllib/cpuid.c
index 6d464c7e..fb69cef6 100644
--- a/com32/gpllib/cpuid.c
+++ b/com32/gpllib/cpuid.c
@@ -295,6 +295,8 @@ void set_cpu_flags(struct cpuinfo_x86 *c, s_cpu * cpu)
cpu->flags.nowext = cpu_has(c, X86_FEATURE_3DNOWEXT);
cpu->flags.now = cpu_has(c, X86_FEATURE_3DNOW);
cpu->flags.smp = find_smp_config();
+ cpu->flags.vmx = cpu_has(c, X86_FEATURE_VMX);
+ cpu->flags.svm = cpu_has(c, X86_FEATURE_SVM);
}
void set_generic_info(struct cpuinfo_x86 *c, s_cpu * cpu)
diff --git a/com32/gpllib/disk/ata.c b/com32/gpllib/disk/ata.c
index d74dda8f..8694470d 100644
--- a/com32/gpllib/disk/ata.c
+++ b/com32/gpllib/disk/ata.c
@@ -1,4 +1,5 @@
#include <inttypes.h>
+#include <string.h>
/**
* ata_id_string - Convert IDENTIFY DEVICE page into string
diff --git a/com32/gpllib/disk/bootloaders.c b/com32/gpllib/disk/bootloaders.c
new file mode 100644
index 00000000..4b3962ae
--- /dev/null
+++ b/com32/gpllib/disk/bootloaders.c
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <disk/bootloaders.h>
+#include <disk/common.h>
+#include <disk/geom.h>
+#include <disk/read.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * get_bootloader_string - return a string describing the boot code in a
+ * bootsector
+ * @d: driveinfo struct describing the drive
+ * @p: partition to scan (usually the active one)
+ * @buffer: pre-allocated buffer
+ * @buffer_size: @buffer size
+ **/
+int get_bootloader_string(const struct driveinfo *d, const struct part_entry *p,
+ char* buffer, const int buffer_size)
+{
+ char boot_sector[SECTOR * sizeof(char)];
+
+ if (read_sectors(d, &boot_sector, p->start_lba, 1) == -1)
+ return -1;
+ else {
+ if (!strncmp(boot_sector + 3, "SYSLINUX", 8))
+ strncpy(buffer, "SYSLINUX", buffer_size - 1);
+ else if (!strncmp(boot_sector + 3, "EXTLINUX", 8))
+ strncpy(buffer, "EXTLINUX", buffer_size - 1);
+ else if (!strncmp(boot_sector + 3, "MSWIN4.1", 8))
+ strncpy(buffer, "MSWIN4.1", buffer_size - 1);
+ else
+ return -1;
+ /* Add more... */
+
+ buffer[buffer_size - 1] = '\0';
+ return 0;
+ }
+}
diff --git a/com32/gpllib/disk/error.c b/com32/gpllib/disk/error.c
index 1853092b..b3fb6ce1 100644
--- a/com32/gpllib/disk/error.c
+++ b/com32/gpllib/disk/error.c
@@ -13,7 +13,7 @@
/**
* get_error - decode a disk error status
- * @buffer_ptr: Preallocated buffer
+ * @s: Preallocated buffer
*
* Fill @buffer_ptr with the last errno_disk
**/
diff --git a/com32/gpllib/disk/mbrs.c b/com32/gpllib/disk/mbrs.c
new file mode 100644
index 00000000..0abf087a
--- /dev/null
+++ b/com32/gpllib/disk/mbrs.c
@@ -0,0 +1,91 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <disk/common.h>
+#include <disk/geom.h>
+#include <disk/read.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+/**
+ * get_mbr_string - return a string describing the boot code
+ * @label: first four bytes of the MBR
+ * @buffer: pre-allocated buffer
+ * @buffer_size: @buffer size
+ **/
+void get_mbr_string(const uint32_t label, char* buffer, const int buffer_size)
+{
+ /* 2 bytes are usually enough to identify the MBR */
+ uint16_t s_label = label >> 16;
+
+ switch (s_label) {
+ case 0x0000:
+ case 0xfa33:
+ case 0xfab8:
+ case 0xfabe:
+ strncpy(buffer, "No bootloader", buffer_size - 1); break;
+ case 0x0ebe: strncpy(buffer, "ThinkPad", buffer_size - 1); break;
+ case 0x31c0: strncpy(buffer, "Acer 3", buffer_size - 1); break;
+ case 0x33c0: strncpy(buffer, "Windows", buffer_size - 1); break;
+ case 0x33ff: strncpy(buffer, "HP/Gateway", buffer_size - 1); break;
+ case 0xb800: strncpy(buffer, "Plop", buffer_size - 1); break;
+ case 0xea1e: strncpy(buffer, "Truecrypt Boot Loader", buffer_size - 1); break;
+ case 0xeb04: strncpy(buffer, "Solaris", buffer_size - 1); break;
+ case 0xeb48: strncpy(buffer, "Grub", buffer_size - 1); break;
+ case 0xeb63:
+ case 0xeb4c: strncpy(buffer, "Grub2", buffer_size - 1); break;
+ case 0xeb5e:
+ /* We need more than 2 bytes */
+ if (((label >> 8) & 0xff) == 0x00)
+ strncpy(buffer, "fbinst", buffer_size - 1);
+ else if (((label >> 8) & 0xff) == 0x80)
+ strncpy(buffer, "Grub4Dos", buffer_size - 1);
+ else
+ strncpy(buffer, "Unknown mbr", buffer_size - 1); break;
+ break;
+ case 0xfa31:
+ /* We need more than 2 bytes */
+ if (((label >> 8) & 0xff) == 0xc9)
+ strncpy(buffer, "Master Boot LoaDeR", buffer_size - 1);
+ else if (((label >> 8) & 0xff) == 0xc0)
+ strncpy(buffer, "Syslinux", buffer_size - 1);
+ else
+ strncpy(buffer, "Unknown mbr", buffer_size - 1); break;
+ break;
+ case 0xfaeb: strncpy(buffer, "Lilo", buffer_size - 1); break;
+ case 0xfc31: strncpy(buffer, "Testdisk", buffer_size - 1); break;
+ case 0xfc33: strncpy(buffer, "Gag", buffer_size - 1); break;
+ case 0xfceb: strncpy(buffer, "BootIT NG", buffer_size - 1); break;
+ default: strncpy(buffer, "Unknown mbr", buffer_size - 1); break;
+ }
+
+ buffer[buffer_size - 1] = '\0';
+}
+
+/**
+ * get_mbr_id - return the first four bytes of the MBR
+ * @d: driveinfo struct describing the drive
+ **/
+uint32_t get_mbr_id(const struct driveinfo *d)
+{
+ char mbr[SECTOR * sizeof(char)];
+
+ if (read_mbr(d->disk, &mbr) == -1)
+ return -1;
+ else {
+ uint32_t mbr_id;
+ /* Reverse the opcodes */
+ mbr_id = (*(uint8_t *) (mbr + 3));
+ mbr_id += (*(uint8_t *) (mbr + 2) << 8);
+ mbr_id += (*(uint8_t *) (mbr + 1) << 16);
+ mbr_id += (*(uint8_t *) mbr) << 24;
+ return mbr_id;
+ }
+}
diff --git a/com32/gpllib/dmi/dmi.c b/com32/gpllib/dmi/dmi.c
index ebf3c527..9f770376 100644
--- a/com32/gpllib/dmi/dmi.c
+++ b/com32/gpllib/dmi/dmi.c
@@ -406,7 +406,6 @@ static void dmi_processor_id(uint8_t type, uint8_t * p, const char *version,
for (i = 0; i <= 31; i++)
if (cpu_flags_strings[i] != NULL && edx & (1 << i))
((bool *) (&dmi->processor.cpu_flags))[i] = true;
- //printf("%s\t%s\n", prefix, flags[i]);
}
}
@@ -445,20 +444,67 @@ const char *dmi_string(struct dmi_header *dm, uint8_t s)
return bp;
}
-int dmi_checksum(uint8_t * buf)
+int checksum(uint8_t * buf, int len)
{
uint8_t sum = 0;
int a;
- for (a = 0; a < 15; a++)
+ for (a = 0; a < len; a++)
sum += buf[a];
return (sum == 0);
}
+static int smbios_decode(s_dmi *dmi, uint8_t *buf)
+{
+
+ dmi->dmitable.ver = (buf[0x06] << 8) + buf[0x07];
+ /* Some BIOS report weird SMBIOS version, fix that up */
+ switch (dmi->dmitable.ver) {
+ case 0x021F:
+ dmi->dmitable.ver = 0x0203;
+ break;
+ case 0x0233:
+ dmi->dmitable.ver = 0x0206;
+ break;
+ }
+ dmi->dmitable.major_version=dmi->dmitable.ver >> 8;
+ dmi->dmitable.minor_version=dmi->dmitable.ver & 0xFF;
+
+ return DMI_TABLE_PRESENT;
+}
+
+
+static int legacy_decode(s_dmi *dmi, uint8_t *buf)
+{
+ dmi->dmitable.num = buf[13] << 8 | buf[12];
+ dmi->dmitable.len = buf[7] << 8 | buf[6];
+ dmi->dmitable.base =
+ buf[11] << 24 | buf[10] << 16 | buf[9] << 8 | buf[8];
+
+ /* Version already found? */
+ if (dmi->dmitable.ver>0) return DMI_TABLE_PRESENT;
+
+ dmi->dmitable.ver = (buf[0x06] << 8) + buf[0x07];
+
+ /*
+ * DMI version 0.0 means that the real version is taken from
+ * the SMBIOS version, which we don't know at this point.
+ */
+ if (buf[14] != 0) {
+ dmi->dmitable.major_version = buf[14] >> 4;
+ dmi->dmitable.minor_version = buf[14] & 0x0F;
+ } else {
+ dmi->dmitable.major_version = 0;
+ dmi->dmitable.minor_version = 0;
+ }
+ return DMI_TABLE_PRESENT;
+}
+
+
int dmi_iterate(s_dmi * dmi)
{
- uint8_t buf[16];
- char *p, *q;
+ uint8_t *p, *q;
+ int found = 0;
/* Cleaning structures */
memset(&dmi->base_board, 0, sizeof(s_base_board));
@@ -480,34 +526,32 @@ int dmi_iterate(s_dmi * dmi)
dmi->processor.filled = false;
dmi->system.filled = false;
- p = (char *)0xF0000; /* The start address to look at the dmi table */
+ p = (uint8_t *)0xF0000; /* The start address to look at the dmi table */
+ /* The anchor-string is 16-bytes aligned */
for (q = p; q < p + 0x10000; q += 16) {
- memcpy(buf, q, 15);
- if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf)) {
- dmi->dmitable.num = buf[13] << 8 | buf[12];
- dmi->dmitable.len = buf[7] << 8 | buf[6];
- dmi->dmitable.base =
- buf[11] << 24 | buf[10] << 16 | buf[9] << 8 | buf[8];
- dmi->dmitable.ver = (buf[0x06] << 8) + buf[0x07];
-
- /*
- * DMI version 0.0 means that the real version is taken from
- * the SMBIOS version, which we don't know at this point.
- */
- if (buf[14] != 0) {
- dmi->dmitable.major_version = buf[14] >> 4;
- dmi->dmitable.minor_version = buf[14] & 0x0F;
- } else {
- dmi->dmitable.major_version = 0;
- dmi->dmitable.minor_version = 0;
-
- }
-/* printf("DMI present (version %d.%d)\n", dmitable.major_version,dmitable.minor_version);
- printf("%d structures occupying %d bytes.\n",dmitable.num, dmitable.len);
- printf("DMI table at 0x%08X.\n",dmitable.base);*/
- return DMI_TABLE_PRESENT;
- }
+ /* To validate the presence of SMBIOS:
+ * + the overall checksum must be correct
+ * + the intermediate anchor-string must be _DMI_
+ * + the intermediate checksum must be correct
+ */
+ if (memcmp(q, "_SM_", 4) == 0 &&
+ checksum(q, q[0x05]) &&
+ memcmp(q + 0x10, "_DMI_", 5)==0 &&
+ checksum(q + 0x10, 0x0F)) {
+ /* Do not return, legacy_decode will need to be called
+ * on the intermediate structure to get the table length
+ * and address
+ */
+ smbios_decode(dmi, q);
+ } else if (memcmp(q, "_DMI_", 5) == 0 && checksum(q, 0x0F)) {
+ found = 1;
+ legacy_decode(dmi, q);
+ }
}
+
+ if (found)
+ return DMI_TABLE_PRESENT;
+
dmi->dmitable.base = 0;
dmi->dmitable.num = 0;
dmi->dmitable.ver = 0;
@@ -524,7 +568,6 @@ void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi)
*/
switch (h->type) {
case 0: /* 3.3.1 BIOS Information */
-// printf("BIOS Information\n");
if (h->length < 0x12)
break;
dmi->bios.filled = true;
@@ -552,7 +595,6 @@ void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi)
data[0x16], data[0x17]);
break;
case 1: /* 3.3.2 System Information */
-// printf("System Information\n");
if (h->length < 0x08)
break;
dmi->system.filled = true;
@@ -571,7 +613,6 @@ void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi)
break;
case 2: /* 3.3.3 Base Board Information */
-// printf("Base Board Information\n");
if (h->length < 0x08)
break;
dmi->base_board.filled = true;
@@ -589,7 +630,6 @@ void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi)
break;
break;
case 3: /* 3.3.4 Chassis Information */
-// printf("Chassis Information\n");
if(h->length<0x09) break;
dmi->chassis.filled=true;
strcpy(dmi->chassis.manufacturer,dmi_string(h,data[0x04]));
@@ -611,7 +651,6 @@ void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi)
break;
case 4: /* 3.3.5 Processor Information */
-// printf("Processor Information\n");
if(h->length<0x1A) break;
dmi->processor.filled=true;
strcpy(dmi->processor.socket_designation,dmi_string(h, data[0x04]));
@@ -628,7 +667,7 @@ void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi)
strcpy(dmi->processor.status,dmi_processor_status(data[0x18]&0x07));
else
sprintf(dmi->processor.status,"Unpopulated");
- sprintf(dmi->processor.upgrade,dmi_processor_upgrade(data[0x19]));
+ strcpy(dmi->processor.upgrade,dmi_processor_upgrade(data[0x19]));
if(h->length<0x20) break;
dmi_processor_cache(WORD(data+0x1A), "L1", ver,dmi->processor.cache1);
dmi_processor_cache(WORD(data+0x1C), "L2", ver,dmi->processor.cache2);
@@ -843,7 +882,6 @@ void parse_dmitable(s_dmi * dmi)
(unsigned int)h.length);
break;
}
-// printf("Handle 0x%04X, DMI type %d, %d bytes\n", h.handle, h.type, h.length);
/* loo for the next handle */
next = data + h.length;
diff --git a/com32/gpllib/dmi/dmi_memory.c b/com32/gpllib/dmi/dmi_memory.c
index 588e4ad6..5c747d69 100644
--- a/com32/gpllib/dmi/dmi_memory.c
+++ b/com32/gpllib/dmi/dmi_memory.c
@@ -242,9 +242,9 @@ void dmi_memory_module_size(uint8_t code, char* size)
}
if(code&0x80)
- printf(size, "%s", "(Double-bank Connection)");
+ sprintf(size, "%s", "(Double-bank Connection)");
else
- printf(size, "%s", "(Single-bank Connection)");
+ sprintf(size, "%s", "(Single-bank Connection)");
}
void dmi_memory_module_error(uint8_t code, const char *prefix, char *error)
@@ -253,10 +253,10 @@ void dmi_memory_module_error(uint8_t code, const char *prefix, char *error)
sprintf(error, "%s", "See Event Log\n");
else
{ if((code&0x03)==0)
- printf(error, "%s", "OK\n");
+ sprintf(error, "%s", "OK\n");
if(code&(1<<0))
- printf(error, "%sUncorrectable Errors\n", prefix);
+ sprintf(error, "%sUncorrectable Errors\n", prefix);
if(code&(1<<1))
- printf(error, "%sCorrectable Errors\n", prefix);
+ sprintf(error, "%sCorrectable Errors\n", prefix);
}
}
diff --git a/com32/hdt/Makefile b/com32/hdt/Makefile
index 8f8cae21..b3eb88dc 100644
--- a/com32/hdt/Makefile
+++ b/com32/hdt/Makefile
@@ -27,11 +27,55 @@ TESTFILES =
OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
+KERNEL_VERSION ?= $(shell uname -r)
+MODULES_ALIAS_FILE ?= /lib/modules/$(KERNEL_VERSION)/modules.alias
+MODULES_PCIMAP_FILE ?= /lib/modules/$(KERNEL_VERSION)/modules.pcimap
+ISO_DIR ?= iso
+ISOLINUX_DIR ?= isolinux
+FLOPPY_DIR ?= floppy
+PCI_IDS_FILE ?= $(PWD)/$(FLOPPY_DIR)/pci.ids
+REBOOT_COM32 ?= $(com32)/modules/reboot.c32
+
all: $(MODULES) $(TESTFILES)
hdt.elf : $(OBJS) $(LIBS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
+hdt.img: hdt.c32 $(FLOPPY_DIR)/hdt.cfg $(FLOPPY_DIR)/mtools.conf $(topdir)/mtools/syslinux $(REBOOT_COM32)
+ rm -f hdt.img
+ MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MFORMAT) -v HDT -f 2880 -C a:
+ $(topdir)/mtools/syslinux hdt.img
+ -[ ! -f $(PCI_IDS_FILE) ] && cp /usr/share/hwdata/pci.ids $(PCI_IDS_FILE)
+ -[ ! -f $(PCI_IDS_FILE) ] && cp /usr/share/pci.ids $(PCI_IDS_FILE)
+ -[ -f $(MODULES_ALIAS_FILE) ] && MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(MODULES_ALIAS_FILE) a:
+ -[ -f $(MODULES_PCIMAP_FILE) ] && MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(MODULES_PCIMAP_FILE) a:
+ MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) hdt.c32 a:
+ MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(REBOOT_COM32) a:
+ @ [ -f $(PCI_IDS_FILE) ] && MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(PCI_IDS_FILE) a: || printf "\nThe $(FLOPPY_DIR)/pci.ids file is missing and can be downloaded from http://pciids.sourceforge.net and put in\nthe ./com32/hdt/$(FLOPPY_DIR) directory of the extracted Syslinux source.\n\n"
+ MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(FLOPPY_DIR)/hdt.cfg a:syslinux.cfg
+
+hdt.img.gz: hdt.img
+ rm -rf hdt.img.gz
+ $(GZIPPROG) -c hdt.img >hdt.img.gz
+
+hdt.iso: hdt.c32 $(topdir)/core/isolinux.bin $(FLOPPY_DIR)/hdt.cfg
+ rm -rf $(ISO_DIR)
+ rm -f hdt.iso
+ mkdir -p $(ISO_DIR)/$(ISOLINUX_DIR)
+ cp $(topdir)/core/isolinux.bin $(ISO_DIR)/$(ISOLINUX_DIR)
+ cp $(FLOPPY_DIR)/hdt.cfg $(ISO_DIR)/$(ISOLINUX_DIR)/isolinux.cfg
+ cp hdt.c32 $(ISO_DIR)/$(ISOLINUX_DIR)
+ cp $(REBOOT_COM32) $(ISO_DIR)/$(ISOLINUX_DIR)
+ -[ ! -f $(PCI_IDS_FILE) ] && cp /usr/share/hwdata/pci.ids $(PCI_IDS_FILE)
+ -[ ! -f $(PCI_IDS_FILE) ] && cp /usr/share/pci.ids $(PCI_IDS_FILE)
+ -[ -f $(MODULES_ALIAS_FILE) ] && cp $(MODULES_ALIAS_FILE) $(ISO_DIR)/$(ISOLINUX_DIR)
+ -[ -f $(MODULES_PCIMAP_FILE) ] && cp $(MODULES_PCIMAP_FILE) $(ISO_DIR)/$(ISOLINUX_DIR)
+ -[ ! -f $(ISO_DIR)/$(ISOLINUX_DIR)/pci.ids ] && cp $(PCI_IDS_FILE) $(ISO_DIR)/$(ISOLINUX_DIR)
+ -[ ! -f $(ISO_DIR)/$(ISOLINUX_DIR)/pci.ids ] && printf "\nThe $(FLOPPY_DIR)/pci.ids file is missing and can be downloaded from http://pciids.sourceforge.net and put in\nthe ./com32/hdt/$(FLOPPY_DIR) directory of the extracted Syslinux source.\n\n"
+ $(MKISOFS) -o hdt.iso -b $(ISOLINUX_DIR)/isolinux.bin -c $(ISOLINUX_DIR)/boot.cat \
+ -no-emul-boot -boot-load-size 4 -boot-info-table \
+ $(ISO_DIR)
+
tidy dist:
rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
@@ -39,7 +83,8 @@ clean: tidy
rm -f *.lnx
spotless: clean
- rm -f *.lss *.c32 *.com
+ rm -f *.lss *.c32 *.com hdt.img hdt.iso
+ rm -rf $(ISO_DIR)
rm -f *~ \#*
install:
diff --git a/com32/hdt/README b/com32/hdt/README
new file mode 100644
index 00000000..8e171616
--- /dev/null
+++ b/com32/hdt/README
@@ -0,0 +1,19 @@
+--------------
+Compiling HDT
+--------------
+To build HDT, you just have to do a "make" call in this directory.
+
+---------------------------
+Creating a bootable floppy
+--------------------------
+To build a bootable HDT floppy image, you can do a "make hdt.img" call.
+This will requires the mtools (http://mtools.linux.lu) to be installed.
+The script will try to pick several files from your system :
+- /lib/modules/`uname -r`/modules.alias
+- /lib/modules/`uname -r`/modules.pcimap
+- /usr/share/pci.ids or /usr/share/hwdata/pci.ids
+
+This paths can be overrided with the following command line:
+make MODULES_ALIAS_FILE=$(PWD)/floppy/modules.alias MODULES_PCIMAP_FILE=$(PWD)/floppy/modules.pcimap PCI_IDS_FILE=$(PWD)/floppy/pci.ids hdt.img
+
+If your system doesn't have pci.ids, please download it from http://pciids.sourceforge.net/ and put it into the floppy/ directory.
diff --git a/com32/hdt/floppy/hdt.cfg b/com32/hdt/floppy/hdt.cfg
new file mode 100644
index 00000000..8f707d0f
--- /dev/null
+++ b/com32/hdt/floppy/hdt.cfg
@@ -0,0 +1,7 @@
+DEFAULT hdt
+PROMPT 0
+SERIAL 0
+
+LABEL hdt
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids
diff --git a/com32/hdt/floppy/mtools.conf b/com32/hdt/floppy/mtools.conf
new file mode 100644
index 00000000..adbe2c83
--- /dev/null
+++ b/com32/hdt/floppy/mtools.conf
@@ -0,0 +1,2 @@
+# Floppy image for HDT
+drive a: file="hdt.img"
diff --git a/com32/hdt/hdt-cli-cpu.c b/com32/hdt/hdt-cli-cpu.c
index f0f0a1bb..d2b5979f 100644
--- a/com32/hdt/hdt-cli-cpu.c
+++ b/com32/hdt/hdt-cli-cpu.c
@@ -174,6 +174,10 @@ static void show_cpu(int argc __unused, char **argv __unused,
strcat(buffer1, "3dnowext ");
if (hardware->cpu.flags.now)
strcat(buffer1, "3dnow! ");
+ if (hardware->cpu.flags.svm)
+ strcat(buffer1, "svm ");
+ if (hardware->cpu.flags.vmx)
+ strcat(buffer1, "vmx ");
if (buffer1[0]) {
snprintf(buffer, sizeof buffer, "Flags : %s\n", buffer1);
more_printf(buffer);
diff --git a/com32/hdt/hdt-cli-disk.c b/com32/hdt/hdt-cli-disk.c
index 4e2994d9..7f6b00db 100644
--- a/com32/hdt/hdt-cli-disk.c
+++ b/com32/hdt/hdt-cli-disk.c
@@ -31,13 +31,6 @@
#include <stdlib.h>
#include <errno.h>
-#include <disk/errno_disk.h>
-#include <disk/geom.h>
-#include <disk/read.h>
-#include <disk/error.h>
-#include <disk/swsusp.h>
-#include <disk/msdos.h>
-
#include "hdt-cli.h"
#include "hdt-common.h"
#include "hdt-util.h"
@@ -63,11 +56,14 @@ static void show_partition_information(struct driveinfo *drive_info,
int nb_partitions_seen)
{
char size[9];
+ char bootloader_name[9];
char *parttype;
unsigned int start, end;
int i = nb_partitions_seen;
+ reset_more_printf();
+
start = partition_offset;
end = start + ptab->length - 1;
@@ -77,10 +73,10 @@ static void show_partition_information(struct driveinfo *drive_info,
memset(size, 0, sizeof size);
if (i == 1)
- more_printf(" # B Start End Size Id Type\n");
+ more_printf(" # B Start End Size Id Type\n");
get_label(ptab->ostype, &parttype);
- more_printf(" %2d %s %11d %11d %s %02X %s",
+ more_printf("%2d %s %11d %11d %s %02X %s",
i, (ptab->active_flag == 0x80) ? "x" : " ",
start,
end,
@@ -91,6 +87,9 @@ static void show_partition_information(struct driveinfo *drive_info,
if (ptab->ostype == 0x82 && swsusp_check(drive_info, ptab))
more_printf("%s", " (Swsusp sig. detected)");
+ if (get_bootloader_string(drive_info, ptab, bootloader_name, 9) == 0)
+ more_printf("%-46s %s %s", " ", "Bootloader:", bootloader_name);
+
more_printf("\n");
free(parttype);
@@ -99,7 +98,6 @@ static void show_partition_information(struct driveinfo *drive_info,
void main_show_disk(int argc, char **argv,
struct s_hardware *hardware)
{
- reset_more_printf();
if (!argc) {
more_printf("Which disk?\n");
return;
@@ -115,11 +113,16 @@ void main_show_disk(int argc, char **argv,
int i = drive - 0x80;
struct driveinfo *d = &hardware->disk_info[i];
char disk_size[9];
+ char mbr_name[50];
detect_disks(hardware);
+ reset_more_printf();
+
if (!hardware->disk_info[i].cbios)
return; /* Invalid geometry */
+ get_mbr_string(hardware->mbr_ids[i], &mbr_name, 50);
+
if ((int) d->edd_params.sectors > 0)
sectors_to_size((int) d->edd_params.sectors, disk_size);
else
@@ -127,14 +130,17 @@ void main_show_disk(int argc, char **argv,
more_printf("DISK 0x%X:\n"
" C/H/S: %d cylinders, %d heads, %d sectors/track\n"
- " EDD: Version: %X\n"
+ " EDD: Version: %X\n"
" Size: %s, %d bytes/sector, %d sectors/track\n"
- " Host bus: %s, Interface type: %s\n\n",
+ " Host bus: %s, Interface type: %s\n"
+ " MBR: %s (id 0x%X)\n\n",
d->disk,
d->legacy_max_cylinder + 1, d->legacy_max_head + 1, d->legacy_sectors_per_track,
d->edd_version,
disk_size, (int) d->edd_params.bytes_per_sector, (int) d->edd_params.sectors_per_track,
- remove_spaces(d->edd_params.host_bus_type), remove_spaces(d->edd_params.interface_type));
+ remove_spaces((char *) d->edd_params.host_bus_type), remove_spaces((char*) d->edd_params.interface_type),
+ mbr_name, hardware->mbr_ids[i]);
+ display_line_nb += 6;
if (parse_partition_table(d, &show_partition_information)) {
if (errno_disk) {
@@ -145,6 +151,8 @@ void main_show_disk(int argc, char **argv,
}
fprintf(stderr, "\n");
}
+
+ more_printf("\n");
}
void main_show_disks(int argc __unused, char **argv __unused,
@@ -153,11 +161,19 @@ void main_show_disks(int argc __unused, char **argv __unused,
reset_more_printf();
detect_disks(hardware);
+ int first_one = 0;
for (int drive = 0x80; drive < 0xff; drive++) {
- char buf[5] = "";
- sprintf(buf, "0x%x", drive);
- char *argv[1] = { buf };
- main_show_disk(1, argv, hardware);
+ if (hardware->disk_info[drive - 0x80].cbios) {
+ if (!first_one) {
+ first_one = 1;
+ } else {
+ pause_printf();
+ }
+ char buf[5] = "";
+ sprintf(buf, "0x%x", drive);
+ char *argv[1] = { buf };
+ main_show_disk(1, argv, hardware);
+ }
}
}
@@ -167,6 +183,7 @@ void disks_summary(int argc __unused, char** argv __unused,
int i = -1;
detect_disks(hardware);
+ reset_more_printf();
for (int drive = 0x80; drive < 0xff; drive++) {
i++;
@@ -187,8 +204,8 @@ void disks_summary(int argc __unused, char** argv __unused,
more_printf(" EDD: Version: %X, size: %s\n", d->edd_version,
disk_size);
more_printf(" Host bus: %s, Interface type: %s\n\n",
- remove_spaces(d->edd_params.host_bus_type),
- remove_spaces(d->edd_params.interface_type));
+ remove_spaces((char*) d->edd_params.host_bus_type),
+ remove_spaces((char*) d->edd_params.interface_type));
}
}
diff --git a/com32/hdt/hdt-cli-dmi.c b/com32/hdt/hdt-cli-dmi.c
index fca94cdc..194cded3 100644
--- a/com32/hdt/hdt-cli-dmi.c
+++ b/com32/hdt/hdt-cli-dmi.c
@@ -38,48 +38,49 @@ static void show_dmi_modules(int argc __unused, char** argv __unused,
struct s_hardware *hardware)
{
char available_dmi_commands[1024];
+ reset_more_printf();
memset(available_dmi_commands, 0, sizeof(available_dmi_commands));
- printf("Available DMI modules on your system:\n");
+ more_printf("Available DMI modules on your system:\n");
if (hardware->dmi.base_board.filled == true)
- printf("\t%s\n", CLI_DMI_BASE_BOARD);
+ more_printf("\t%s\n", CLI_DMI_BASE_BOARD);
if (hardware->dmi.battery.filled == true)
- printf("\t%s\n", CLI_DMI_BATTERY);
+ more_printf("\t%s\n", CLI_DMI_BATTERY);
if (hardware->dmi.bios.filled == true)
- printf("\t%s\n", CLI_DMI_BIOS);
+ more_printf("\t%s\n", CLI_DMI_BIOS);
if (hardware->dmi.chassis.filled == true)
- printf("\t%s\n", CLI_DMI_CHASSIS);
+ more_printf("\t%s\n", CLI_DMI_CHASSIS);
for (int i = 0; i < hardware->dmi.memory_count; i++) {
if (hardware->dmi.memory[i].filled == true) {
- printf("\tbank <number>\n");
+ more_printf("\tbank <number>\n");
break;
}
}
for (int i = 0; i < hardware->dmi.memory_module_count; i++) {
if (hardware->dmi.memory_module[i].filled == true) {
- printf("\tmodule <number>\n");
+ more_printf("\tmodule <number>\n");
break;
}
}
if (hardware->dmi.processor.filled == true)
- printf("\t%s\n", CLI_DMI_PROCESSOR);
+ more_printf("\t%s\n", CLI_DMI_PROCESSOR);
if (hardware->dmi.system.filled == true)
- printf("\t%s\n", CLI_DMI_SYSTEM);
+ more_printf("\t%s\n", CLI_DMI_SYSTEM);
if (hardware->dmi.ipmi.filled == true)
- printf("\t%s\n", CLI_DMI_IPMI);
+ more_printf("\t%s\n", CLI_DMI_IPMI);
if (hardware->dmi.cache_count)
- printf("\t%s\n", CLI_DMI_CACHE);
+ more_printf("\t%s\n", CLI_DMI_CACHE);
if (strlen(hardware->dmi.oem_strings))
more_printf("\t%s\n", CLI_DMI_OEM);
if (hardware->dmi.hardware_security.filled)
- printf("\t%s\n", CLI_DMI_SECURITY);
+ more_printf("\t%s\n", CLI_DMI_SECURITY);
}
static void show_dmi_base_board(int argc __unused, char** argv __unused,
struct s_hardware *hardware)
{
if (hardware->dmi.base_board.filled == false) {
- printf("base_board information not found on your system, see "
+ more_printf("base_board information not found on your system, see "
"`show list' to see which module is available.\n");
return;
}
@@ -114,54 +115,55 @@ static void show_dmi_system(int argc __unused, char** argv __unused,
struct s_hardware *hardware)
{
if (hardware->dmi.system.filled == false) {
- printf("system information not found on your system, see "
+ more_printf("system information not found on your system, see "
"`show list' to see which module is available.\n");
return;
}
- printf("System\n");
- printf(" Manufacturer : %s\n", hardware->dmi.system.manufacturer);
- printf(" Product Name : %s\n", hardware->dmi.system.product_name);
- printf(" Version : %s\n", hardware->dmi.system.version);
- printf(" Serial : %s\n", hardware->dmi.system.serial);
- printf(" UUID : %s\n", hardware->dmi.system.uuid);
- printf(" Wakeup Type : %s\n", hardware->dmi.system.wakeup_type);
- printf(" SKU Number : %s\n", hardware->dmi.system.sku_number);
- printf(" Family : %s\n", hardware->dmi.system.family);
+ reset_more_printf();
+ more_printf("System\n");
+ more_printf(" Manufacturer : %s\n", hardware->dmi.system.manufacturer);
+ more_printf(" Product Name : %s\n", hardware->dmi.system.product_name);
+ more_printf(" Version : %s\n", hardware->dmi.system.version);
+ more_printf(" Serial : %s\n", hardware->dmi.system.serial);
+ more_printf(" UUID : %s\n", hardware->dmi.system.uuid);
+ more_printf(" Wakeup Type : %s\n", hardware->dmi.system.wakeup_type);
+ more_printf(" SKU Number : %s\n", hardware->dmi.system.sku_number);
+ more_printf(" Family : %s\n", hardware->dmi.system.family);
if (strlen(hardware->dmi.system.configuration_options)) {
- printf("System Configuration Options\n");
- printf("%s\n", hardware->dmi.system.configuration_options);
+ more_printf("System Configuration Options\n");
+ more_printf("%s\n", hardware->dmi.system.configuration_options);
}
if (hardware->dmi.system.system_reset.filled) {
- printf("System Reset\n");
- printf(" Status : %s\n",
+ more_printf("System Reset\n");
+ more_printf(" Status : %s\n",
(hardware->dmi.system.system_reset.status ? "Enabled" : "Disabled"));
- printf(" Watchdog Timer : %s\n",
+ more_printf(" Watchdog Timer : %s\n",
(hardware->dmi.system.system_reset.watchdog ? "Present" : "Not Present"));
if (strlen(hardware->dmi.system.system_reset.boot_option))
- printf(" Boot Option : %s\n", hardware->dmi.system.system_reset.boot_option);
+ more_printf(" Boot Option : %s\n", hardware->dmi.system.system_reset.boot_option);
if (strlen(hardware->dmi.system.system_reset.boot_option_on_limit))
- printf(" Boot Option On Limit : %s\n", hardware->dmi.system.system_reset.boot_option_on_limit);
+ more_printf(" Boot Option On Limit : %s\n", hardware->dmi.system.system_reset.boot_option_on_limit);
if (strlen(hardware->dmi.system.system_reset.reset_count))
- printf(" Reset Count : %s\n", hardware->dmi.system.system_reset.reset_count);
+ more_printf(" Reset Count : %s\n", hardware->dmi.system.system_reset.reset_count);
if (strlen(hardware->dmi.system.system_reset.reset_limit))
- printf(" Reset Limit : %s\n", hardware->dmi.system.system_reset.reset_limit);
+ more_printf(" Reset Limit : %s\n", hardware->dmi.system.system_reset.reset_limit);
if (strlen(hardware->dmi.system.system_reset.timer_interval))
- printf(" Timer Interval : %s\n", hardware->dmi.system.system_reset.timer_interval);
+ more_printf(" Timer Interval : %s\n", hardware->dmi.system.system_reset.timer_interval);
if (strlen(hardware->dmi.system.system_reset.timeout))
- printf(" Timeout : %s\n", hardware->dmi.system.system_reset.timeout);
+ more_printf(" Timeout : %s\n", hardware->dmi.system.system_reset.timeout);
}
- printf("System Boot Information\n");
- printf(" Status : %s\n", hardware->dmi.system.system_boot_status);
+ more_printf("System Boot Information\n");
+ more_printf(" Status : %s\n", hardware->dmi.system.system_boot_status);
}
static void show_dmi_bios(int argc __unused, char** argv __unused,
struct s_hardware *hardware)
{
if (hardware->dmi.bios.filled == false) {
- printf("bios information not found on your system, see "
+ more_printf("bios information not found on your system, see "
"`show list' to see which module is available.\n");
return;
}
@@ -213,28 +215,29 @@ static void show_dmi_chassis(int argc __unused, char** argv __unused,
"`show list' to see which module is available.\n");
return;
}
- printf("Chassis\n");
- printf(" Manufacturer : %s\n",
+ reset_more_printf();
+ more_printf("Chassis\n");
+ more_printf(" Manufacturer : %s\n",
hardware->dmi.chassis.manufacturer);
- printf(" Type : %s\n", hardware->dmi.chassis.type);
- printf(" Lock : %s\n", hardware->dmi.chassis.lock);
- printf(" Version : %s\n",
+ more_printf(" Type : %s\n", hardware->dmi.chassis.type);
+ more_printf(" Lock : %s\n", hardware->dmi.chassis.lock);
+ more_printf(" Version : %s\n",
hardware->dmi.chassis.version);
- printf(" Serial : %s\n", hardware->dmi.chassis.serial);
- printf(" Asset Tag : %s\n",
+ more_printf(" Serial : %s\n", hardware->dmi.chassis.serial);
+ more_printf(" Asset Tag : %s\n",
del_multi_spaces(hardware->dmi.chassis.asset_tag));
- printf(" Boot up state : %s\n",
+ more_printf(" Boot up state : %s\n",
hardware->dmi.chassis.boot_up_state);
- printf(" Power supply state : %s\n",
+ more_printf(" Power supply state : %s\n",
hardware->dmi.chassis.power_supply_state);
- printf(" Thermal state : %s\n",
+ more_printf(" Thermal state : %s\n",
hardware->dmi.chassis.thermal_state);
- printf(" Security Status : %s\n",
+ more_printf(" Security Status : %s\n",
hardware->dmi.chassis.security_status);
- printf(" OEM Information : %s\n",
+ more_printf(" OEM Information : %s\n",
hardware->dmi.chassis.oem_information);
- printf(" Height : %u\n", hardware->dmi.chassis.height);
- printf(" NB Power Cords : %u\n",
+ more_printf(" Height : %u\n", hardware->dmi.chassis.height);
+ more_printf(" NB Power Cords : %u\n",
hardware->dmi.chassis.nb_power_cords);
}
@@ -245,21 +248,22 @@ static void show_dmi_ipmi(int argc __unused, char **argv __unused,
more_printf("IPMI module not available\n");
return;
}
- printf("IPMI\n");
- printf(" Interface Type : %s\n",
+ reset_more_printf();
+ more_printf("IPMI\n");
+ more_printf(" Interface Type : %s\n",
hardware->dmi.ipmi.interface_type);
- printf(" Specification Ver. : %u.%u\n",
+ more_printf(" Specification Ver. : %u.%u\n",
hardware->dmi.ipmi.major_specification_version,
hardware->dmi.ipmi.minor_specification_version);
- printf(" I2C Slave Address : 0x%02x\n",
+ more_printf(" I2C Slave Address : 0x%02x\n",
hardware->dmi.ipmi.I2C_slave_address);
- printf(" Nv Storage Address : %u\n",
+ more_printf(" Nv Storage Address : %u\n",
hardware->dmi.ipmi.nv_address);
uint32_t high = hardware->dmi.ipmi.base_address >> 32;
uint32_t low = hardware->dmi.ipmi.base_address & 0xFFFF;
- printf(" Base Address : %08X%08X\n",
+ more_printf(" Base Address : %08X%08X\n",
high,(low & ~1));
- printf(" IRQ : %d\n",
+ more_printf(" IRQ : %d\n",
hardware->dmi.ipmi.irq);
}
@@ -267,31 +271,32 @@ static void show_dmi_battery(int argc __unused, char** argv __unused,
struct s_hardware *hardware)
{
if (hardware->dmi.battery.filled == false) {
- printf("battery information not found on your system, see "
+ more_printf("battery information not found on your system, see "
"`show list' to see which module is available.\n");
return;
}
- printf("Battery \n");
- printf(" Vendor : %s\n",
+ reset_more_printf();
+ more_printf("Battery \n");
+ more_printf(" Vendor : %s\n",
hardware->dmi.battery.manufacturer);
- printf(" Manufacture Date : %s\n",
+ more_printf(" Manufacture Date : %s\n",
hardware->dmi.battery.manufacture_date);
- printf(" Serial : %s\n", hardware->dmi.battery.serial);
- printf(" Name : %s\n", hardware->dmi.battery.name);
- printf(" Chemistry : %s\n",
+ more_printf(" Serial : %s\n", hardware->dmi.battery.serial);
+ more_printf(" Name : %s\n", hardware->dmi.battery.name);
+ more_printf(" Chemistry : %s\n",
hardware->dmi.battery.chemistry);
- printf(" Design Capacity : %s\n",
+ more_printf(" Design Capacity : %s\n",
hardware->dmi.battery.design_capacity);
- printf(" Design Voltage : %s\n",
+ more_printf(" Design Voltage : %s\n",
hardware->dmi.battery.design_voltage);
- printf(" SBDS : %s\n", hardware->dmi.battery.sbds);
- printf(" SBDS Manuf. Date : %s\n",
+ more_printf(" SBDS : %s\n", hardware->dmi.battery.sbds);
+ more_printf(" SBDS Manuf. Date : %s\n",
hardware->dmi.battery.sbds_manufacture_date);
- printf(" SBDS Chemistry : %s\n",
+ more_printf(" SBDS Chemistry : %s\n",
hardware->dmi.battery.sbds_chemistry);
- printf(" Maximum Error : %s\n",
+ more_printf(" Maximum Error : %s\n",
hardware->dmi.battery.maximum_error);
- printf(" OEM Info : %s\n",
+ more_printf(" OEM Info : %s\n",
hardware->dmi.battery.oem_info);
}
@@ -299,7 +304,7 @@ static void show_dmi_cpu(int argc __unused, char** argv __unused,
struct s_hardware *hardware)
{
if (hardware->dmi.processor.filled == false) {
- printf("processor information not found on your system, see "
+ more_printf("processor information not found on your system, see "
"`show list' to see which module is available.\n");
return;
}
@@ -363,44 +368,45 @@ void show_dmi_memory_bank(int argc, char** argv,
bank = strtol(argv[0], (char **)NULL, 10);
if (errno == ERANGE || bank < 0) {
- printf("This bank number is incorrect\n");
+ more_printf("This bank number is incorrect\n");
return;
}
if ((bank >= hardware->dmi.memory_count) || (bank < 0)) {
- printf("Bank %d number doesn't exists\n", bank);
+ more_printf("Bank %d number doesn't exist\n", bank);
return;
}
if (hardware->dmi.memory[bank].filled == false) {
- printf("Bank %d doesn't contain any information\n", bank);
+ more_printf("Bank %d doesn't contain any information\n", bank);
return;
}
- printf("Memory Bank %d\n", bank);
- printf(" Form Factor : %s\n",
+ reset_more_printf();
+ more_printf("Memory Bank %d\n", bank);
+ more_printf(" Form Factor : %s\n",
hardware->dmi.memory[bank].form_factor);
- printf(" Type : %s\n", hardware->dmi.memory[bank].type);
- printf(" Type Detail : %s\n",
+ more_printf(" Type : %s\n", hardware->dmi.memory[bank].type);
+ more_printf(" Type Detail : %s\n",
hardware->dmi.memory[bank].type_detail);
- printf(" Speed : %s\n", hardware->dmi.memory[bank].speed);
- printf(" Size : %s\n", hardware->dmi.memory[bank].size);
- printf(" Device Set : %s\n",
+ more_printf(" Speed : %s\n", hardware->dmi.memory[bank].speed);
+ more_printf(" Size : %s\n", hardware->dmi.memory[bank].size);
+ more_printf(" Device Set : %s\n",
hardware->dmi.memory[bank].device_set);
- printf(" Device Loc. : %s\n",
+ more_printf(" Device Loc. : %s\n",
hardware->dmi.memory[bank].device_locator);
- printf(" Bank Locator : %s\n",
+ more_printf(" Bank Locator : %s\n",
hardware->dmi.memory[bank].bank_locator);
- printf(" Total Width : %s\n",
+ more_printf(" Total Width : %s\n",
hardware->dmi.memory[bank].total_width);
- printf(" Data Width : %s\n",
+ more_printf(" Data Width : %s\n",
hardware->dmi.memory[bank].data_width);
- printf(" Error : %s\n", hardware->dmi.memory[bank].error);
- printf(" Vendor : %s\n",
+ more_printf(" Error : %s\n", hardware->dmi.memory[bank].error);
+ more_printf(" Vendor : %s\n",
hardware->dmi.memory[bank].manufacturer);
- printf(" Serial : %s\n", hardware->dmi.memory[bank].serial);
- printf(" Asset Tag : %s\n",
+ more_printf(" Serial : %s\n", hardware->dmi.memory[bank].serial);
+ more_printf(" Asset Tag : %s\n",
hardware->dmi.memory[bank].asset_tag);
- printf(" Part Number : %s\n",
+ more_printf(" Part Number : %s\n",
hardware->dmi.memory[bank].part_number);
}
@@ -408,7 +414,7 @@ static void show_dmi_cache(int argc, char** argv,
struct s_hardware *hardware)
{
if (!hardware->dmi.cache_count) {
- printf("cache information not found on your system, see "
+ more_printf("cache information not found on your system, see "
"`show list' to see which module is available.\n");
return;
}
@@ -416,7 +422,7 @@ static void show_dmi_cache(int argc, char** argv,
int cache = strtol(argv[0], NULL, 10);
if (argc != 1 || cache > hardware->dmi.cache_count) {
- printf("show cache [0-%d]\n", hardware->dmi.cache_count-1);
+ more_printf("show cache [0-%d]\n", hardware->dmi.cache_count-1);
return;
}
@@ -464,34 +470,35 @@ void show_dmi_memory_module(int argc, char** argv,
module = strtol(argv[0], (char **)NULL, 10);
if (errno == ERANGE || module < 0) {
- printf("This module number is incorrect\n");
+ more_printf("This module number is incorrect\n");
return;
}
if ((module >= hardware->dmi.memory_module_count) || (module < 0)) {
- printf("Module number %d doesn't exist\n", module);
+ more_printf("Module number %d doesn't exist\n", module);
return;
}
if (hardware->dmi.memory_module[module].filled == false) {
- printf("Module %d doesn't contain any information\n", module);
+ more_printf("Module %d doesn't contain any information\n", module);
return;
}
- printf("Memory Module %d\n", module);
- printf(" Socket Designation : %s\n",
+ reset_more_printf();
+ more_printf("Memory Module %d\n", module);
+ more_printf(" Socket Designation : %s\n",
hardware->dmi.memory_module[module].socket_designation);
- printf(" Bank Connections : %s\n",
+ more_printf(" Bank Connections : %s\n",
hardware->dmi.memory_module[module].bank_connections);
- printf(" Current Speed : %s\n",
+ more_printf(" Current Speed : %s\n",
hardware->dmi.memory_module[module].speed);
- printf(" Type : %s\n",
+ more_printf(" Type : %s\n",
hardware->dmi.memory_module[module].type);
- printf(" Installed Size : %s\n",
+ more_printf(" Installed Size : %s\n",
hardware->dmi.memory_module[module].installed_size);
- printf(" Enabled Size : %s\n",
+ more_printf(" Enabled Size : %s\n",
hardware->dmi.memory_module[module].enabled_size);
- printf(" Error Status : %s\n",
+ more_printf(" Error Status : %s\n",
hardware->dmi.memory_module[module].error_status);
}
@@ -502,10 +509,11 @@ void main_show_dmi(int argc __unused, char **argv __unused,
detect_dmi(hardware);
if (hardware->is_dmi_valid == false) {
- printf("No valid DMI table found, exiting.\n");
+ more_printf("No valid DMI table found, exiting.\n");
return;
}
- printf("DMI Table version %d.%d found\n",
+ reset_more_printf();
+ more_printf("DMI Table version %u.%u found\n",
hardware->dmi.dmitable.major_version,
hardware->dmi.dmitable.minor_version);
@@ -536,6 +544,7 @@ void show_dmi_memory_modules(int argc __unused, char** argv __unused,
return;
}
+ reset_more_printf();
more_printf("Memory Banks\n");
for (int i = 0; i < hardware->dmi.memory_count; i++) {
if (hardware->dmi.memory[i].filled == true) {
diff --git a/com32/hdt/hdt-cli-hdt.c b/com32/hdt/hdt-cli-hdt.c
index 5bebf584..f11cbec4 100644
--- a/com32/hdt/hdt-cli-hdt.c
+++ b/com32/hdt/hdt-cli-hdt.c
@@ -52,6 +52,7 @@ static void main_show_modes(int argc __unused, char** argv __unused,
{
int i = 0;
+ reset_more_printf();
printf("Available modes:\n");
while (list_modes[i]) {
printf("%s ", list_modes[i]->name);
@@ -70,8 +71,9 @@ static void cli_set_mode(int argc, char **argv,
{
cli_mode_t new_mode;
+ reset_more_printf();
if (argc <= 0) {
- printf("Which mode?\n");
+ more_printf("Which mode?\n");
return;
}
@@ -191,8 +193,8 @@ static void goto_menu(int argc __unused, char** argv __unused,
struct s_hardware *hardware)
{
char version_string[256];
- snprintf(version_string, sizeof version_string, "%s %s by %s",
- PRODUCT_NAME, VERSION, AUTHOR);
+ snprintf(version_string, sizeof version_string, "%s %s (%s)",
+ PRODUCT_NAME, VERSION, CODENAME);
start_menu_mode(hardware, version_string);
return;
}
@@ -206,6 +208,7 @@ void main_show_summary(int argc __unused, char **argv __unused,
detect_pci(hardware); /* pxe is detected in the pci */
detect_dmi(hardware);
cpu_detect(hardware);
+ reset_more_printf();
clear_screen();
main_show_cpu(argc, argv, hardware);
if (hardware->is_dmi_valid) {
@@ -236,17 +239,32 @@ void main_show_summary(int argc __unused, char **argv __unused,
void main_show_hdt(int argc __unused, char **argv __unused,
struct s_hardware *hardware __unused)
{
- printf("HDT\n");
- printf(" Product : %s\n", PRODUCT_NAME);
- printf(" Version : %s\n", VERSION);
- printf(" Author : %s\n", AUTHOR);
- printf(" Contact : %s\n", CONTACT);
+ reset_more_printf();
+ more_printf("HDT\n");
+ more_printf(" Product : %s\n", PRODUCT_NAME);
+ more_printf(" Version : %s (%s)\n", VERSION, CODENAME);
+ more_printf(" Project Leader : %s\n", AUTHOR);
+ more_printf(" Contact : %s\n", CONTACT);
+ more_printf(" Core Developer : %s\n", CORE_DEVELOPER);
char *contributors[NB_CONTRIBUTORS] = CONTRIBUTORS;
for (int c = 0; c < NB_CONTRIBUTORS; c++) {
- printf(" Contributor : %s\n", contributors[c]);
+ more_printf(" Contributor : %s\n", contributors[c]);
}
}
+/**
+ * do_reboot - reboot the system
+ **/
+static void do_reboot(int argc __unused, char** argv __unused,
+ struct s_hardware *hardware)
+{
+ /* Use specific syslinux call if needed */
+ if (issyslinux())
+ return runsyslinuxcmd(hardware->reboot_label);
+ else
+ return csprint(hardware->reboot_label, 0x07);
+}
+
/* Default hdt mode */
struct cli_callback_descr list_hdt_default_modules[] = {
{
@@ -266,6 +284,10 @@ struct cli_callback_descr list_hdt_default_modules[] = {
.exec = goto_menu,
},
{
+ .name = CLI_REBOOT,
+ .exec = do_reboot,
+ },
+ {
.name = NULL,
.exec = NULL
},
diff --git a/com32/hdt/hdt-cli-kernel.c b/com32/hdt/hdt-cli-kernel.c
index 41c80bea..d33cdd80 100644
--- a/com32/hdt/hdt-cli-kernel.c
+++ b/com32/hdt/hdt-cli-kernel.c
@@ -46,6 +46,7 @@ void main_show_kernel(int argc __unused, char **argv __unused,
memset(buffer, 0, sizeof(buffer));
detect_pci(hardware);
+ reset_more_printf();
more_printf("Kernel modules\n");
// more_printf(" PCI device no: %d \n", p->pci_device_pos);
@@ -105,17 +106,18 @@ static void show_kernel_modules(int argc __unused, char **argv __unused,
if (hardware->pci_ids_return_code == -ENOPCIIDS) {
nopciids = true;
- printf(" Missing pci.ids, we can't compute the list\n");
+ more_printf(" Missing pci.ids, we can't compute the list\n");
return;
}
if (hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) {
nomodulespcimap = true;
- printf
+ more_printf
(" Missing modules.pcimap, we can't compute the list\n");
return;
}
+ reset_more_printf();
for_each_pci_func(pci_device, hardware->pci_domain) {
memset(kernel_modules, 0, sizeof kernel_modules);
@@ -140,7 +142,7 @@ static void show_kernel_modules(int argc __unused, char **argv __unused,
/* Print the found items */
for (int i = 0; i < MAX_PCI_CLASSES; i++) {
if (strlen(category_name[i]) > 1) {
- printf("%s : %s\n", category_name[i], modules[i]);
+ more_printf("%s : %s\n", category_name[i], modules[i]);
}
}
}
diff --git a/com32/hdt/hdt-cli-memory.c b/com32/hdt/hdt-cli-memory.c
index 89f871e1..3f8ed75a 100644
--- a/com32/hdt/hdt-cli-memory.c
+++ b/com32/hdt/hdt-cli-memory.c
@@ -41,8 +41,8 @@ static void show_memory_e820(int argc __unused, char **argv __unused,
char type[14];
detect_memory_e820(map, E820MAX, &count);
- printf("BIOS-provided physical RAM e820 map:\n");
reset_more_printf();
+ more_printf("BIOS-provided physical RAM e820 map:\n");
for (int i = 0; i < count; i++) {
get_type(map[i].type, type, 14);
more_printf("%016llx - %016llx %016llx (%s)\n",
diff --git a/com32/hdt/hdt-cli-pci.c b/com32/hdt/hdt-cli-pci.c
index 2de43fe3..75e28968 100644
--- a/com32/hdt/hdt-cli-pci.c
+++ b/com32/hdt/hdt-cli-pci.c
@@ -37,7 +37,7 @@ void main_show_pci(int argc __unused, char **argv __unused,
struct s_hardware *hardware)
{
cli_detect_pci(hardware);
-
+ reset_more_printf();
more_printf("PCI\n");
more_printf(" NB Devices : %d\n", hardware->nb_pci_devices);
}
@@ -56,19 +56,20 @@ static void show_pci_device(int argc, char **argv,
MAX_KERNEL_MODULES_PER_PCI_DEVICE];
int bus = 0, slot = 0, func = 0;
+ reset_more_printf();
/* Sanitize arguments */
if (argc <= 0) {
- printf("show device <number>\n");
+ more_printf("show device <number>\n");
return;
} else
pcidev = strtol(argv[0], (char **)NULL, 10);
if (errno == ERANGE) {
- printf("This PCI device number is incorrect\n");
+ more_printf("This PCI device number is incorrect\n");
return;
}
if ((pcidev > hardware->nb_pci_devices) || (pcidev <= 0)) {
- printf("PCI device %d doesn't exists\n", pcidev);
+ more_printf("PCI device %d doesn't exist\n", pcidev);
return;
}
if (hardware->pci_ids_return_code == -ENOPCIIDS) {
@@ -92,7 +93,7 @@ static void show_pci_device(int argc, char **argv,
}
if (pci_device == NULL) {
- printf("We were enabled to find PCI device %d\n", pcidev);
+ more_printf("We were enabled to find PCI device %d\n", pcidev);
return;
}
@@ -109,41 +110,41 @@ static void show_pci_device(int argc, char **argv,
if (pci_device->dev_info->linux_kernel_module_count == 0)
strlcpy(kernel_modules, "unknown", 7);
- printf("PCI Device %d\n", pcidev);
+ more_printf("PCI Device %d\n", pcidev);
if (nopciids == false) {
- printf("Vendor Name : %s\n",
+ more_printf("Vendor Name : %s\n",
pci_device->dev_info->vendor_name);
- printf("Product Name : %s\n",
+ more_printf("Product Name : %s\n",
pci_device->dev_info->product_name);
- printf("Class Name : %s\n",
+ more_printf("Class Name : %s\n",
pci_device->dev_info->class_name);
}
if (nomodulesfiles == false) {
- printf("Kernel module : %s\n", kernel_modules);
+ more_printf("Kernel module : %s\n", kernel_modules);
}
- printf("Vendor ID : %04x\n", pci_device->vendor);
- printf("Product ID : %04x\n", pci_device->product);
- printf("SubVendor ID : %04x\n", pci_device->sub_vendor);
- printf("SubProduct ID : %04x\n", pci_device->sub_product);
- printf("Class ID : %02x.%02x.%02x\n", pci_device->class[2],
+ more_printf("Vendor ID : %04x\n", pci_device->vendor);
+ more_printf("Product ID : %04x\n", pci_device->product);
+ more_printf("SubVendor ID : %04x\n", pci_device->sub_vendor);
+ more_printf("SubProduct ID : %04x\n", pci_device->sub_product);
+ more_printf("Class ID : %02x.%02x.%02x\n", pci_device->class[2],
pci_device->class[1], pci_device->class[0]);
- printf("Revision : %02x\n", pci_device->revision);
+ more_printf("Revision : %02x\n", pci_device->revision);
if ((pci_device->dev_info->irq > 0)
&& (pci_device->dev_info->irq < 255))
more_printf("IRQ : %0d\n", pci_device->dev_info->irq);
- printf("Latency : %0d\n", pci_device->dev_info->latency);
- printf("PCI Bus : %02d\n", bus);
- printf("PCI Slot : %02d\n", slot);
- printf("PCI Func : %02d\n", func);
+ more_printf("Latency : %0d\n", pci_device->dev_info->latency);
+ more_printf("PCI Bus : %02d\n", bus);
+ more_printf("PCI Slot : %02d\n", slot);
+ more_printf("PCI Func : %02d\n", func);
if (hardware->is_pxe_valid == true) {
if ((hardware->pxe.pci_device != NULL)
&& (hardware->pxe.pci_device == pci_device)) {
- printf("Mac Address : %s\n", hardware->pxe.mac_addr);
- printf("PXE : Current boot device\n");
+ more_printf("Mac Address : %s\n", hardware->pxe.mac_addr);
+ more_printf("PXE : Current boot device\n");
}
}
}
@@ -305,21 +306,21 @@ void cli_detect_pci(struct s_hardware *hardware)
if (hardware->pci_detection == false) {
detect_pci(hardware);
if (hardware->pci_ids_return_code == -ENOPCIIDS) {
- printf
+ more_printf
("The pci.ids file is missing, device names can't be computed.\n");
- printf("Please put one in same dir as hdt\n");
+ more_printf("Please put one in same dir as hdt\n");
error = true;
}
if ((hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) &&
(hardware->modules_alias_return_code == -ENOMODULESALIAS)) {
- printf
+ more_printf
("The modules.pcimap or modules.alias files are missing, device names can't be computed.\n");
- printf("Please put one of them in same dir as hdt\n");
+ more_printf("Please put one of them in same dir as hdt\n");
error = true;
}
if (error == true) {
char tempbuf[10];
- printf("Press enter to continue\n");
+ more_printf("Press enter to continue\n");
fgets(tempbuf, sizeof(tempbuf), stdin);
}
}
diff --git a/com32/hdt/hdt-cli-pxe.c b/com32/hdt/hdt-cli-pxe.c
index 1d00cae5..a281d158 100644
--- a/com32/hdt/hdt-cli-pxe.c
+++ b/com32/hdt/hdt-cli-pxe.c
@@ -41,20 +41,21 @@ void main_show_pxe(int argc __unused, char **argv __unused,
{
char buffer[81];
memset(buffer, 0, sizeof(81));
+ reset_more_printf();
if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
- printf("You are not currently using PXELINUX\n");
+ more_printf("You are not currently using PXELINUX\n");
return;
}
detect_pxe(hardware);
- printf("PXE\n");
+ more_printf("PXE\n");
if (hardware->is_pxe_valid == false) {
- printf(" No valid PXE ROM found\n");
+ more_printf(" No valid PXE ROM found\n");
return;
}
struct s_pxe *p = &hardware->pxe;
- printf(" PCI device no: %d \n", p->pci_device_pos);
+ more_printf(" PCI device no: %d \n", p->pci_device_pos);
if (hardware->pci_ids_return_code == -ENOPCIIDS ||
(p->pci_device == NULL)) {
@@ -65,16 +66,16 @@ void main_show_pxe(int argc __unused, char **argv __unused,
snprintf(buffer, sizeof(buffer),
" PCI Bus pos. : %02x:%02x.%02x\n", p->pci_bus,
p->pci_dev, p->pci_func);
- printf(buffer);
+ more_printf(buffer);
} else {
snprintf(buffer, sizeof(buffer), " Manufacturer : %s \n",
p->pci_device->dev_info->vendor_name);
- printf(buffer);
+ more_printf(buffer);
snprintf(buffer, sizeof(buffer), " Product : %s \n",
p->pci_device->dev_info->product_name);
- printf(buffer);
+ more_printf(buffer);
}
- printf(" Addresses : %d.%d.%d.%d @ %s\n", p->ip_addr[0],
+ more_printf(" Addresses : %d.%d.%d.%d @ %s\n", p->ip_addr[0],
p->ip_addr[1], p->ip_addr[2], p->ip_addr[3], p->mac_addr);
}
diff --git a/com32/hdt/hdt-cli-syslinux.c b/com32/hdt/hdt-cli-syslinux.c
index 0d78bc66..160e33c4 100644
--- a/com32/hdt/hdt-cli-syslinux.c
+++ b/com32/hdt/hdt-cli-syslinux.c
@@ -39,12 +39,13 @@
void main_show_syslinux(int argc __unused, char **argv __unused,
struct s_hardware *hardware)
{
- printf("SYSLINUX\n");
- printf(" Bootloader : %s\n", hardware->syslinux_fs);
- printf(" Version : %s\n", hardware->sv->version_string + 2);
- printf(" Version : %u\n", hardware->sv->version);
- printf(" Max API : %u\n", hardware->sv->max_api);
- printf(" Copyright : %s\n", hardware->sv->copyright_string + 1);
+ reset_more_printf();
+ more_printf("SYSLINUX\n");
+ more_printf(" Bootloader : %s\n", hardware->syslinux_fs);
+ more_printf(" Version : %s\n", hardware->sv->version_string + 2);
+ more_printf(" Version : %u\n", hardware->sv->version);
+ more_printf(" Max API : %u\n", hardware->sv->max_api);
+ more_printf(" Copyright : %s\n", hardware->sv->copyright_string + 1);
}
struct cli_module_descr syslinux_show_modules = {
diff --git a/com32/hdt/hdt-cli-vesa.c b/com32/hdt/hdt-cli-vesa.c
index 70d1dc61..c6eea072 100644
--- a/com32/hdt/hdt-cli-vesa.c
+++ b/com32/hdt/hdt-cli-vesa.c
@@ -36,33 +36,34 @@
void main_show_vesa(int argc __unused, char **argv __unused,
struct s_hardware *hardware)
{
+ reset_more_printf();
detect_vesa(hardware);
if (hardware->is_vesa_valid == false) {
- printf("No VESA BIOS detected\n");
+ more_printf("No VESA BIOS detected\n");
return;
}
- printf("VESA\n");
- printf(" Vesa version : %d.%d\n", hardware->vesa.major_version,
+ more_printf("VESA\n");
+ more_printf(" Vesa version : %d.%d\n", hardware->vesa.major_version,
hardware->vesa.minor_version);
- printf(" Vendor : %s\n", hardware->vesa.vendor);
- printf(" Product : %s\n", hardware->vesa.product);
- printf(" Product rev. : %s\n", hardware->vesa.product_revision);
- printf(" Software rev.: %d\n", hardware->vesa.software_rev);
- printf(" Memory (KB) : %d\n", hardware->vesa.total_memory * 64);
- printf(" Modes : %d\n", hardware->vesa.vmi_count);
+ more_printf(" Vendor : %s\n", hardware->vesa.vendor);
+ more_printf(" Product : %s\n", hardware->vesa.product);
+ more_printf(" Product rev. : %s\n", hardware->vesa.product_revision);
+ more_printf(" Software rev.: %d\n", hardware->vesa.software_rev);
+ more_printf(" Memory (KB) : %d\n", hardware->vesa.total_memory * 64);
+ more_printf(" Modes : %d\n", hardware->vesa.vmi_count);
}
static void show_vesa_modes(int argc __unused, char **argv __unused,
struct s_hardware *hardware)
{
detect_vesa(hardware);
+ reset_more_printf();
if (hardware->is_vesa_valid == false) {
- printf("No VESA BIOS detected\n");
+ more_printf("No VESA BIOS detected\n");
return;
}
- reset_more_printf();
- printf(" ResH. x ResV x Bits : vga= : Vesa Mode\n");
- printf("----------------------------------------\n");
+ more_printf(" ResH. x ResV x Bits : vga= : Vesa Mode\n");
+ more_printf("----------------------------------------\n");
for (int i = 0; i < hardware->vesa.vmi_count; i++) {
struct vesa_mode_info *mi = &hardware->vesa.vmi[i].mi;
@@ -71,7 +72,7 @@ static void show_vesa_modes(int argc __unused, char **argv __unused,
* We don't need to display that ones.
*/
if ((mi->h_res == 0) || (mi->v_res == 0)) continue;
- printf("%5u %5u %3u %3d 0x%04x\n",
+ more_printf("%5u %5u %3u %3d 0x%04x\n",
mi->h_res, mi->v_res, mi->bpp,
hardware->vesa.vmi[i].mode + 0x200,
hardware->vesa.vmi[i].mode);
diff --git a/com32/hdt/hdt-cli-vpd.c b/com32/hdt/hdt-cli-vpd.c
index 03614d39..a445d833 100644
--- a/com32/hdt/hdt-cli-vpd.c
+++ b/com32/hdt/hdt-cli-vpd.c
@@ -39,11 +39,11 @@ void main_show_vpd(int argc __unused, char **argv __unused,
detect_vpd(hardware);
if (!hardware->is_vpd_valid) {
- printf("No VPD structure detected.\n");
+ more_printf("No VPD structure detected.\n");
return;
}
- printf("VPD present at address : 0x%s\n", hardware->vpd.base_address);
+ more_printf("VPD present at address : 0x%s\n", hardware->vpd.base_address);
if (strlen(hardware->vpd.bios_build_id) > 0)
more_printf("Bios Build ID : %s\n", hardware->vpd.bios_build_id);
if (strlen(hardware->vpd.bios_release_date) > 0)
diff --git a/com32/hdt/hdt-cli.c b/com32/hdt/hdt-cli.c
index 0d38fb2b..060f953b 100644
--- a/com32/hdt/hdt-cli.c
+++ b/com32/hdt/hdt-cli.c
@@ -32,7 +32,6 @@
#include <getkey.h>
#include "hdt-cli.h"
#include "hdt-common.h"
-#include "lib-ansi.h"
struct cli_mode_descr *list_modes[] = {
&hdt_mode,
@@ -54,8 +53,8 @@ struct cli_mode_descr *list_modes[] = {
* array of variables. There is no easy way around it besides declaring the arrays of
* strings first.
*/
-char *exit_aliases[] = {"q", "quit"};
-char *help_aliases[] = {"h", "?"};
+const char *exit_aliases[] = {"q", "quit"};
+const char *help_aliases[] = {"h", "?"};
/* List of aliases */
struct cli_alias hdt_aliases[] = {
@@ -750,6 +749,48 @@ static void reset_prompt()
}
}
+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)) {
+ 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");
+}
+
+
/* Code that manages the cli mode */
void start_cli_mode(struct s_hardware *hardware)
{
@@ -773,6 +814,11 @@ void start_cli_mode(struct s_hardware *hardware)
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();
diff --git a/com32/hdt/hdt-cli.h b/com32/hdt/hdt-cli.h
index 47137cca..3684fa40 100644
--- a/com32/hdt/hdt-cli.h
+++ b/com32/hdt/hdt-cli.h
@@ -48,6 +48,7 @@
#define CLI_CLEAR "clear"
#define CLI_EXIT "exit"
#define CLI_HELP "help"
+#define CLI_REBOOT "reboot"
#define CLI_SHOW "show"
#define CLI_SET "set"
#define CLI_MODE "mode"
@@ -152,6 +153,7 @@ cli_mode_t mode_s_to_mode_t(char *name);
void set_mode(cli_mode_t mode, struct s_hardware *hardware);
void start_cli_mode(struct s_hardware *hardware);
+void start_auto_mode(struct s_hardware *hardware);
void main_show(char *item, struct s_hardware *hardware);
// DMI STUFF
diff --git a/com32/hdt/hdt-common.c b/com32/hdt/hdt-common.c
index 80305a3e..5cfa9e87 100644
--- a/com32/hdt/hdt-common.c
+++ b/com32/hdt/hdt-common.c
@@ -33,8 +33,8 @@
#include "syslinux/config.h"
#include "../lib/sys/vesa/vesa.h"
#include "hdt-common.h"
-#include "lib-ansi.h"
#include <disk/util.h>
+#include <disk/mbrs.h>
/* ISOlinux requires a 8.3 format */
void convert_isolinux_filename(char *filename, struct s_hardware *hardware) {
@@ -55,8 +55,13 @@ void convert_isolinux_filename(char *filename, struct s_hardware *hardware) {
void detect_parameters(const int argc, const char *argv[],
struct s_hardware *hardware)
{
+ /* Quiet mode - make the output more quiet */
+ quiet = false;
+
for (int i = 1; i < argc; i++) {
- if (!strncmp(argv[i], "modules_pcimap=", 15)) {
+ if (!strncmp(argv[i], "quiet", 5)) {
+ quiet = true;
+ } else if (!strncmp(argv[i], "modules_pcimap=", 15)) {
strncpy(hardware->modules_pcimap_path, argv[i] + 15,
sizeof(hardware->modules_pcimap_path));
convert_isolinux_filename(hardware->modules_pcimap_path,hardware);
@@ -72,6 +77,36 @@ void detect_parameters(const int argc, const char *argv[],
strncpy(hardware->memtest_label, argv[i] + 8,
sizeof(hardware->memtest_label));
convert_isolinux_filename(hardware->memtest_label,hardware);
+ } else if (!strncmp(argv[i], "reboot=", 7)) {
+ strncpy(hardware->reboot_label, argv[i] + 7,
+ sizeof(hardware->reboot_label));
+ convert_isolinux_filename(hardware->reboot_label,hardware);
+ } else if (!strncmp(argv[i], "auto=", 5)) {
+ /* The auto= parameter is separated in several argv[]
+ * as it can contains spaces.
+ * We use the AUTO_DELIMITER char to define the limits
+ * of this parameter.
+ * i.e auto='show dmi; show pci'
+ */
+
+ /* Extracting the first parameter */
+ strcpy(hardware->auto_label, argv[i] + 6);
+ strcat(hardware->auto_label," ");
+ char *pos;
+ i++;
+
+ /* While we can't find the other AUTO_DELIMITER, let's process the argv[] */
+ while(((pos=strstr(argv[i],AUTO_DELIMITER)) == NULL) && (i<argc)) {
+ strcat(hardware->auto_label,argv[i]);
+ strcat(hardware->auto_label," ");
+ i++;
+ }
+
+ /* If we didn't reach the end of the line, let's grab the last item */
+ if (i<argc) {
+ strcat(hardware->auto_label,argv[i]);
+ hardware->auto_label[strlen(hardware->auto_label)-1]=0;
+ }
}
}
}
@@ -133,10 +168,13 @@ void init_hardware(struct s_hardware *hardware)
memset(hardware->modules_alias_path, 0,
sizeof hardware->modules_alias_path);
memset(hardware->memtest_label, 0, sizeof hardware->memtest_label);
+ memset(hardware->reboot_label, 0, sizeof hardware->reboot_label);
+ memset(hardware->auto_label, 0, sizeof hardware->auto_label);
strcat(hardware->pciids_path, "pci.ids");
strcat(hardware->modules_pcimap_path, "modules.pcimap");
strcat(hardware->modules_alias_path, "modules.alias");
strcat(hardware->memtest_label, "memtest");
+ strcat(hardware->reboot_label, "reboot.c32");
}
/*
@@ -269,6 +307,9 @@ void detect_disks(struct s_hardware *hardware)
if (err == -1 || !hardware->disk_info[i].cbios)
continue;
+ /* Detect MBR */
+ hardware->mbr_ids[i] = get_mbr_id(&hardware->disk_info[i]);
+
hardware->disks_count++;
}
}
@@ -442,19 +483,23 @@ void detect_pci(struct s_hardware *hardware)
hardware->nb_pci_devices++;
}
- printf("PCI: %d devices detected\n", hardware->nb_pci_devices);
- printf("PCI: Resolving names\n");
+ if (!quiet) {
+ more_printf("PCI: %d devices detected\n", hardware->nb_pci_devices);
+ more_printf("PCI: Resolving names\n");
+ }
/* Assigning product & vendor name for each device */
hardware->pci_ids_return_code =
get_name_from_pci_ids(hardware->pci_domain, hardware->pciids_path);
- printf("PCI: Resolving class names\n");
+ if (!quiet)
+ more_printf("PCI: Resolving class names\n");
/* Assigning class name for each device */
hardware->pci_ids_return_code =
get_class_name_from_pci_ids(hardware->pci_domain,
hardware->pciids_path);
- printf("PCI: Resolving module names\n");
+ if (!quiet)
+ more_printf("PCI: Resolving module names\n");
/* Detecting which kernel module should match each device using modules.pcimap*/
hardware->modules_pcimap_return_code =
get_module_name_from_pcimap(hardware->pci_domain,
@@ -534,6 +579,20 @@ char *remove_spaces(char *p)
return p;
}
+/* remove trailing LF */
+char *remove_trailing_lf(char *p)
+{
+ char *save=p;
+ p+=strlen(p)-1;
+ while (*p && *p == 10) {
+ *p='\0';
+ p--;
+ }
+ p=save;
+
+ return p;
+}
+
/* delete multiple spaces, one is enough */
char *del_multi_spaces(char *p) {
/* Saving the original pointer*/
diff --git a/com32/hdt/hdt-common.h b/com32/hdt/hdt-common.h
index 2b67f9ca..f178b223 100644
--- a/com32/hdt/hdt-common.h
+++ b/com32/hdt/hdt-common.h
@@ -32,13 +32,22 @@
#include <syslinux/pxe.h>
#include "sys/pci.h"
+#include <disk/bootloaders.h>
+#include <disk/errno_disk.h>
+#include <disk/error.h>
#include <disk/geom.h>
+#include <disk/mbrs.h>
+#include <disk/msdos.h>
+#include <disk/partition.h>
+#include <disk/swsusp.h>
+#include <disk/read.h>
#include "cpuid.h"
#include "dmi/dmi.h"
#include "hdt-ata.h"
#include "../lib/sys/vesa/vesa.h"
#include <vpd/vpd.h>
+#include <libansi.h>
/* Declare a variable or data structure as unused. */
#define __unused __attribute__ (( unused ))
@@ -48,16 +57,42 @@
#define HDT_RETURN_TO_CLI 100
#define MAX_VESA_MODES 255
+/* The maximum number of commands we can process */
+#define MAX_NB_AUTO_COMMANDS 255
+/* The maximum size of a command */
+#define AUTO_COMMAND_SIZE 255
+/* The char that separate two commands */
+#define AUTO_SEPARATOR ";"
+/* The char that surround the list of commands */
+#define AUTO_DELIMITER "'"
+
+/* Defines if the cli is quiet*/
+bool quiet;
+
extern int display_line_nb;
+extern bool disable_more_printf;
+#define pause_printf() do {\
+ printf("--More--");\
+ get_key(stdin, 0);\
+ printf("\033[2K\033[1G\033[1F\n");\
+} while (0);
+
+/* The brokeness of that macro is that
+ * it assumes that __VA_ARGS__ contains
+ * one \n (and only one)
+ */
#define more_printf(...) do {\
- if (display_line_nb == 23) {\
- printf("Press any key to continue\n");\
+ if (__likely(!disable_more_printf)) {\
+ if (display_line_nb == 20) {\
display_line_nb=0;\
+ printf("\n--More--");\
get_key(stdin, 0);\
+ printf("\033[2K\033[1G\033[1F");\
+ }\
+ display_line_nb++;\
}\
- printf ( __VA_ARGS__);\
- display_line_nb++; \
+ printf(__VA_ARGS__);\
} while (0);
/* Display CPU registers for debugging purposes */
@@ -114,6 +149,7 @@ struct s_hardware {
s_vpd vpd; /* VPD information */
struct pci_domain *pci_domain; /* PCI Devices */
struct driveinfo disk_info[256]; /* Disk Information */
+ uint32_t mbr_ids[256]; /* MBR ids */
int disks_count; /* Number of detected disks */
struct s_pxe pxe;
struct s_vesa vesa;
@@ -141,11 +177,14 @@ struct s_hardware {
char modules_alias_path[255];
char pciids_path[255];
char memtest_label[255];
+ char reboot_label[255];
+ char auto_label[AUTO_COMMAND_SIZE];
};
void reset_more_printf();
const char *find_argument(const char **argv, const char *argument);
char *remove_spaces(char *p);
+char *remove_trailing_lf(char *p);
char *skip_spaces(char *p);
char *del_multi_spaces(char *p);
int detect_dmi(struct s_hardware *hardware);
diff --git a/com32/hdt/hdt-menu-about.c b/com32/hdt/hdt-menu-about.c
index f19dc361..53b58f21 100644
--- a/com32/hdt/hdt-menu-about.c
+++ b/com32/hdt/hdt-menu-about.c
@@ -39,29 +39,34 @@ void compute_aboutmenu(struct s_my_menu *menu)
set_menu_pos(SUBMENU_Y, SUBMENU_X);
- snprintf(buffer, sizeof buffer, "Product : %s", PRODUCT_NAME);
+ snprintf(buffer, sizeof buffer, "Product : %s", PRODUCT_NAME);
snprintf(statbuffer, sizeof statbuffer, "Product : %s", PRODUCT_NAME);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu->items_count++;
- snprintf(buffer, sizeof buffer, "Version : %s", VERSION);
- snprintf(statbuffer, sizeof statbuffer, "Version : %s", VERSION);
+ snprintf(buffer, sizeof buffer, "Version : %s (%s)", VERSION, CODENAME);
+ snprintf(statbuffer, sizeof statbuffer, "Version : %s (%s)", VERSION,CODENAME);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu->items_count++;
- snprintf(buffer, sizeof buffer, "Author : %s", AUTHOR);
- snprintf(statbuffer, sizeof statbuffer, "Author : %s", AUTHOR);
+ snprintf(buffer, sizeof buffer, "Project Leader : %s", AUTHOR);
+ snprintf(statbuffer, sizeof statbuffer, "Project Leader : %s", AUTHOR);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu->items_count++;
- snprintf(buffer, sizeof buffer, "Contact : %s", CONTACT);
+ snprintf(buffer, sizeof buffer, "Contact : %s", CONTACT);
snprintf(statbuffer, sizeof statbuffer, "Contact : %s", CONTACT);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu->items_count++;
+ snprintf(buffer, sizeof buffer, "Core Developer : %s", CORE_DEVELOPER);
+ snprintf(statbuffer, sizeof statbuffer, "Core Developer : %s", CORE_DEVELOPER);
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+ menu->items_count++;
+
char *contributors[NB_CONTRIBUTORS] = CONTRIBUTORS;
for (int c=0; c<NB_CONTRIBUTORS; c++) {
- snprintf(buffer, sizeof buffer, "Contributor : %s", contributors[c]);
+ snprintf(buffer, sizeof buffer, "Contributor : %s", contributors[c]);
snprintf(statbuffer, sizeof statbuffer, "Contributor : %s", contributors[c]);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu->items_count++;
diff --git a/com32/hdt/hdt-menu-disk.c b/com32/hdt/hdt-menu-disk.c
index bd33bdf3..2f3571b9 100644
--- a/com32/hdt/hdt-menu-disk.c
+++ b/com32/hdt/hdt-menu-disk.c
@@ -27,13 +27,6 @@
*/
#include <stdlib.h>
-#include <disk/errno_disk.h>
-#include <disk/geom.h>
-#include <disk/read.h>
-#include <disk/partition.h>
-#include <disk/error.h>
-#include <disk/msdos.h>
-#include <disk/swsusp.h>
#include "hdt-menu.h"
#include "hdt-util.h"
@@ -81,6 +74,7 @@ static void compute_partition_information(struct driveinfo *drive_info,
int nb_partitions_seen)
{
char size[9];
+ char bootloader_name[9];
char *parttype;
unsigned int start, end;
char buffer[SUBMENULEN+1];
@@ -120,6 +114,14 @@ static void compute_partition_information(struct driveinfo *drive_info,
parttype);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+ if (get_bootloader_string(drive_info, ptab, bootloader_name, 9) == 0) {
+ snprintf(buffer, sizeof buffer, "Bootloader : %s",
+ bootloader_name);
+ snprintf(statbuffer, sizeof statbuffer, "Bootloader: %s",
+ bootloader_name);
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+ }
+
snprintf(buffer, sizeof buffer, "Bootable : %s",
(ptab->active_flag == 0x80) ? "Yes" : "No");
snprintf(statbuffer, sizeof statbuffer, "Bootable: %s",
@@ -157,10 +159,12 @@ static void compute_partition_information(struct driveinfo *drive_info,
/* Compute the disk submenu */
static int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
- struct driveinfo *d, int disk_number)
+ const struct s_hardware *hardware, int disk_number)
{
char buffer[MENULEN + 1];
char statbuffer[STATLEN + 1];
+ char mbr_name[50];
+ struct driveinfo *d = (struct driveinfo*) hardware->disk_info;
snprintf(buffer, sizeof buffer, " Disk <0x%X> (EDD %X)", d[disk_number].disk,
d[disk_number].edd_version);
@@ -181,10 +185,10 @@ static int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
menu[nb_sub_disk_menu].items_count++;
snprintf(buffer, sizeof buffer, "Host Bus / Interface : %s / %s",
- remove_spaces(d[disk_number].edd_params.host_bus_type),
+ remove_spaces((char *) d[disk_number].edd_params.host_bus_type),
d[disk_number].edd_params.interface_type);
snprintf(statbuffer, sizeof statbuffer, "Host Bus / Interface: %s / %s",
- remove_spaces(d[disk_number].edd_params.host_bus_type),
+ remove_spaces((char *) d[disk_number].edd_params.host_bus_type),
d[disk_number].edd_params.interface_type);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
@@ -207,6 +211,17 @@ static int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
+ get_mbr_string(hardware->mbr_ids[disk_number], &mbr_name, 50);
+
+ snprintf(buffer, sizeof buffer, "MBR : %s (0x%X)",
+ remove_spaces(mbr_name),
+ hardware->mbr_ids[disk_number]);
+ snprintf(statbuffer, sizeof statbuffer, "MBR: %s (id 0x%X)",
+ remove_spaces(mbr_name),
+ hardware->mbr_ids[disk_number]);
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+ menu[nb_sub_disk_menu].items_count++;
+
dn=disk_number;
parse_partition_table(&d[disk_number], &show_partition_information);
@@ -219,7 +234,7 @@ static int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
}
/* Compute the Disks menu */
-void compute_disks(struct s_hdt_menu *menu, struct driveinfo *disk_info, struct s_hardware *hardware)
+void compute_disks(struct s_hdt_menu *menu, struct s_hardware *hardware)
{
char buffer[MENULEN + 1];
int nb_sub_disk_menu = 0;
@@ -232,8 +247,8 @@ void compute_disks(struct s_hdt_menu *menu, struct driveinfo *disk_info, struct
if (!hardware->disk_info[i].cbios)
continue; /* Invalid geometry */
compute_disk_module
- ((struct s_my_menu*) &(menu->disk_sub_menu), nb_sub_disk_menu, disk_info,
- i);
+ ((struct s_my_menu*) &(menu->disk_sub_menu), nb_sub_disk_menu,
+ hardware, i);
nb_sub_disk_menu++;
}
diff --git a/com32/hdt/hdt-menu-kernel.c b/com32/hdt/hdt-menu-kernel.c
index 7e2d6cab..81b44dbf 100644
--- a/com32/hdt/hdt-menu-kernel.c
+++ b/com32/hdt/hdt-menu-kernel.c
@@ -75,7 +75,7 @@ void compute_kernel(struct s_my_menu *menu, struct s_hardware *hardware)
kernel_modules,
pci_device->dev_info->class_name);
snprintf(infobar, sizeof infobar,
- "%04x:%04x %s : %s\n",
+ "%04x:%04x %s : %s",
pci_device->vendor,
pci_device->product,
pci_device->dev_info->vendor_name,
diff --git a/com32/hdt/hdt-menu-pci.c b/com32/hdt/hdt-menu-pci.c
index 4e0d5887..d4a6b7e7 100644
--- a/com32/hdt/hdt-menu-pci.c
+++ b/com32/hdt/hdt-menu-pci.c
@@ -167,7 +167,7 @@ int compute_PCI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
pci_device->dev_info->vendor_name,
pci_device->dev_info->product_name);
snprintf(infobar[i], STATLEN,
- "%02x:%02x.%01x # %s # ID:%04x:%04x[%04x:%04x] # Kmod:%s\n",
+ "%02x:%02x.%01x # %s # ID:%04x:%04x[%04x:%04x] # Kmod:%s",
__pci_bus, __pci_slot, __pci_func,
pci_device->dev_info->class_name, pci_device->vendor,
pci_device->product, pci_device->sub_vendor,
diff --git a/com32/hdt/hdt-menu-processor.c b/com32/hdt/hdt-menu-processor.c
index a30cf0f6..4e102cb5 100644
--- a/com32/hdt/hdt-menu-processor.c
+++ b/com32/hdt/hdt-menu-processor.c
@@ -231,6 +231,10 @@ void compute_processor(struct s_my_menu *menu, struct s_hardware *hardware)
strcat(buffer1, "3dnowext ");
if (hardware->cpu.flags.now)
strcat(buffer1, "3dnow! ");
+ if (hardware->cpu.flags.vmx)
+ strcat(buffer1, "vmx ");
+ if (hardware->cpu.flags.svm)
+ strcat(buffer1, "svm ");
snprintf(buffer, sizeof buffer, "Flags : %s", buffer1);
snprintf(statbuffer, sizeof statbuffer, "Flags: %s", buffer1);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
diff --git a/com32/hdt/hdt-menu-summary.c b/com32/hdt/hdt-menu-summary.c
index 6401221a..e8e2fc65 100644
--- a/com32/hdt/hdt-menu-summary.c
+++ b/com32/hdt/hdt-menu-summary.c
@@ -189,7 +189,7 @@ void compute_summarymenu(struct s_my_menu *menu, struct s_hardware *hardware)
kernel_modules,
pci_device->dev_info->class_name);
snprintf(statbuffer, sizeof statbuffer,
- "%04x:%04x %s : %s\n",
+ "%04x:%04x %s : %s",
pci_device->vendor,
pci_device->product,
pci_device->dev_info->vendor_name,
diff --git a/com32/hdt/hdt-menu-syslinux.c b/com32/hdt/hdt-menu-syslinux.c
index 4c874d0e..758274fe 100644
--- a/com32/hdt/hdt-menu-syslinux.c
+++ b/com32/hdt/hdt-menu-syslinux.c
@@ -76,8 +76,9 @@ void compute_syslinuxmenu(struct s_my_menu *menu, struct s_hardware *hardware)
snprintf(buffer, sizeof buffer, "%s",
hardware->sv->copyright_string + 1);
+ /* Remove the trailing LF in the copyright string to avoid scrolling */
snprintf(statbuffer, sizeof statbuffer, "%s",
- hardware->sv->copyright_string + 1);
+ remove_trailing_lf(hardware->sv->copyright_string + 1));
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu->items_count++;
diff --git a/com32/hdt/hdt-menu.c b/com32/hdt/hdt-menu.c
index c37fd41b..98eb45e7 100644
--- a/com32/hdt/hdt-menu.c
+++ b/com32/hdt/hdt-menu.c
@@ -27,6 +27,7 @@
*/
#include "hdt-menu.h"
+#include <unistd.h>
int start_menu_mode(struct s_hardware *hardware, char *version_string)
{
@@ -50,7 +51,8 @@ int start_menu_mode(struct s_hardware *hardware, char *version_string)
t_menuitem *curr;
char cmd[160];
- printf("Starting Menu (%d menus)\n", hdt_menu.total_menu_count);
+ if (!quiet)
+ more_printf("Starting Menu (%d menus)\n", hdt_menu.total_menu_count);
curr = showmenus(hdt_menu.main_menu.menu);
/* When we exit the menu, do we have something to do? */
if (curr) {
@@ -84,26 +86,32 @@ TIMEOUTCODE ontimeout()
}
/* Keyboard handler for the menu system */
-void keys_handler(t_menusystem * ms, t_menuitem * mi, unsigned int scancode)
+void keys_handler(t_menusystem * ms __attribute__ (( unused )), t_menuitem * mi, int scancode)
{
- char nc;
+ int nr, nc;
- if ((scancode >> 8) == F1) { // If scancode of F1
+ /* 0xFFFF is an invalid helpid */
+ if (scancode == KEY_F1 && mi->helpid != 0xFFFF) {
runhelpsystem(mi->helpid);
}
+
/*
* If user hit TAB, and item is an "executable" item
* and user has privileges to edit it, edit it in place.
*/
- if (((scancode & 0xFF) == 0x09) && (mi->action == OPT_RUN)) {
+ if ((scancode == KEY_TAB) && (mi->action == OPT_RUN)) {
//(isallowed(username,"editcmd") || isallowed(username,"root"))) {
- nc = getnumcols();
+ if (getscreensize(1, &nr, &nc)) {
+ /* Unknown screen size? */
+ nc = 80;
+ nr = 24;
+ }
/* User typed TAB and has permissions to edit command line */
- gotoxy(EDITPROMPT, 1, ms->menupage);
+ gotoxy(EDITPROMPT, 1);
csprint("Command line:", 0x07);
editstring(mi->data, ACTIONLEN);
- gotoxy(EDITPROMPT, 1, ms->menupage);
- cprint(' ', 0x07, nc - 1, ms->menupage);
+ gotoxy(EDITPROMPT, 1);
+ cprint(' ', 0x07, nc - 1);
}
}
@@ -114,6 +122,9 @@ void setup_menu(char *version)
init_menusystem(version);
set_window_size(0, 0, 25, 80);
+ /* Do not use inactive attributes - they make little sense for HDT */
+ set_normal_attr(-1, -1, 0x17, 0x1F);
+
/* Register the menusystem handler */
// reg_handler(HDLR_SCREEN,&msys_handler);
reg_handler(HDLR_KEYS, &keys_handler);
@@ -154,7 +165,7 @@ void compute_submenus(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
compute_processor(&(hdt_menu->cpu_menu), hardware);
compute_vpd(&(hdt_menu->vpd_menu), hardware);
- compute_disks(hdt_menu, hardware->disk_info, hardware);
+ compute_disks(hdt_menu, hardware);
#ifdef WITH_PCI
compute_PCI(hdt_menu, hardware);
@@ -282,6 +293,7 @@ void compute_main_menu(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
HDT_SWITCH_TO_CLI, 0);
add_item("<A>bout", "About Menu", OPT_SUBMENU, NULL,
hdt_menu->about_menu.menu);
+ add_item("<R>eboot", "Reboot", OPT_RUN, hardware->reboot_label, 0);
add_item("E<x>it","Exit", OPT_EXITMENU,NULL,0);
hdt_menu->main_menu.items_count++;
@@ -290,30 +302,37 @@ void compute_main_menu(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
void detect_hardware(struct s_hardware *hardware)
{
- printf("CPU: Detecting\n");
+ if (!quiet)
+ more_printf("CPU: Detecting\n");
cpu_detect(hardware);
- printf("DISKS: Detecting\n");
+ if (!quiet)
+ more_printf("DISKS: Detecting\n");
detect_disks(hardware);
- printf("DMI: Detecting Table\n");
+ if (!quiet)
+ more_printf("DMI: Detecting Table\n");
if (detect_dmi(hardware) == -ENODMITABLE) {
printf("DMI: ERROR ! Table not found ! \n");
printf
("DMI: Many hardware components will not be detected ! \n");
} else {
- printf("DMI: Table found ! (version %d.%d)\n",
- hardware->dmi.dmitable.major_version,
- hardware->dmi.dmitable.minor_version);
+ if (!quiet)
+ more_printf("DMI: Table found ! (version %u.%u)\n",
+ hardware->dmi.dmitable.major_version,
+ hardware->dmi.dmitable.minor_version);
}
- printf("VPD: Detecting\n");
+ if (!quiet)
+ more_printf("VPD: Detecting\n");
detect_vpd(hardware);
#ifdef WITH_PCI
detect_pci(hardware);
- printf("PCI: %d Devices Found\n", hardware->nb_pci_devices);
+ if (!quiet)
+ more_printf("PCI: %d Devices Found\n", hardware->nb_pci_devices);
#endif
- printf("VESA: Detecting\n");
+ if (!quiet)
+ more_printf("VESA: Detecting\n");
detect_vesa(hardware);
}
diff --git a/com32/hdt/hdt-menu.h b/com32/hdt/hdt-menu.h
index 1cd2c129..8743da35 100644
--- a/com32/hdt/hdt-menu.h
+++ b/com32/hdt/hdt-menu.h
@@ -29,6 +29,7 @@
#ifndef DEFINE_HDT_MENU_H
#define DEFINE_HDT_MENU_H
#include <stdio.h>
+#include <getkey.h>
#include "menu.h"
#include "help.h"
@@ -82,7 +83,7 @@ struct s_hdt_menu {
};
TIMEOUTCODE ontimeout();
-void keys_handler(t_menusystem * ms, t_menuitem * mi, unsigned int scancode);
+void keys_handler(t_menusystem * ms __attribute__ (( unused )), t_menuitem * mi, int scancode);
// PCI Stuff
int compute_PCI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
@@ -91,7 +92,7 @@ int compute_PCI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
void compute_kernel(struct s_my_menu *menu, struct s_hardware *hardware);
// Disk Stuff
-void compute_disks(struct s_hdt_menu *menu, struct driveinfo *disk_info, struct s_hardware *hardware);
+void compute_disks(struct s_hdt_menu *menu, struct s_hardware *hardware);
// DMI Stuff
void compute_motherboard(struct s_my_menu *menu, s_dmi * dmi);
diff --git a/com32/hdt/hdt.c b/com32/hdt/hdt.c
index 93c4aae2..0fe2021b 100644
--- a/com32/hdt/hdt.c
+++ b/com32/hdt/hdt.c
@@ -37,10 +37,10 @@
#include <consoles.h>
#include "hdt.h"
#include "hdt-menu.h"
-#include "hdt-cli.h"
#include "hdt-common.h"
int display_line_nb = 0;
+bool disable_more_printf = false;
int main(const int argc, const char *argv[])
{
@@ -48,8 +48,8 @@ int main(const int argc, const char *argv[])
const char *arg;
struct s_hardware hardware;
- snprintf(version_string, sizeof version_string, "%s %s by %s",
- PRODUCT_NAME,VERSION,AUTHOR);
+ snprintf(version_string, sizeof version_string, "%s %s (%s)",
+ PRODUCT_NAME,VERSION, CODENAME);
/* Opening the Syslinux console */
console_ansi_raw();
@@ -63,20 +63,19 @@ int main(const int argc, const char *argv[])
/* Detecting parameters */
detect_parameters(argc, argv, &hardware);
-
+ /* Clear the screen and reset position of the cursor */
clear_screen();
- printf("%s\n", version_string);
+ printf("\033[1;1H");
- if ((arg = find_argument(argv + 1, "nomenu")))
- start_cli_mode(&hardware);
+ printf("%s\n", version_string);
+ if ((arg = find_argument(argv + 1, "nomenu")) || (find_argument(argv+1,"auto")))
+ start_cli_mode(&hardware);
else {
- int return_code = start_menu_mode(&hardware, version_string);
-
- if (return_code == HDT_RETURN_TO_CLI)
- start_cli_mode(&hardware);
- else
- return return_code;
+ int return_code = start_menu_mode(&hardware, version_string);
+ if (return_code == HDT_RETURN_TO_CLI)
+ start_cli_mode(&hardware);
+ else
+ return return_code;
}
-
return 0;
}
diff --git a/com32/hdt/hdt.h b/com32/hdt/hdt.h
index 04c0e664..2c2c8796 100644
--- a/com32/hdt/hdt.h
+++ b/com32/hdt/hdt.h
@@ -31,10 +31,12 @@
#define PRODUCT_NAME "Hardware Detection Tool"
#define AUTHOR "Erwan Velu"
+#define CORE_DEVELOPER "Pierre-Alexandre Meyer"
#define CONTACT "hdt@zytor.com"
-#define VERSION "0.3.4"
+#define VERSION "0.3.5-pre3"
+#define CODENAME "mojito"
#define NB_CONTRIBUTORS 2
-#define CONTRIBUTORS {"Pierre-Alexandre Meyer", "Sebastien Gonzalve"}
+#define CONTRIBUTORS {"Sebastien Gonzalve", "Gert Hulselmans"}
#define ATTR_PACKED __attribute__((packed))
diff --git a/com32/hdt/lib-ansi.c b/com32/hdt/lib-ansi.c
deleted file mode 100644
index 411dba80..00000000
--- a/com32/hdt/lib-ansi.c
+++ /dev/null
@@ -1,104 +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.
- *
- * -----------------------------------------------------------------------
- * Ansi Sequences can be found here :
- * http://ascii-table.com/ansi-escape-sequences-vt-100.php
- * http://en.wikipedia.org/wiki/ANSI_escape_code
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdbool.h>
-
-void display_cursor(bool status)
-{
- if (status == true) {
- fputs("\033[?25h", stdout);
- } else {
- fputs("\033[?25l", stdout);
- }
-}
-
-void clear_end_of_line() {
- fputs("\033[0K", stdout);
-}
-
-void move_cursor_left(int count) {
- char buffer[10];
- memset(buffer,0,sizeof(buffer));
- sprintf(buffer,"\033[%dD",count);
- fputs(buffer, stdout);
-}
-
-void move_cursor_right(int count) {
- char buffer[10];
- memset(buffer,0,sizeof(buffer));
- sprintf(buffer,"\033[%dC",count);
- fputs(buffer, stdout);
-}
-
-void set_cursor_blink(bool status) {
- if (status == true)
- fputs("\033[05m",stdout);
- else
- fputs("\033[0m",stdout);
-}
-
-void clear_line() {
- fputs("\033[2K", stdout);
-}
-
-void clear_beginning_of_line() {
- fputs("\033[1K", stdout);
-}
-
-void move_cursor_to_column(int count) {
- char buffer[10];
- memset(buffer,0,sizeof(buffer));
- sprintf(buffer,"\033[%dG",count);
- fputs(buffer, stdout);
-}
-
-void move_cursor_to_next_line() {
- fputs("\033e", stdout);
-}
-
-void disable_utf8() {
- fputs("\033%@", stdout);
-}
-
-void set_g1_special_char(){
- fputs("\033)0", stdout);
-}
-
-void set_us_g0_charset() {
- fputs("\033(B\1#0", stdout);
-}
-
-void clear_entire_screen() {
- fputs("\033[2J", stdout);
-}
diff --git a/com32/include/cpufeature.h b/com32/include/cpufeature.h
index 2fd47579..036631a7 100644
--- a/com32/include/cpufeature.h
+++ b/com32/include/cpufeature.h
@@ -72,6 +72,7 @@
#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
#define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */
#define X86_FEATURE_DSCPL (4*32+ 4) /* CPL Qualified Debug Store */
+#define X86_FEATURE_VMX (4*32+ 5) /* Hardware virtualization */
#define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */
#define X86_FEATURE_TM2 (4*32+ 8) /* Thermal Monitor 2 */
#define X86_FEATURE_CID (4*32+10) /* Context ID */
@@ -87,6 +88,7 @@
/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
#define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */
#define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
+#define X86_FEATURE_SVM (6*32+ 2) /* Secure virtual machine */
#endif /* __ASM_I386_CPUFEATURE_H */
diff --git a/com32/hdt/lib-ansi.h b/com32/include/libansi.h
index 0b0d0d18..d813f9fc 100644
--- a/com32/hdt/lib-ansi.h
+++ b/com32/include/libansi.h
@@ -28,17 +28,76 @@
#ifndef DEFINE_LIB_ANSI_H
#define DEFINE_LIB_ANSI_H
+
+#define CSI "\e["
+
void display_cursor(bool status);
-void clear_end_of_line();
+void clear_end_of_line(void);
void move_cursor_left(int count);
void move_cursor_right(int count);
-void clear_line();
-void clear_beginning_of_line();
+void clear_line(void);
+void clear_beginning_of_line(void);
void move_cursor_to_column(int count);
-void move_cursor_to_next_line();
-void disable_utf8();
-void set_g1_special_char();
-void set_us_g0_charset();
-void clear_entire_screen();
+void move_cursor_to_next_line(void);
+void disable_utf8(void);
+void set_g1_special_char(void);
+void set_us_g0_charset(void);
+void clear_entire_screen(void);
void set_cursor_blink(bool status);
+void move_cursor_to_next_line(void);
+void disable_utf8(void);
+void set_g1_special_char(void);
+void set_us_g0_charset(void);
+void clear_entire_screen(void);
+void clearwindow(const char top, const char left, const char bot,
+ const char right, const char fillchar, const char fillattr);
+
+static inline void beep(void)
+{
+ fputs("\007", stdout);
+}
+
+void reset_colors(void);
+
+/* Print a string */
+void csprint(const char *, const char);
+
+/* Print one character, one or more times */
+void cprint(const char, const char, unsigned int);
+
+/* Print one character, once */
+static inline void putch(const char x, char attr)
+{
+ cprint(x, attr, 1);
+}
+
+void cls(void);
+
+static inline void cursoroff(void)
+{
+ display_cursor(false);
+}
+
+static inline void cursoron(void)
+{
+ display_cursor(true);
+}
+
+static inline void scrollup(int times)
+{
+ if (times > 0)
+ printf(CSI "%dS", times);
+}
+
+/* Scroll up display screen by one line */
+static inline void scrollup_once(void)
+{
+ printf(CSI "S");
+}
+
+static inline void gotoxy(const char row, const char col)
+{
+ printf(CSI "%d;%dH", row + 1, col + 1);
+}
+
#endif
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index c5b19813..ecf4dfeb 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -54,6 +54,8 @@ LIBOBJS = \
\
sys/ansi.o \
\
+ sys/libansi.o \
+ \
sys/ansicon_write.o sys/ansiserial_write.o \
\
sys/vesacon_write.o sys/vesaserial_write.o \
diff --git a/com32/lib/sys/ansi.c b/com32/lib/sys/ansi.c
index 7d580856..17ace1d4 100644
--- a/com32/lib/sys/ansi.c
+++ b/com32/lib/sys/ansi.c
@@ -36,21 +36,22 @@
#include "ansi.h"
static const struct term_state default_state = {
+ .state = st_init,
+ .pvt = false,
+ .nparms = 0,
.xy = {0, 0},
.cindex = 0, /* First color table entry */
- .vtgraphics = 0,
+ .vtgraphics = false,
.intensity = 1,
- .underline = 0,
- .blink = 0,
- .reverse = 0,
+ .underline = false,
+ .blink = false,
+ .reverse = false,
.fg = 7,
.bg = 0,
- .autocr = 1, /* Mimic \n -> \r\n conversion by default */
+ .autocr = true, /* Mimic \n -> \r\n conversion by default */
+ .autowrap = true, /* Wrap lines by default */
.saved_xy = {0, 0},
- .cursor = 1,
- .state = st_init,
- .pvt = 0,
- .nparms = 0,
+ .cursor = true,
};
/* DEC VT graphics to codepage 437 table (characters 0x60-0x7F only) */
@@ -123,7 +124,7 @@ void __ansi_putchar(const struct term_info *ti, uint8_t ch)
if (st->vtgraphics && (ch & 0xe0) == 0x60)
ch = decvt_to_cp437[ch - 0x60];
- op->write_char(xy.x, xy.y, ch, st);
+ op->write_char(xy.x, xy.y, BIOS_PAGE, ch, st);
xy.x++;
}
break;
@@ -141,7 +142,8 @@ void __ansi_putchar(const struct term_info *ti, uint8_t ch)
break;
case '[':
st->state = st_csi;
- st->nparms = st->pvt = 0;
+ st->nparms = 0;
+ st->pvt = false;
memset(st->parms, 0, sizeof st->parms);
break;
case 'c':
@@ -170,7 +172,7 @@ void __ansi_putchar(const struct term_info *ti, uint8_t ch)
st->nparms = ANSI_MAX_PARMS - 1;
break;
} else if (ch == '?') {
- st->pvt = 1;
+ st->pvt = true;
} else {
switch (ch) {
case 'A':
@@ -278,22 +280,25 @@ void __ansi_putchar(const struct term_info *ti, uint8_t ch)
break;
case 'h':
case 'l':
- {
- int set = (ch == 'h');
- switch (st->parms[0]) {
- case 20:
- st->autocr = set;
- break;
- case 25:
- st->cursor = set;
- op->showcursor(st);
- break;
- default:
- /* Ignore */
- break;
- }
+ {
+ bool set = (ch == 'h');
+ switch (st->parms[0]) {
+ case 7: /* DECAWM */
+ st->autowrap = set;
+ break;
+ case 20: /* LNM */
+ st->autocr = set;
+ break;
+ case 25: /* DECTECM */
+ st->cursor = set;
+ op->showcursor(st);
+ break;
+ default:
+ /* Ignore */
+ break;
}
break;
+ }
case 'm':
{
static const int ansi2pc[8] =
@@ -421,8 +426,12 @@ void __ansi_putchar(const struct term_info *ti, uint8_t ch)
/* If we fell off the end of the screen, adjust */
if (xy.x >= cols) {
- xy.x = 0;
- xy.y++;
+ if (st->autowrap) {
+ xy.x = 0;
+ xy.y++;
+ } else {
+ xy.x = cols - 1;
+ }
}
while (xy.y >= rows) {
xy.y--;
@@ -430,6 +439,6 @@ void __ansi_putchar(const struct term_info *ti, uint8_t ch)
}
/* Update cursor position */
- op->set_cursor(xy.x, xy.y, st->cursor);
+ op->set_cursor(xy.x, xy.y, BIOS_PAGE, st->cursor);
st->xy = xy;
}
diff --git a/com32/lib/sys/ansi.h b/com32/lib/sys/ansi.h
index 0d1f1025..ed4b01cb 100644
--- a/com32/lib/sys/ansi.h
+++ b/com32/lib/sys/ansi.h
@@ -6,9 +6,15 @@
#define COM32_LIB_SYS_ANSI_H
#include <inttypes.h>
+#include <stdbool.h>
#define ANSI_MAX_PARMS 16
+#define BIOS_CURXY ((struct curxy *)0x450) /* Array for each page */
+#define BIOS_ROWS (*(uint8_t *)0x484) /* Minus one; if zero use 24 (= 25 lines) */
+#define BIOS_COLS (*(uint16_t *)0x44A) /* Number of columns on screen */
+#define BIOS_PAGE (*(uint8_t *)0x462) /* Current page number */
+
enum ansi_state {
st_init,
st_esc,
@@ -22,31 +28,32 @@ struct curxy {
} __attribute__ ((packed));
struct term_state {
- struct curxy xy;
- int cindex; /* SOH color index */
- int vtgraphics; /* VT graphics on/off */
- int intensity;
- int underline;
- int blink;
- int reverse;
- int fg;
- int bg;
- int autocr;
- struct curxy saved_xy;
- int cursor;
enum ansi_state state;
- int pvt; /* Private code? */
int nparms; /* Number of parameters seen */
int parms[ANSI_MAX_PARMS];
+ bool pvt; /* Private code? */
+ struct curxy xy;
+ struct curxy saved_xy;
+ uint8_t cindex; /* SOH color index */
+ uint8_t fg;
+ uint8_t bg;
+ uint8_t intensity;
+ bool vtgraphics; /* VT graphics on/off */
+ bool underline;
+ bool blink;
+ bool reverse;
+ bool autocr;
+ bool autowrap;
+ bool cursor;
};
struct ansi_ops {
void (*erase) (const struct term_state * st, int x0, int y0, int x1,
int y1);
- void (*write_char) (int x, int y, uint8_t ch, const struct term_state * st);
+ void (*write_char) (int x, int y, int page, uint8_t ch, const struct term_state * st);
void (*showcursor) (const struct term_state * st);
void (*scroll_up) (const struct term_state * st);
- void (*set_cursor) (int x, int y, int visible);
+ void (*set_cursor) (int x, int y, int page, int visible);
void (*beep) (void);
};
diff --git a/com32/lib/sys/ansicon_write.c b/com32/lib/sys/ansicon_write.c
index 7c2754e7..8ec16b0a 100644
--- a/com32/lib/sys/ansicon_write.c
+++ b/com32/lib/sys/ansicon_write.c
@@ -44,10 +44,10 @@
#include "ansi.h"
static void ansicon_erase(const struct term_state *, int, int, int, int);
-static void ansicon_write_char(int, int, uint8_t, const struct term_state *);
+static void ansicon_write_char(int, int, int, uint8_t, const struct term_state *);
static void ansicon_showcursor(const struct term_state *);
static void ansicon_scroll_up(const struct term_state *);
-static void ansicon_set_cursor(int, int, int);
+static void ansicon_set_cursor(int, int, int, int);
static struct term_state ts;
struct ansi_ops __ansicon_ops = {
@@ -65,11 +65,6 @@ static struct term_info ti = {
.op = &__ansicon_ops
};
-#define BIOS_CURXY ((struct curxy *)0x450) /* Array for each page */
-#define BIOS_ROWS (*(uint8_t *)0x484) /* Minus one; if zero use 24 (= 25 lines) */
-#define BIOS_COLS (*(uint16_t *)0x44A)
-#define BIOS_PAGE (*(uint8_t *)0x462)
-
/* Reference counter to the screen, to keep track of if we need
reinitialization. */
static int ansicon_counter = 0;
@@ -176,9 +171,8 @@ static void ansicon_showcursor(const struct term_state *st)
__intcall(0x10, &ireg, NULL);
}
-static void ansicon_set_cursor(int x, int y, int visible)
+static void ansicon_set_cursor(int x, int y, int page, int visible)
{
- const int page = BIOS_PAGE;
struct curxy xy = BIOS_CURXY[page];
static com32sys_t ireg;
@@ -193,16 +187,16 @@ static void ansicon_set_cursor(int x, int y, int visible)
}
}
-static void ansicon_write_char(int x, int y, uint8_t ch,
+static void ansicon_write_char(int x, int y, int page, uint8_t ch,
const struct term_state *st)
{
static com32sys_t ireg;
- ansicon_set_cursor(x, y, 0);
+ ansicon_set_cursor(x, y, 0, page);
ireg.eax.b[1] = 0x09;
ireg.eax.b[0] = ch;
- ireg.ebx.b[1] = BIOS_PAGE;
+ ireg.ebx.b[1] = page;
ireg.ebx.b[0] = ansicon_attribute(st);
ireg.ecx.w[0] = 1;
__intcall(0x10, &ireg, NULL);
diff --git a/com32/lib/sys/libansi.c b/com32/lib/sys/libansi.c
new file mode 100644
index 00000000..5bc0026e
--- /dev/null
+++ b/com32/lib/sys/libansi.c
@@ -0,0 +1,237 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * 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.
+ *
+ * -----------------------------------------------------------------------
+ * Ansi Sequences can be found here :
+ * http://ascii-table.com/ansi-escape-sequences-vt-100.php
+ * http://en.wikipedia.org/wiki/ANSI_escape_code
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "libansi.h"
+
+void display_cursor(bool status)
+{
+ if (status == true) {
+ fputs(CSI "?25h", stdout);
+ } else {
+ fputs(CSI "?25l", stdout);
+ }
+}
+
+void clear_end_of_line() {
+ fputs(CSI "0K", stdout);
+}
+
+void move_cursor_left(int count) {
+ char buffer[10];
+ memset(buffer,0,sizeof(buffer));
+ sprintf(buffer,CSI "%dD",count);
+ fputs(buffer, stdout);
+}
+
+void move_cursor_right(int count) {
+ char buffer[10];
+ memset(buffer,0,sizeof(buffer));
+ sprintf(buffer, CSI "%dC", count);
+ fputs(buffer, stdout);
+}
+
+void set_cursor_blink(bool status) {
+ if (status == true)
+ fputs("\033[05m",stdout);
+ else
+ fputs("\033[0m",stdout);
+}
+
+void clear_line() {
+ fputs(CSI "2K", stdout);
+}
+
+void clear_beginning_of_line() {
+ fputs(CSI "1K", stdout);
+}
+
+void move_cursor_to_column(int count) {
+ char buffer[10];
+ memset(buffer,0,sizeof(buffer));
+ sprintf(buffer, CSI "%dG", count);
+ fputs(buffer, stdout);
+}
+
+void move_cursor_to_next_line() {
+ fputs("\033e", stdout);
+}
+
+void disable_utf8() {
+ fputs("\033%@", stdout);
+}
+
+void set_g1_special_char(){
+ fputs("\033)0", stdout);
+}
+
+void set_us_g0_charset() {
+ fputs("\033(B\1#0", stdout);
+}
+
+void clear_entire_screen() {
+ fputs(CSI "2J", stdout);
+}
+
+/**
+ * cprint_vga2ansi - given a VGA attribute, print a character
+ * @chr: character to print
+ * @attr: vga attribute
+ *
+ * Convert the VGA attribute @attr to an ANSI escape sequence and
+ * print it.
+ * For performance, SGR parameters are cached. To reset them,
+ * call cprint_vga2ansi('0', '0').
+ **/
+static void cprint_vga2ansi(const char chr, const char attr)
+{
+ static const char ansi_char[8] = "04261537";
+ static uint16_t last_attr = 0x300;
+ char buf[16], *p;
+
+ if (chr == '0' && attr == '0') {
+ last_attr = 0x300;
+ return;
+ }
+
+ if (attr != last_attr) {
+ bool reset = false;
+ p = buf;
+ *p++ = '\033';
+ *p++ = '[';
+
+ if (last_attr & ~attr & 0x88) {
+ *p++ = '0';
+ *p++ = ';';
+ /* Reset last_attr to unknown to handle
+ * background/foreground attributes correctly */
+ last_attr = 0x300;
+ reset = true;
+ }
+ if (attr & 0x08) {
+ *p++ = '1';
+ *p++ = ';';
+ }
+ if (attr & 0x80) {
+ *p++ = '4';
+ *p++ = ';';
+ }
+ if (reset || (attr ^ last_attr) & 0x07) {
+ *p++ = '3';
+ *p++ = ansi_char[attr & 7];
+ *p++ = ';';
+ }
+ if (reset || (attr ^ last_attr) & 0x70) {
+ *p++ = '4';
+ *p++ = ansi_char[(attr >> 4) & 7];
+ *p++ = ';';
+ }
+ p[-1] = 'm'; /* We'll have generated at least one semicolon */
+ p[0] = '\0';
+
+ last_attr = attr;
+
+ fputs(buf, stdout);
+ }
+
+ putchar(chr);
+}
+
+/*
+ * cls - clear and initialize the entire screen
+ *
+ * Note: when initializing xterm, one has to specify that
+ * G1 points to the alternate character set (this is not true
+ * by default). Without the initial printf "\033)0", line drawing
+ * characters won't be displayed.
+ */
+void cls(void)
+{
+ fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout);
+
+ /* Reset SGR parameters cache */
+ cprint_vga2ansi('0', '0');
+}
+
+void reset_colors()
+{
+ csprint(CSI "1D", 0x07);
+}
+
+/**
+ * cprint - given a VGA attribute, print a single character at cursor
+ * @chr: character to print
+ * @attr: VGA attribute
+ * @times: number of times to print @chr
+ *
+ * Note: @attr is a VGA attribute.
+ **/
+void cprint(const char chr, const char attr, unsigned int times)
+{
+ while (times--)
+ cprint_vga2ansi(chr, attr);
+}
+
+/**
+ * csprint - given a VGA attribute, print a NULL-terminated string
+ * @str: string to print
+ * @attr: VGA attribute
+ **/
+void csprint(const char *str, const char attr)
+{
+ while (*str) {
+ cprint(*str, attr, 1);
+ str++;
+ }
+}
+
+/**
+ * clearwindow - fill a given a region on the screen
+ * @top, @left, @bot, @right: coordinates to fill
+ * @fillchar: character to use to fill the region
+ * @fillattr: character attribute (VGA)
+ **/
+void clearwindow(const char top, const char left, const char bot,
+ const char right, const char fillchar, const char fillattr)
+{
+ char x;
+ for (x = top; x < bot + 1; x++) {
+ gotoxy(x, left);
+ cprint(fillchar, fillattr, right - left + 1);
+ }
+}
+
+
diff --git a/com32/mboot/map.c b/com32/mboot/map.c
index 1a788ef7..887776fe 100644
--- a/com32/mboot/map.c
+++ b/com32/mboot/map.c
@@ -127,7 +127,7 @@ int map_image(void *ptr, size_t len)
else
mbh_len = 12;
- if (i + mbh_len < len)
+ if (i + mbh_len > len)
mbh_len = 0; /* Invalid... */
else
break; /* Found something... */
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 68e50571..4e262782 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -18,10 +18,10 @@
topdir = ../..
include ../MCONFIG
-MODULES = chain.c32 config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 disk.c32 \
- pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 meminfo.c32 \
- sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 kbdmap.c32 cmd.c32 \
- vpdtest.c32 host.c32 dir.c32
+MODULES = chain.c32 config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \
+ disk.c32 pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 \
+ meminfo.c32 sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 \
+ kbdmap.c32 cmd.c32 vpdtest.c32 host.c32 dir.c32 gpxecmd.c32
TESTFILES =
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index bdeb82d5..27220143 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -39,6 +39,12 @@
* seg=<segment>:
* loads at and jumps to <seg>:0000 instead of 0000:7C00.
*
+ * isolinux=<loader>:
+ * chainload another version/build of the ISOLINUX bootloader and patch
+ * the loader with appropriate parameters in memory.
+ * This avoids the need for the -eltorito-alt-boot parameter of mkisofs,
+ * when you want more than one ISOLINUX per CD/DVD.
+ *
* ntldr=<loader>:
* equivalent to -seg 0x2000 -file <loader>, used with WinNT's loaders
*
@@ -77,6 +83,7 @@ static struct options {
const char *loadfile;
uint16_t keeppxe;
uint16_t seg;
+ bool isolinux;
bool swap;
bool hide;
} opt;
@@ -446,7 +453,7 @@ static void do_boot(void *boot_sector, size_t boot_size,
mmap = syslinux_memory_map();
if (!mmap) {
- error("Cannot read system memory map");
+ error("Cannot read system memory map\n");
return;
}
@@ -546,12 +553,12 @@ static void do_boot(void *boot_sector, size_t boot_size,
error("Chainboot failed!\n");
return;
-too_big:
- error("Loader file too large");
+ too_big:
+ error("Loader file too large\n");
return;
-enomem:
- error("Out of memory");
+ enomem:
+ error("Out of memory\n");
return;
}
@@ -589,6 +596,47 @@ static int hide_unhide(char *mbr, int part)
return 0; /* ok */
}
+static uint32_t get_file_lba(const char *filename)
+{
+ com32sys_t inregs;
+ uint32_t lba;
+
+ /* Start with clean registers */
+ memset(&inregs, 0, sizeof(com32sys_t));
+
+ /* Put the filename in the bounce buffer */
+ strlcpy(__com32.cs_bounce, filename, __com32.cs_bounce_size);
+
+ /* Call comapi_open() which returns a structure pointer in SI
+ * to a structure whose first member happens to be the LBA.
+ */
+ inregs.eax.w[0] = 0x0006;
+ inregs.esi.w[0] = OFFS(__com32.cs_bounce);
+ inregs.es = SEG(__com32.cs_bounce);
+ __com32.cs_intcall(0x22, &inregs, &inregs);
+
+ if ((inregs.eflags.l & EFLAGS_CF) || inregs.esi.w[0] == 0) {
+ return 0; /* Filename not found */
+ }
+
+ /* Since the first member is the LBA, we simply cast */
+ lba = *((uint32_t *) MK_PTR(inregs.ds, inregs.esi.w[0]));
+
+ /* Clean the registers for the next call */
+ memset(&inregs, 0, sizeof(com32sys_t));
+
+ /* Put the filename in the bounce buffer */
+ strlcpy(__com32.cs_bounce, filename, __com32.cs_bounce_size);
+
+ /* Call comapi_close() to free the structure */
+ inregs.eax.w[0] = 0x0008;
+ inregs.esi.w[0] = OFFS(__com32.cs_bounce);
+ inregs.es = SEG(__com32.cs_bounce);
+ __com32.cs_intcall(0x22, &inregs, &inregs);
+
+ return lba;
+}
+
int main(int argc, char *argv[])
{
char *mbr, *p;
@@ -598,6 +646,9 @@ int main(int argc, char *argv[])
char *drivename, *partition;
int hd, drive, whichpart;
int i;
+ uint32_t file_lba = 0;
+ unsigned char *isolinux_bin;
+ uint32_t *checksum, *chkhead, *chktail;
size_t boot_size = SECTOR;
openconsole(&dev_null_r, &dev_stdcon_w);
@@ -614,10 +665,13 @@ int main(int argc, char *argv[])
} else if (!strncmp(argv[i], "seg=", 4)) {
uint32_t segval = strtoul(argv[i] + 4, NULL, 0);
if (segval < 0x50 || segval > 0x9f000) {
- error("Invalid segment");
+ error("Invalid segment\n");
goto bail;
}
opt.seg = segval;
+ } else if (!strncmp(argv[i], "isolinux=", 9)) {
+ opt.loadfile = argv[i] + 9;
+ opt.isolinux = true;
} else if (!strncmp(argv[i], "ntldr=", 6)) {
opt.seg = 0x2000; /* NTLDR wants this address */
opt.loadfile = argv[i] + 6;
@@ -650,7 +704,19 @@ int main(int argc, char *argv[])
}
} else {
error
- ("Usage: chain.c32 (hd#|fd#|mbr:#|boot)[,partition] [options]\n");
+ ("Usage: chain.c32 hd<disk#> [<partition>] [options]\n"
+ " chain.c32 fd<disk#> [options]\n"
+ " chain.c32 mbr:<id> [<partition>] [options]\n"
+ " chain.c32 boot [<partition>] [options]\n"
+ "Options: file=<loader> load file, instead of boot sector\n"
+ " isolinux=<loader> load another version of ISOLINUX\n"
+ " ntldr=<loader> load Windows bootloaders: NTLDR, SETUPLDR, BOOTMGR\n"
+ " freedos=<loader> load FreeDOS kernel.sys\n"
+ " msdos=<loader> load MS-DOS io.sys\n"
+ " pcdos=<loader> load PC-DOS ibmbio.com\n"
+ " seg=<segment> jump to <seg>:0000 instead of 0000:7C00\n"
+ " swap swap drive numbers, if bootdisk is not fd0/hd0\n"
+ " hide hide primary partitions, except selected partition\n");
goto bail;
}
}
@@ -748,6 +814,64 @@ int main(int argc, char *argv[])
error("Failed to load the boot file\n");
goto bail;
}
+
+ /* Create boot info table: needed when you want to chainload
+ another version of ISOLINUX (or another bootlaoder that needs
+ the -boot-info-table switch of mkisofs)
+ (will only work when run from ISOLINUX) */
+ if (opt.isolinux) {
+ const union syslinux_derivative_info *sdi;
+ sdi = syslinux_derivative_info();
+
+ if (sdi->c.filesystem == SYSLINUX_FS_ISOLINUX) {
+ /* Boot info table info (integers in little endian format)
+
+ Offset Name Size Meaning
+ 8 bi_pvd 4 bytes LBA of primary volume descriptor
+ 12 bi_file 4 bytes LBA of boot file
+ 16 bi_length 4 bytes Boot file length in bytes
+ 20 bi_csum 4 bytes 32-bit checksum
+ 24 bi_reserved 40 bytes Reserved
+
+ The 32-bit checksum is the sum of all the 32-bit words in the
+ boot file starting at byte offset 64. All linear block
+ addresses (LBAs) are given in CD sectors (normally 2048 bytes).
+
+ LBA of primary volume descriptor should already be set to 16.
+ */
+
+ isolinux_bin = (unsigned char *)boot_sector;
+
+ /* Get LBA address of bootfile */
+ file_lba = get_file_lba(opt.loadfile);
+
+ if (file_lba == 0) {
+ error("Failed to find LBA offset of the boot file\n");
+ goto bail;
+ }
+ /* Set it */
+ *((uint32_t *) & isolinux_bin[12]) = file_lba;
+
+ /* Set boot file length */
+ *((uint32_t *) & isolinux_bin[16]) = boot_size;
+
+ /* Calculate checksum */
+ checksum = (uint32_t *) & isolinux_bin[20];
+ chkhead = (uint32_t *) & isolinux_bin[64];
+ chktail = (uint32_t *) & isolinux_bin[boot_size - 1];
+ /* Fresh checksum and clear possibly fractional uint32_t at the end */
+ *checksum = *((uint32_t *) & isolinux_bin[boot_size]) = 0;
+
+ while (chkhead <= chktail) {
+ *checksum += *chkhead++;
+ }
+ } else {
+ error
+ ("The isolinux= option is only valid when run from ISOLINUX\n");
+ goto bail;
+ }
+ }
+
} else if (partinfo) {
/* Actually read the boot sector */
/* Pick the first buffer that isn't already in use */
@@ -773,6 +897,6 @@ int main(int argc, char *argv[])
do_boot(boot_sector, boot_size, &regs);
-bail:
+ bail:
return 255;
}
diff --git a/com32/modules/cpuidtest.c b/com32/modules/cpuidtest.c
index bfc1c190..b7688852 100644
--- a/com32/modules/cpuidtest.c
+++ b/com32/modules/cpuidtest.c
@@ -121,6 +121,10 @@ int main(void)
printf("3dnowext ");
if (cpu.flags.now)
printf("3dnow! ");
+ if (cpu.flags.vmx)
+ printf("vmx ");
+ if (cpu.flags.svm)
+ printf("svm ");
printf("\n");
printf("SMP = ");
if (cpu.flags.smp)
diff --git a/com32/modules/dmitest.c b/com32/modules/dmitest.c
index d85b3127..212e82af 100644
--- a/com32/modules/dmitest.c
+++ b/com32/modules/dmitest.c
@@ -179,7 +179,7 @@ int main(void)
printf("No DMI Structure found\n");
return -1;
} else {
- printf("DMI %d.%d present.\n", dmi.dmitable.major_version,
+ printf("DMI %u.%u present.\n", dmi.dmitable.major_version,
dmi.dmitable.minor_version);
printf("%d structures occupying %d bytes.\n", dmi.dmitable.num,
dmi.dmitable.len);
diff --git a/com32/modules/gpxecmd.c b/com32/modules/gpxecmd.c
new file mode 100644
index 00000000..de6ffb21
--- /dev/null
+++ b/com32/modules/gpxecmd.c
@@ -0,0 +1,137 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * gpxecmd.c
+ *
+ * Invoke an arbitrary gPXE command, if available.
+ */
+
+#include <alloca.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <console.h>
+#include <com32.h>
+#include <stdbool.h>
+#include <string.h>
+#include <syslinux/config.h>
+
+struct segoff16 {
+ uint16_t offs, seg;
+};
+
+struct s_PXENV_FILE_CHECK_API {
+ uint16_t Status;
+ uint16_t Size;
+ uint32_t Magic;
+ uint32_t Provider;
+ uint32_t APIMask;
+ uint32_t Flags;
+};
+
+static bool is_gpxe(void)
+{
+ const struct syslinux_version *sv;
+ com32sys_t reg;
+ struct s_PXENV_FILE_CHECK_API *fca;
+
+ sv = syslinux_version();
+ if (sv->filesystem != SYSLINUX_FS_PXELINUX)
+ return false; /* Not PXELINUX */
+
+ fca = __com32.cs_bounce;
+ memset(fca, 0, sizeof *fca);
+ fca->Size = sizeof *fca;
+ fca->Magic = 0x91d447b2;
+
+ memset(&reg, 0, sizeof reg);
+ reg.eax.w[0] = 0x0009;
+ reg.ebx.w[0] = 0x00e6; /* PXENV_FILE_API_CHECK */
+ reg.edi.w[0] = OFFS(fca);
+ reg.es = SEG(fca);
+
+ __intcall(0x22, &reg, &reg);
+
+ if (reg.eflags.l & EFLAGS_CF)
+ return false; /* Cannot invoke PXE stack */
+
+ if (reg.eax.w[0] || fca->Status)
+ return false; /* PXE failure */
+
+ if (fca->Magic != 0xe9c17b20)
+ return false; /* Incorrect magic */
+
+ if (fca->Size < sizeof *fca)
+ return false; /* Short return */
+
+ if (!(fca->APIMask & (1 << 5)))
+ return false; /* No FILE EXEC */
+
+ return true;
+}
+
+struct s_PXENV_FILE_EXEC {
+ uint16_t Status;
+ struct segoff16 Command;
+};
+
+static void gpxecmd(const char **args)
+{
+ char *q;
+ struct s_PXENV_FILE_EXEC *fx;
+ com32sys_t reg;
+
+ memset(&reg, 0, sizeof reg);
+
+ fx = __com32.cs_bounce;
+ q = (char *)(fx + 1);
+
+ fx->Status = 1;
+ fx->Command.offs = OFFS(q);
+ fx->Command.seg = SEG(q);
+
+ while (*args) {
+ q = stpcpy(q, *args);
+ *q++ = ' ';
+ args++;
+ }
+ *--q = '\0';
+
+ memset(&reg, 0, sizeof reg);
+ reg.eax.w[0] = 0x0009;
+ reg.ebx.w[0] = 0x00e5; /* PXENV_FILE_EXEC */
+ reg.edi.w[0] = OFFS(fx);
+ reg.es = SEG(fx);
+
+ __intcall(0x22, &reg, &reg);
+
+ /* This should not return... */
+}
+
+int main(int argc, const char *argv[])
+{
+ openconsole(&dev_null_r, &dev_stdcon_w);
+
+ if (argc < 2) {
+ printf("Usage: gpxecmd command...\n");
+ return 1;
+ }
+
+ if (!is_gpxe()) {
+ printf("gpxecmd: gPXE API not detected\n");
+ return 1;
+ }
+
+ gpxecmd(argv + 1);
+
+ return 0;
+}
diff --git a/core/localboot.inc b/core/localboot.inc
index 78483463..a66cf206 100644
--- a/core/localboot.inc
+++ b/core/localboot.inc
@@ -31,9 +31,7 @@ local_boot:
mov gs,dx
mov si,localboot_msg
call writestr
- push ax
call cleanup_hardware
- pop ax
cmp ax,-1
je .int18
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 93ef8b4a..e5aed7ca 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -122,6 +122,25 @@ MaxLMA equ 384*1024
;
bootsec equ $
_start:
+ jmp 0:_start1 ; Canonicalize the address and skip
+ ; the patch header
+
+;
+; Patch area for adding hardwired DHCP options
+;
+ align 4
+
+hcdhcp_magic dd 0x2983c8ac ; Magic number
+hcdhcp_len dd 7*4 ; Size of this structure
+hcdhcp_flags dd 0 ; Reserved for the future
+ ; Parameters to be parsed before the ones from PXE
+bdhcp_offset dd 0 ; Offset (entered by patcher)
+bdhcp_len dd 0 ; Length (entered by patcher)
+ ; Parameters to be parsed *after* the ones from PXE
+adhcp_offset dd 0 ; Offset (entered by patcher)
+adhcp_len dd 0 ; Length (entered by patcher)
+
+_start1:
pushfd ; Paranoia... in case of return to PXE
pushad ; ... save as much state as possible
push ds
@@ -134,8 +153,6 @@ _start:
mov ds,ax
mov es,ax
- jmp 0:_start1 ; Canonicalize address
-_start1:
; That is all pushed onto the PXE stack. Save the pointer
; to it and switch to an internal stack.
mov [InitStack],sp
@@ -150,6 +167,54 @@ _start1:
lss esp,[BaseStack]
sti ; Stack set up and ready
+;
+; Move the hardwired DHCP options (if present) to a safe place...
+;
+bdhcp_copy:
+ mov cx,[bdhcp_len]
+ mov ax,trackbufsize/2
+ jcxz .none
+ cmp cx,ax
+ jbe .oksize
+ mov cx,ax
+ mov [bdhcp_len],ax
+.oksize:
+ mov eax,[bdhcp_offset]
+ add eax,_start
+ mov si,ax
+ and si,000Fh
+ shr eax,4
+ push ds
+ mov ds,ax
+ mov di,trackbuf
+ add cx,3
+ shr cx,2
+ rep movsd
+ pop ds
+.none:
+
+adhcp_copy:
+ mov cx,[adhcp_len]
+ mov ax,trackbufsize/2
+ jcxz .none
+ cmp cx,ax
+ jbe .oksize
+ mov cx,ax
+ mov [adhcp_len],ax
+.oksize:
+ mov eax,[adhcp_offset]
+ add eax,_start
+ mov si,ax
+ and si,000Fh
+ shr eax,4
+ push ds
+ mov ds,ax
+ mov di,trackbuf+trackbufsize/2
+ add cx,3
+ shr cx,2
+ rep movsd
+ pop ds
+.none:
;
; Initialize screen (if we're using one)
diff --git a/core/runkernel.inc b/core/runkernel.inc
index 893c41c0..68ab9fac 100644
--- a/core/runkernel.inc
+++ b/core/runkernel.inc
@@ -461,8 +461,6 @@ run_linux_kernel:
; Set up segment registers and the Linux real-mode stack
; Note: ds == the real mode segment
;
- call cleanup_hardware
-
cli
mov ax,ds
mov ss,ax
diff --git a/core/serirq.inc b/core/serirq.inc
index a0cf9bf6..47ccd50f 100644
--- a/core/serirq.inc
+++ b/core/serirq.inc
@@ -91,6 +91,9 @@ SerialIRQPort resw 1 ; Serial port w IRQ service
SerialHead resw 1 ; Head of serial port rx buffer
SerialTail resw 1 ; Tail of serial port rx buffer
+ section .bss16
+IRQMask resw 1 ; PIC IRQ mask status
+
section .text16
sirq_install:
@@ -133,6 +136,22 @@ sirq_install:
mov al,1 ; Enable receive interrupt
slow_out dx,al
+ ;
+ ; Enable all ther interupt lines at the PIC. Some BIOSes
+ ; only enable the timer interrupts and other interrupts
+ ; actively in use by the BIOS.
+ ;
+ in al,0xA1 ; Secondary PIC mask register
+ mov ah,al
+ in al,0x21 ; Primary PIC mask register
+ mov [IRQMask],ax
+
+ io_delay
+
+ xor ax,ax ; Remove all interrupt masks
+ out 0x21,al
+ out 0xA1,al
+
popad
ret
@@ -156,6 +175,12 @@ sirq_cleanup_nowipe:
xor ax,ax
slow_out dx,al ; Clear IER
+ ; Restore PIC masks
+ mov ax,[IRQMask]
+ out 0x21,al
+ mov al,ah
+ out 0xA1,al
+
; Restore the original interrupt vectors
mov si,oldirq0
mov di,4*08h
@@ -165,6 +190,9 @@ sirq_cleanup_nowipe:
mov cx,8
rep movsd
+ xor ax,ax
+ mov [SerialIRQPort],ax ; No active interrupt system
+
.done:
pop es
pop ds
diff --git a/modules/Makefile b/modules/Makefile
index 80eb995d..77020ea0 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -19,7 +19,7 @@ include $(topdir)/MCONFIG.embedded
INCLUDES = -I$(com32)/include
-BINS = pxechain.com gfxboot.com poweroff.com
+BINS = pxechain.com gfxboot.com poweroff.com int18.com
all: $(BINS)
diff --git a/modules/int18.asm b/modules/int18.asm
new file mode 100644
index 00000000..a13ada75
--- /dev/null
+++ b/modules/int18.asm
@@ -0,0 +1,16 @@
+ bits 16
+ org 100h
+_start:
+ mov ax,5
+ int 22h
+ mov ah,09h
+ mov dx,msg
+ int 21h
+ mov ax,000Ch
+ xor dx,dx
+ int 22h
+ int 18h
+ jmp 0F000h:0FFF0h ; INT 18h should not return...
+
+ section .data
+msg: db 'Local boot via INT 18...', 13, 10, '$'
diff --git a/utils/Makefile b/utils/Makefile
index 9df9595a..39adf7d3 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -21,7 +21,8 @@ CFLAGS = -W -Wall -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
LDFLAGS = -O2 -s
TARGETS = mkdiskimage isohybrid gethostip
-ASIS = keytab-lilo lss16toppm md5pass ppmtolss16 sha1pass syslinux2ansi
+ASIS = keytab-lilo lss16toppm md5pass ppmtolss16 sha1pass syslinux2ansi \
+ pxelinux-options
ISOHDPFX = ../mbr/isohdpfx.bin ../mbr/isohdpfx_f.bin ../mbr/isohdpfx_c.bin \
../mbr/isohdppx.bin ../mbr/isohdppx_f.bin ../mbr/isohdppx_c.bin
diff --git a/utils/pxelinux-options b/utils/pxelinux-options
new file mode 100755
index 00000000..ab7075b5
--- /dev/null
+++ b/utils/pxelinux-options
@@ -0,0 +1,499 @@
+#!/usr/bin/perl
+#
+# Set PXELINUX hard-coded options
+#
+
+use Socket; # For gethostbyname
+use Fcntl;
+use bytes;
+
+%option_names = (
+ 6 => 'domain-name-servers',
+ 15 => 'domain-name',
+ 54 => 'next-server',
+ 209 => 'config-file',
+ 210 => 'path-prefix',
+ 211 => 'reboottime'
+ );
+
+@fmt_oneip = ("ip-address", \&parse_oneip, \&show_ip);
+@fmt_multiip = ("ip-address-list", \&parse_multiip, \&show_ip);
+@fmt_string = ("string", \&parse_string, \&show_string);
+@fmt_uint32 = ("uint32", \&parse_uint32, \&show_uint32);
+
+%option_format = (
+ 6 => \@fmt_multiip,
+ 15 => \@fmt_string,
+ 54 => \@fmt_oneip,
+ 67 => \@fmt_string,
+ 209 => \@fmt_string,
+ 210 => \@fmt_string,
+ 211 => \@fmt_uint32
+ );
+
+sub parse_oneip($)
+{
+ my($s) = @_;
+ my($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($s);
+
+ return ($addrtype == AF_INET) ? $addrs[0] : undef;
+}
+
+sub parse_multiip($)
+{
+ my($l) = @_;
+ my $s;
+ my @a = ();
+ my $addr;
+ my $d = '';
+
+ foreach $s (split(/,/, $l)) {
+ my($name,$aliases,$addrtype,$length,@addrs)
+ = gethostbyname($s);
+ if ($addrtype == AF_INET) {
+ foreach $addr (@addrs) {
+ $d .= $addr;
+ }
+ }
+ }
+
+ return $d ne '' ? $d : undef;
+}
+
+sub show_ip($)
+{
+ my($l) = @_;
+
+ if (length($l) & 3) {
+ return undef;
+ } else {
+ my @h = ();
+ my $i;
+
+ for ($i = 0; $i < length($l); $i += 4) {
+ push(@h, inet_ntoa(substr($l, $i, 4)));
+ }
+
+ return join(',', @h);
+ }
+}
+
+sub parse_string($)
+{
+ return $_[0];
+}
+
+sub show_string($)
+{
+ my($s) = @_;
+ my $o, $i, $c;
+
+ $o = "\'";
+ for ($i = 0; $i < length($s); $i++) {
+ $c = substr($s, $i, 1);
+ if ($c eq "\'" || $c eq '!') {
+ $o .= "\'\\$c\'";
+ } else {
+ $o .= $c;
+ }
+ }
+ $o .= "\'";
+
+ return $o;
+}
+
+sub parse_uint32($)
+{
+ my($s) = @_;
+
+ if ($s =~ /^[0-9]+$/) {
+ return pack("N", $s);
+ } else {
+ return undef;
+ }
+}
+
+sub show_uint32($)
+{
+ my($l) = @_;
+
+ if (length($l) == 4) {
+ return unpack("N", $l);
+ } else {
+ return undef;
+ }
+}
+
+sub parse_generic($)
+{
+ my($s) = @_;
+
+ if ($s =~ /^[0-9a-f]{1,2}(:[0-9a-f]{1,2})*$/) {
+ my $h;
+ my @b = ();
+
+ foreach $h (split(/\:/, $s)) {
+ push(@b, hex $h);
+ }
+
+ return pack("C", @b);
+ } else {
+ return undef;
+ }
+}
+
+sub show_generic($)
+{
+ my($l) = @_;
+ my $i;
+ my @h;
+
+ for ($i = 0; $i < length($l); $i++) {
+ push(@h, sprintf("%02x", unpack("C", substr($l, $i, $1))));
+ }
+
+ return join(':', @h);
+}
+
+sub parse_option($$)
+{
+ my($opt, $arg) = @_;
+ my $v;
+
+ if (defined($option_format{$opt})) {
+ $v = $option_format{$opt}[1]($arg);
+ return $v if (defined($v));
+ }
+
+ return parse_generic($arg);
+}
+
+sub show_option($$)
+{
+ my($opt, $arg) = @_;
+ my $v;
+
+ if (defined($option_format{$opt})) {
+ $v = $option_format{$opt}[2]($arg);
+ return $v if (defined($v));
+ }
+
+ return show_generic($arg);
+}
+
+sub option_number($)
+{
+ my($n) = @_;
+
+ if (defined($option_rnames{$n})) {
+ return $option_rnames{$n};
+ } elsif ($n =~ /^[0-9]+$/ && $n >= 1 && $n <= 254) {
+ return $n+0;
+ } else {
+ return undef;
+ }
+}
+
+sub read_optsets($)
+{
+ my($file) = @_;
+ my $data, $bdata, $adata;
+ my $patch_start = (stat($file))[7];
+
+ return undef unless (seek($file, 8, SEEK_SET));
+ return undef unless (read($file, $data, 7*4) == 7*4);
+
+ my($magic, $len, $flags, $boff, $blen, $aoff, $alen)
+ = unpack("VVVVVVV", $data);
+ return undef if ($magic != 0x2983c8ac);
+ return undef if ($len < 7*4);
+
+ if ($blen == 0) {
+ $bdata = '';
+ } else {
+ return undef unless (seek($file, $boff, SEEK_SET));
+ return undef unless (read($file, $bdata, $blen) == $blen);
+ $patch_start = $boff if ($boff < $patch_start);
+ }
+
+ if ($alen == 0) {
+ $adata = '';
+ } else {
+ return undef unless (seek($file, $aoff, SEEK_SET));
+ return undef unless (read($file, $adata, $alen) == $alen);
+ $patch_start = $aoff if ($aoff < $patch_start);
+ }
+
+ return ($patch_start, $bdata, $adata);
+}
+
+sub write_optsets($$@)
+{
+ my($file, $patch_start, $bdata, $adata) = @_;
+ my $boff = 0;
+ my $aoff = 0;
+
+ if (length($bdata) > 0) {
+ $bdata .= "\xff";
+ $boff = $patch_start;
+ return undef unless (seek($file, $boff, SEEK_SET));
+ return undef unless (print $file $bdata);
+ $patch_start += length($bdata);
+ }
+
+ if (length($adata) > 0) {
+ $adata .= "\xff";
+ $aoff = $patch_start;
+ return undef unless (seek($file, $aoff, SEEK_SET));
+ return undef unless (print $file $adata);
+ $patch_start += length($adata);
+ }
+
+ my $hdr = pack("VVVV", $boff, length($bdata), $aoff, length($adata));
+
+ return undef unless (seek($file, 8+3*4, SEEK_SET));
+ return undef unless (print $file $hdr);
+
+ truncate($file, $patch_start);
+ return 1;
+}
+
+sub delete_option($$)
+{
+ my ($num, $block) = @_;
+ my $o, $l, $c, $x;
+
+ $x = 0;
+ while ($x < length($block)) {
+ ($o, $l) = unpack("CC", substr($block, $x, 2));
+ if ($o == $num) {
+ # Delete this option
+ substr($block, $x, $l+2) = '';
+ } elsif ($o == 0) {
+ # Delete a null option
+ substr($block, $x, 1) = '';
+ } elsif ($o == 255) {
+ # End marker - truncate block
+ $block = substr($block, 0, $x);
+ last;
+ } else {
+ # Skip to the next option
+ $x += $l+2;
+ }
+ }
+
+ return $block;
+}
+
+sub add_option($$$)
+{
+ my ($num, $data, $block) = @_;
+
+ $block = delete_option($num, $block);
+
+ if (length($data) == 0) {
+ return $block;
+ } elsif (length($data) > 255) {
+ die "$0: option $num has too much data (max 255 bytes)\n";
+ } else {
+ return $block . pack("CC", $num, length($data)) . $data;
+ }
+}
+
+sub list_options($$)
+{
+ my($pfx, $data) = @_;
+ my $x, $o, $l;
+
+ while ($x < length($data)) {
+ ($o, $l) = unpack("CC", substr($data, $x, 2));
+
+ if ($o == 0) {
+ $x++;
+ } elsif ($o == 255) {
+ last;
+ } else {
+ my $odata = substr($data, $x+2, $l);
+ last if (length($odata) != $l); # Incomplete option
+
+ printf "%s%-20s %s\n", $pfx,
+ $option_names{$o} || sprintf("%d", $o),
+ show_option($o, $odata);
+
+ $x += $l+2;
+ }
+ }
+}
+
+sub usage()
+{
+ my $i;
+
+ print STDERR "Usage: $0 options pxelinux.0\n";
+ print STDERR "Options:\n";
+ print STDERR "--before option value -b Add an option before DHCP data\n";
+ print STDERR "--after option value -a Add an option after DHCP data\n";
+ print STDERR "--delete option -d Delete an option\n";
+ print STDERR "--list -l List set options\n";
+ print STDERR "--dry-run -n Don't modify the target file\n";
+ print STDERR "--help -h Display this help text\n";
+ print STDERR "\n";
+ print STDERR "The following DHCP options are currently recognized:\n";
+ printf STDERR "%-23s %-3s %s\n", 'Name', 'Num', 'Value Format';
+
+ foreach $i (sort { $a <=> $b } keys(%option_names)) {
+ printf STDERR "%-23s %3d %s\n",
+ $option_names{$i}, $i, $option_format{$i}[0];
+ }
+}
+
+%option_rnames = ();
+foreach $opt (keys(%option_names)) {
+ $option_rnames{$option_names{$opt}} = $opt;
+}
+
+%before = ();
+%after = ();
+@clear = ();
+$usage = 0;
+$err = 0;
+$list = 0;
+$no_write = 0;
+undef $file;
+
+while (defined($opt = shift(@ARGV))) {
+ if ($opt !~ /^-/) {
+ if (defined($file)) {
+ $err = $usage = 1;
+ last;
+ }
+ $file = $opt;
+ } elsif ($opt eq '-b' || $opt eq '--before') {
+ $oname = shift(@ARGV);
+ $odata = shift(@ARGV);
+
+ if (!defined($odata)) {
+ $err = $usage = 1;
+ last;
+ }
+
+ $onum = option_number($oname);
+ if (!defined($onum)) {
+ print STDERR "$0: unknown option name: $oname\n";
+ $err = 1;
+ next;
+ }
+
+ $odata = parse_option($onum, $odata);
+ if (!defined($odata)) {
+ print STDERR "$0: unable to parse data for option $oname\n";
+ $err = 1;
+ next;
+ }
+
+ delete $after{$onum};
+ $before{$onum} = $odata;
+ push(@clear, $onum);
+ } elsif ($opt eq '-a' || $opt eq '--after') {
+ $oname = shift(@ARGV);
+ $odata = shift(@ARGV);
+
+ if (!defined($odata)) {
+ $err = $usage = 1;
+ last;
+ }
+
+ $onum = option_number($oname);
+ if (!defined($onum)) {
+ print STDERR "$0: unknown option name: $oname\n";
+ $err = 1;
+ next;
+ }
+
+ $odata = parse_option($onum, $odata);
+ if (!defined($odata)) {
+ print STDERR "$0: unable to parse data for option $oname\n";
+ $err = 1;
+ next;
+ }
+
+ delete $before{$onum};
+ $after{$onum} = $odata;
+ push(@clear, $onum);
+ } elsif ($opt eq '-d' || $opt eq '--delete') {
+ $oname = shift(@ARGV);
+
+ if (!defined($oname)) {
+ $err = $usage = 1;
+ last;
+ }
+
+ $onum = option_number($oname);
+ if (!defined($onum)) {
+ print STDERR "$0: unknown option name: $oname\n";
+ $err = 1;
+ next;
+ }
+
+ push(@clear, $onum);
+ delete $before{$onum};
+ delete $after{$onum};
+ } elsif ($opt eq '-n' || $opt eq '--no-write' || $opt eq '--dry-run') {
+ $no_write = 1;
+ } elsif ($opt eq '-l' || $opt eq '--list') {
+ $list = 1;
+ } elsif ($opt eq '-h' || $opt eq '--help') {
+ $usage = 1;
+ } else {
+ print STDERR "Invalid option: $opt\n";
+ $err = $usage = 1;
+ }
+}
+
+if (!defined($file) && !$usage) {
+ $err = $usage = 1;
+}
+if ($usage) {
+ usage();
+}
+if ($err || $usage) {
+ exit($err);
+}
+
+if (!scalar(@clear)) {
+ $no_write = 1; # No modifications requested
+}
+
+$mode = $no_write ? '<' : '+<';
+
+open(FILE, $mode, $file)
+ or die "$0: cannot open: $file: $!\n";
+($patch_start, @data) = read_optsets(\*FILE);
+if (!defined($patch_start)) {
+ die "$0: $file: patch block not found or file corrupt\n";
+}
+
+foreach $o (@clear) {
+ $data[0] = delete_option($o, $data[0]);
+ $data[1] = delete_option($o, $data[1]);
+}
+foreach $o (keys(%before)) {
+ $data[0] = add_option($o, $before{$o}, $data[0]);
+}
+foreach $o (keys(%after)) {
+ $data[1] = add_option($o, $after{$o}, $data[1]);
+}
+
+if ($list) {
+ list_options('-b ', $data[0]);
+ list_options('-a ', $data[1]);
+}
+
+if (!$no_write) {
+ if (!write_optsets(\*FILE, $patch_start, @data)) {
+ die "$0: $file: failed to write options: $!\n";
+ }
+}
+
+close(FILE);
+exit 0;