aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--com32/include/unistd.h4
-rw-r--r--com32/rosh/rosh.c658
-rw-r--r--com32/rosh/rosh.h18
-rw-r--r--core/pxelinux.asm21
-rw-r--r--core/writedec.inc5
-rw-r--r--modules/Makefile2
-rw-r--r--modules/ver.asm606
7 files changed, 1057 insertions, 257 deletions
diff --git a/com32/include/unistd.h b/com32/include/unistd.h
index fc514f10..9e13381a 100644
--- a/com32/include/unistd.h
+++ b/com32/include/unistd.h
@@ -28,6 +28,10 @@ __extern int chdir(const char *);
__extern unsigned int sleep(unsigned int);
__extern unsigned int msleep(unsigned int);
+__extern int getopt(int, char *const *, const char *);
+__extern char *optarg;
+__extern int optind, opterr, optopt;
+
/* Standard file descriptor numbers. */
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
diff --git a/com32/rosh/rosh.c b/com32/rosh/rosh.c
index 9efa35ef..12e09995 100644
--- a/com32/rosh/rosh.c
+++ b/com32/rosh/rosh.c
@@ -20,7 +20,12 @@
/*
* ToDos:
- * rosh_ls(): sorted; then multiple columns
+ * prompt: Allow left/right arrow, home/end and more?
+ * commands Break into argv/argc-like array
+ * rosh_cfg: allow -s <file> to change config
+ * rosh_ls(): sorted; then multiple columns
+ * prompt: Possibly honor timeout on initial entry for usage as UI
+ * Also possibly honor totaltimeout
*/
/*#define DO_DEBUG 1
@@ -38,8 +43,10 @@
#define APP_NAME "rosh"
#define APP_AUTHOR "Gene Cumm"
#define APP_YEAR "2010"
-#define APP_VER "beta-b068"
+#define APP_VER "beta-b089"
+/* Print version information to stdout
+ */
void rosh_version(int vtype)
{
char env[256];
@@ -52,6 +59,8 @@ void rosh_version(int vtype)
}
}
+/* Print beta message and if DO_DEBUG/DO_DEBUG2 are active
+ */
void print_beta(void)
{
puts(rosh_beta_str);
@@ -119,32 +128,156 @@ int rosh_parse_sp_1(char *dest, const char *src, const int ipos)
return epos;
}
+/*
+ * parse_args1: Try 1 at parsing a string to an argc/argv pair. use free_args1 to free memory malloc'd
+ *
+ * Derived from com32/lib/sys/argv.c:__parse_argv()
+ * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ */
+int parse_args1(char ***iargv, const char *istr)
+{
+ int argc = 0;
+ const char *p;
+ char *q, *r, *args, **arg;
+ int sp = 1; //, qt = 0; /* Was a space; inside a quote */
+
+ /* Scan 1: Length */
+ /* I could eliminate this if I knew a max length, like strncpy() */
+ int len = strlen(istr);
+
+ /* Scan 2: Copy, nullify and make argc */
+ if (!(args = malloc(len + 1)))
+ goto fail_args;
+ q = args;
+ for (p = istr;; p++) {
+ if (*p <= ' ') {
+ if (!sp) {
+ sp = 1;
+ *q++ = '\0';
+ }
+ } else {
+ if (sp) {
+ argc++;
+ sp = 0;
+ }
+ *q++ = *p;
+ }
+ if (!*p)
+ break;
+ }
+
+ q--; /* Point q to final null */
+ /* Scan 3: Build array of pointers */
+ if (!(*iargv = malloc((argc + 1) * sizeof(char *))))
+ goto fail_args_ptr;
+ arg = *iargv;
+ arg[argc] = NULL; /* Nullify the last pointer */
+ if (*args != '\0')
+ *arg++ = args;
+ for (r = args; r < q ; r++) {
+ if (*r == '\0') {
+ *arg++ = r + 1;
+ }
+ }
+
+fail_args:
+ return argc;
+fail_args_ptr:
+ free(args);
+ return 0;
+}
+
+/* Free argv created by parse_args1()
+ * argv Argument Values
+ */
+void free_args1(char ***argv)
+{
+ char *s;
+ s = **argv;
+ free(*argv);
+ free(s);
+}
+
+/* Convert a string to an argc/argv pair
+ * str String to parse
+ * argv Argument Values
+ * returns Argument Count
+ */
+int rosh_str2argv(char ***argv, const char *str)
+{
+ return parse_args1(argv, str);
+}
+
+/* Free an argv created by rosh_str2argv()
+ * argv Argument Values to free
+ */
+void rosh_free_argv(char ***argv)
+{
+ free_args1(argv);
+}
+
+/* Print the contents of an argc/argv pair
+ * argc Argument Count
+ * argv Argument Values
+ */
+void rosh_pr_argv(int argc, char *argv[])
+{
+ int i;
+ for (i = 0; i < argc; i++) {
+ printf("%s%s", argv[i], (i < argc)? " " : "");
+ }
+ puts("");
+}
+
+/* Print the contents of an argc/argv pair verbosely
+ * argc Argument Count
+ * argv Argument Values
+ */
+void rosh_pr_argv_v(int argc, char *argv[])
+{
+ int i;
+ for (i = 0; i < argc; i++) {
+ printf("%4d '%s'\n", i, argv[i]);
+ }
+}
+
+/* Reset the getopt() environment
+ */
+void rosh_getopt_reset(void)
+{
+ optind = 0;
+ optopt = 0;
+}
+
/* Display help
* type Help type
- * cmdstr Command string
+ * cmdstr Command for which help is requested
*/
void rosh_help(int type, const char *cmdstr)
{
- const char *istr;
- istr = cmdstr;
switch (type) {
case 2:
- istr += rosh_search_nonsp(cmdstr, rosh_search_sp(cmdstr, 0));
- if ((cmdstr == NULL) || (strcmp(istr, "") == 0)) {
+ if ((cmdstr == NULL) || (strcmp(cmdstr, "") == 0)) {
rosh_version(0);
puts(rosh_help_str2);
} else {
- switch (istr[0]) {
+ switch (cmdstr[0]) {
+ case 'c':
+ puts(rosh_help_cd_str);
+ break;
case 'l':
puts(rosh_help_ls_str);
break;
default:
- printf(rosh_help_str_adv, istr);
+ printf(rosh_help_str_adv, cmdstr);
}
}
break;
case 1:
default:
+ if (cmdstr)
+ printf("%s: %s: unknown command\n", APP_NAME, cmdstr);
rosh_version(0);
puts(rosh_help_str1);
}
@@ -194,11 +327,13 @@ void rosh_error(const int ierrno, const char *cmdstr, const char *filestr)
/* Concatenate command line arguments into one string
* cmdstr Output command string
+ * cmdlen Length of cmdstr
* argc Argument Count
* argv Argument Values
* barg Beginning Argument
*/
-int rosh_argcat(char *cmdstr, const int argc, char *argv[], const int barg)
+int rosh_argcat(char *cmdstr, const int cmdlen, const int argc, char *argv[],
+ const int barg)
{
int i, arglen, curpos; /* index, argument length, current position
in cmdstr */
@@ -207,15 +342,15 @@ int rosh_argcat(char *cmdstr, const int argc, char *argv[], const int barg)
for (i = barg; i < argc; i++) {
arglen = strlen(argv[i]);
/* Theoretically, this should never be met in SYSLINUX */
- if ((curpos + arglen) > (ROSH_CMD_SZ - 1))
- arglen = (ROSH_CMD_SZ - 1) - curpos;
+ if ((curpos + arglen) > (cmdlen - 1))
+ arglen = (cmdlen - 1) - curpos;
memcpy(cmdstr + curpos, argv[i], arglen);
curpos += arglen;
- if (curpos >= (ROSH_CMD_SZ - 1)) {
+ if (curpos >= (cmdlen - 1)) {
/* Hopefully, curpos should not be greater than
- (ROSH_CMD_SZ - 1) */
+ (cmdlen - 1) */
/* Still need a '\0' at the last character */
- cmdstr[(ROSH_CMD_SZ - 1)] = 0;
+ cmdstr[(cmdlen - 1)] = 0;
break; /* Escape out of the for() loop;
We can no longer process anything more */
} else {
@@ -285,26 +420,19 @@ void rosh_qualify_filestr(char *filestr, const char *ifilstr,
}
/* Concatenate multiple files to stdout
- * cmdstr command string to process
+ * argc Argument Count
+ * argv Argument Values
*/
-void rosh_cat(const char *cmdstr)
+void rosh_cat(int argc, char *argv[])
{
FILE *f;
- char filestr[ROSH_PATH_SZ];
char buf[ROSH_BUF_SZ];
- int numrd;
- int cmdpos;
+ int i, numrd;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
- /* Initialization */
- filestr[0] = 0;
- cmdpos = 0;
- /* skip the first word */
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- while (strlen(filestr) > 0) {
- printf("--File = '%s'\n", filestr);
- f = fopen(filestr, "r");
+ for (i = 0; i < argc; i++) {
+ printf("--File = '%s'\n", argv[i]);
+ errno = 0;
+ f = fopen(argv[i], "r");
if (f != NULL) {
numrd = fread(buf, 1, ROSH_BUF_SZ, f);
while (numrd > 0) {
@@ -313,36 +441,37 @@ void rosh_cat(const char *cmdstr)
}
fclose(f);
} else {
- rosh_error(errno, "cat", filestr);
+ rosh_error(errno, "cat", argv[i]);
errno = 0;
}
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
}
} /* rosh_cat */
/* Change PWD (Present Working Directory)
- * cmdstr command string to process
+ * argc Argument count
+ * argv Argument values
* ipwdstr Initial PWD
*/
-void rosh_cd(const char *cmdstr, const char *ipwdstr)
+void rosh_cd(int argc, char *argv[], const char *ipwdstr)
{
- int rv;
+ int rv = 0;
+#ifdef DO_DEBUG
char filestr[ROSH_PATH_SZ];
- int cmdpos;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
- /* Initialization */
- filestr[0] = 0;
- cmdpos = 0;
- rv = 0;
- /* skip the first word */
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- if (strlen(filestr) != 0)
- rv = chdir(filestr);
- else
+#endif /* DO_DEBUG */
+ ROSH_DEBUG("CMD: \n");
+ ROSH_DEBUG_ARGV_V(argc, argv);
+ errno = 0;
+ if (argc == 2)
+ rv = chdir(argv[1]);
+ else if (argc == 1)
rv = chdir(ipwdstr);
+ else
+ rosh_help(2, argv[0]);
if (rv != 0) {
- rosh_error(errno, "cd", filestr);
+ if (argc == 2)
+ rosh_error(errno, "cd", argv[1]);
+ else
+ rosh_error(errno, "cd", ipwdstr);
errno = 0;
} else {
#ifdef DO_DEBUG
@@ -359,31 +488,61 @@ void rosh_cfg(void)
printf("CFG: '%s'\n", syslinux_config_file());
} /* rosh_cfg */
-/* Process optstr to optarr
- * optstr option string to process
- * optarr option array to populate
+/* Echo a string back to the screen
+ * cmdstr command string to process
*/
-void rosh_ls_arg_opt(const char *optstr, int *optarr)
+void rosh_echo(const char *cmdstr)
{
- char *cpos;
- cpos = strchr(optstr, 'l');
- if (cpos) {
- optarr[0] = cpos - optstr;
- } else {
- optarr[0] = -1;
- }
- cpos = strchr(optstr, 'F');
- if (cpos) {
- optarr[1] = cpos - optstr;
+ int bpos = 0;
+ ROSH_DEBUG("CMD: '%s'\n", cmdstr);
+ bpos = rosh_search_nonsp(cmdstr, rosh_search_sp(cmdstr, 0));
+ if (bpos > 1) {
+ ROSH_DEBUG(" bpos=%d\n", bpos);
+ printf("'%s'\n", cmdstr + bpos);
} else {
- optarr[1] = -1;
+ puts("");
}
- cpos = strchr(optstr, 'i');
- if (cpos) {
- optarr[2] = cpos - optstr;
- } else {
- optarr[2] = -1;
+} /* rosh_echo */
+
+/* Process argc/argv to optarr
+ * argc Argument count
+ * argv Argument values
+ * optarr option array to populate
+ */
+void rosh_ls_arg_opt(int argc, char *argv[], int optarr[])
+{
+ int rv = 0;
+
+ optarr[0] = -1;
+ optarr[1] = -1;
+ optarr[2] = -1;
+ rosh_getopt_reset();
+ while (rv != -1) {
+ ROSH_DEBUG2("getopt optind=%d rv=%d\n", optind, rv);
+ rv = getopt(argc, argv, rosh_ls_opt_str);
+ switch (rv) {
+ case 'l':
+ case 0:
+ optarr[0] = 1;
+ break;
+ case 'F':
+ case 1:
+ optarr[1] = 1;
+ break;
+ case 'i':
+ case 2:
+ optarr[2] = 1;
+ break;
+ case '?':
+ case -1:
+ default:
+ ROSH_DEBUG2("getopt optind=%d rv=%d\n", optind, rv);
+ break;
+ }
}
+ ROSH_DEBUG2(" end getopt optind=%d rv=%d\n", optind, rv);
+ ROSH_DEBUG2("\tIn rosh_ls_arg_opt() opt[0]=%d\topt[1]=%d\topt[2]=%d\n", optarr[0], optarr[1],
+ optarr[2]);
} /* rosh_ls_arg_opt */
/* Retrieve the size of a file argument
@@ -435,6 +594,7 @@ int rosh_ls_de_size_mode(struct dirent *de, mode_t * st_mode)
filestr2[file2pos] = '/';
}
strcpy(filestr2 + file2pos + 1, de->d_name);*/
+ errno = 0;
status = stat(de->d_name, &fdstat);
ROSH_DEBUG2("\t--stat()=%d\terr=%d\n", status, errno);
if (errno) {
@@ -628,14 +788,17 @@ void rosh_ls_arg_dir(const char *filestr, DIR * d, const int *optarr)
int filepos;
filepos = 0;
+ errno = 0;
while ((de = readdir(d))) {
filepos++;
rosh_ls_arg_dir_de(de, optarr);
}
- if (errno)
+ if (errno) {
rosh_error(errno, "ls:arg_dir", filestr);
- else if (filepos == 0)
+ errno = 0;
+ } else { if (filepos == 0)
ROSH_DEBUG("0 files found");
+ }
} /* rosh_ls_arg_dir */
/* Simple directory listing for one argument (file/directory) based on
@@ -667,9 +830,13 @@ void rosh_ls_arg(const char *filestr, const int *optarr)
if (status == 0) {
if (S_ISDIR(fdstat.st_mode)) {
ROSH_DEBUG("PATH '%s' is a directory\n", filestr);
- d = opendir(filestr);
- rosh_ls_arg_dir(filestr, d, optarr);
- closedir(d);
+ if ((d = opendir(filestr))) {
+ rosh_ls_arg_dir(filestr, d, optarr);
+ closedir(d);
+ } else {
+ rosh_error(errno, "ls", filestr);
+ errno = 0;
+ }
} else {
de.d_ino = rosh_ls_d_ino(&fdstat);
de.d_type = (IFTODT(fdstat.st_mode));
@@ -712,71 +879,37 @@ int rosh_ls_parse_opt(const char *filestr, char *optstr)
return ret;
} /* rosh_ls_parse_opt */
-/* List Directory based on cmdstr and pwdstr
- * cmdstr command string to process
- * pwdstr Present Working Directory string
+/* List Directory
+ * argc Argument count
+ * argv Argument values
*/
-void rosh_ls(const char *cmdstr)
+void rosh_ls(int argc, char *argv[])
{
- char filestr[ROSH_PATH_SZ];
- char optstr[ROSH_OPT_SZ]; /* Options string */
- int cmdpos, tpos; /* Position within cmdstr, temp position */
- int numargs; /* number of non-option arguments */
- int argpos; /* number of non-option arguments processed */
int optarr[3];
+ int i;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
- /* Initialization */
- filestr[0] = 0;
- optstr[0] = 0;
- cmdpos = 0;
- numargs = 0;
- argpos = 0;
- /* skip the first word */
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- tpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- /* If there are no real arguments, substitute PWD */
- if (strlen(filestr) == 0) {
- strcpy(filestr, ".");
- cmdpos = tpos;
- } else { /* Parse for command line options */
- while (strlen(filestr) > 0) {
- numargs += rosh_ls_parse_opt(filestr, optstr);
- tpos = rosh_parse_sp_1(filestr, cmdstr, tpos);
- }
- if (numargs == 0) {
- strcpy(filestr, ".");
- cmdpos = tpos;
- } else {
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- }
- }
+ rosh_ls_arg_opt(argc, argv, optarr);
+ ROSH_DEBUG2("In ls()\n");
+ ROSH_DEBUG2_ARGV_V(argc, argv);
#ifdef DO_DEBUG
- if (!strchr(optstr, 'l'))
- strcat(optstr, "l");
+ optarr[0] = 2;
#endif /* DO_DEBUG */
- rosh_ls_arg_opt(optstr, optarr);
- ROSH_DEBUG("\tfopt: '%s'\n", optstr);
- while (strlen(filestr) > 0) {
- if (rosh_ls_parse_opt(filestr, NULL)) {
- rosh_ls_arg(filestr, optarr);
- argpos++;
- }
- if (argpos < numargs)
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- else
- break;
+ ROSH_DEBUG2(" argc=%d; optind=%d\n", argc, optind);
+ if (optind >= argc)
+ rosh_ls_arg(".", optarr);
+ for (i = optind; i < argc; i++) {
+ rosh_ls_arg(argv[i], optarr);
}
} /* rosh_ls */
/* Simple directory listing; calls rosh_ls()
- * cmdstr command string to process
- * pwdstr Present Working Directory string
+ * argc Argument count
+ * argv Argument values
*/
-void rosh_dir(const char *cmdstr)
+void rosh_dir(int argc, char *argv[])
{
ROSH_DEBUG(" dir implemented as ls\n");
- rosh_ls(cmdstr);
+ rosh_ls(argc, argv);
} /* rosh_dir */
/* Page through a buffer string
@@ -874,22 +1007,19 @@ void rosh_more_fd(int fd, int rows, int cols, char *scrbuf)
} /* rosh_more_fd */
/* Page through a file like the more command
- * cmdstr command string to process
- * ipwdstr Initial PWD
+ * argc Argument Count
+ * argv Argument Values
*/
-void rosh_more(const char *cmdstr)
+void rosh_more(int argc, char *argv[])
{
- int fd;
- char filestr[ROSH_PATH_SZ];
- int cmdpos;
+ int fd, i;
+/* char filestr[ROSH_PATH_SZ];
+ int cmdpos;*/
int rows, cols;
char *scrbuf;
int ret;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
- /* Initialization */
- filestr[0] = 0;
- cmdpos = 0;
+ ROSH_DEBUG_ARGV_V(argc, argv);
ret = getscreensize(1, &rows, &cols);
if (ret) {
ROSH_DEBUG("getscreensize() fail(%d); fall back\n", ret);
@@ -906,24 +1036,21 @@ void rosh_more(const char *cmdstr)
if (!scrbuf)
return;
- /* skip the first word */
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- if (strlen(filestr) > 0) {
+ if (argc) {
/* There is no need to mess up the console if we don't have a
file */
rosh_console_raw();
- while (strlen(filestr) > 0) {
- printf("--File = '%s'\n", filestr);
- fd = open(filestr, O_RDONLY);
+ for (i = 0; i < argc; i++) {
+ printf("--File = '%s'\n", argv[i]);
+ errno = 0;
+ fd = open(argv[i], O_RDONLY);
if (fd != -1) {
rosh_more_fd(fd, rows, cols, scrbuf);
close(fd);
} else {
- rosh_error(errno, "more", filestr);
+ rosh_error(errno, "more", argv[i]);
errno = 0;
}
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
}
rosh_console_std();
}
@@ -931,26 +1058,20 @@ void rosh_more(const char *cmdstr)
} /* rosh_more */
/* Page a file with rewind
- * cmdstr command string to process
- * pwdstr Present Working Directory string
- * ipwdstr Initial PWD
+ * argc Argument Count
+ * argv Argument Values
*/
-void rosh_less(const char *cmdstr)
+void rosh_less(int argc, char *argv[])
{
printf(" less implemented as more (for now)\n");
- rosh_more(cmdstr);
+ rosh_more(argc, argv);
} /* rosh_less */
/* Show PWD
- * cmdstr command string to process
*/
-void rosh_pwd(const char *cmdstr)
+void rosh_pwd(void)
{
- int istr;
char pwdstr[ROSH_PATH_SZ];
- if (cmdstr)
- istr = 0;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
errno = 0;
if (getcwd(pwdstr, ROSH_PATH_SZ)) {
printf("%s\n", pwdstr);
@@ -958,190 +1079,223 @@ void rosh_pwd(const char *cmdstr)
rosh_error(errno, "pwd", "");
errno = 0;
}
- istr = htonl(*(int *)pwdstr);
- ROSH_DEBUG2(" --%08X\n", istr);
} /* rosh_pwd */
-/* Reboot
+/* Reboot; use warm reboot if one of certain options set
+ * argc Argument count
+ * argv Argument values
*/
-void rosh_reboot(void)
+void rosh_reboot(int argc, char *argv[])
{
-// char cmdstr[ROSH_CMD_SZ];
-// printf
- syslinux_reboot(0);
+ int rtype = 0;
+ if (argc) {
+ /* For now, just use the first */
+ switch (argv[0][0]) {
+ case '1':
+ case 's':
+ case 'w':
+ rtype = 1;
+ break;
+ case '-':
+ switch (argv[0][1]) {
+ case '1':
+ case 's':
+ case 'w':
+ rtype = 1;
+ break;
+ }
+ break;
+ }
+ }
+ syslinux_reboot(rtype);
} /* rosh_reboot */
/* Run a boot string, calling syslinux_run_command
- * cmdstr command string to process
+ * argc Argument count
+ * argv Argument values
*/
-void rosh_run(const char *cmdstr)
+void rosh_run(int argc, char *argv[])
{
- int cmdpos;
- char *cmdptr;
+ char cmdstr[ROSH_CMD_SZ];
+ int len;
- cmdpos = 0;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
- /* skip the first word */
- cmdpos = rosh_search_sp(cmdstr, cmdpos);
- /* skip spaces */
- cmdpos = rosh_search_nonsp(cmdstr, cmdpos);
- cmdptr = (char *)(cmdstr + cmdpos);
- printf("--run: '%s'\n", cmdptr);
- syslinux_run_command(cmdptr);
+ len = rosh_argcat(cmdstr, ROSH_CMD_SZ, argc, argv, 0);
+ if (len) {
+ printf("--run: '%s'\n", cmdstr);
+ syslinux_run_command(cmdstr);
+ } else {
+ printf(APP_NAME ":run: No arguments\n");
+ }
} /* rosh_run */
-/* Process a single command string and call handling function
- * cmdstr command string to process
+/* Process an argc/argv pair and call handling function
+ * argc Argument count
+ * argv Argument values
* ipwdstr Initial Present Working Directory string
* returns Whether to exit prompt
*/
-char rosh_command(const char *cmdstr, const char *ipwdstr)
+char rosh_command(int argc, char *argv[], const char *ipwdstr)
{
- char do_exit;
- char tstr[ROSH_CMD_SZ];
+ char do_exit = false;
int tlen;
- do_exit = false;
- ROSH_DEBUG("--cmd:'%s'\n", cmdstr);
- tlen = rosh_parse_sp_1(tstr, cmdstr, 0);
- switch (cmdstr[0]) {
+ tlen = strlen(argv[0]);
+ ROSH_DEBUG_ARGV_V(argc, argv);
+ switch (argv[0][0]) {
case 'e':
case 'E':
case 'q':
case 'Q':
- if ((strncasecmp("exit", tstr, tlen) == 0) ||
- (strncasecmp("quit", tstr, tlen) == 0))
- do_exit = true;
- else
- rosh_help(1, NULL);
+ switch (argv[0][1]) {
+ case 0:
+ case 'x':
+ case 'X':
+ case 'u':
+ case 'U':
+ if ((strncasecmp("exit", argv[0], tlen) == 0) ||
+ (strncasecmp("quit", argv[0], tlen) == 0))
+ do_exit = true;
+ else
+ rosh_help(1, argv[0]);
+ break;
+ case 'c':
+ case 'C':
+ if (strncasecmp("echo", argv[0], tlen) == 0)
+ rosh_pr_argv(argc - 1, &argv[1]);
+ else
+ rosh_help(1, argv[0]);
+ break;
+ default:
+ rosh_help(1, argv[0]);
+ }
break;
case 'c':
case 'C': /* run 'cd' 'cat' 'cfg' */
- switch (cmdstr[1]) {
+ switch (argv[0][1]) {
case 'a':
case 'A':
- if (strncasecmp("cat", tstr, tlen) == 0)
- rosh_cat(cmdstr);
+ if (strncasecmp("cat", argv[0], tlen) == 0)
+ rosh_cat(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'd':
case 'D':
- if (strncasecmp("cd", tstr, tlen) == 0)
- rosh_cd(cmdstr, ipwdstr);
+ if (strncasecmp("cd", argv[0], tlen) == 0)
+ rosh_cd(argc, argv, ipwdstr);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'f':
case 'F':
- if (strncasecmp("cfg", tstr, tlen) == 0)
+ if (strncasecmp("cfg", argv[0], tlen) == 0)
rosh_cfg();
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
default:
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
}
break;
case 'd':
case 'D': /* run 'dir' */
- if (strncasecmp("dir", tstr, tlen) == 0)
- rosh_dir(cmdstr);
+ if (strncasecmp("dir", argv[0], tlen) == 0)
+ rosh_dir(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'h':
case 'H':
case '?':
- if ((strncasecmp("help", tstr, tlen) == 0) || (tlen == 1))
- rosh_help(2, cmdstr);
+ if ((strncasecmp("help", argv[0], tlen) == 0) || (tlen == 1))
+ rosh_help(2, argv[1]);
else
rosh_help(1, NULL);
break;
case 'l':
case 'L': /* run 'ls' 'less' */
- switch (cmdstr[1]) {
+ switch (argv[0][1]) {
case 0:
- case ' ':
case 's':
case 'S':
- if (strncasecmp("ls", tstr, tlen) == 0)
- rosh_ls(cmdstr);
+ if (strncasecmp("ls", argv[0], tlen) == 0)
+ rosh_ls(argc, argv);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'e':
case 'E':
- if (strncasecmp("less", tstr, tlen) == 0)
- rosh_less(cmdstr);
+ if (strncasecmp("less", argv[0], tlen) == 0)
+ rosh_less(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
default:
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
}
break;
case 'm':
case 'M':
- switch (cmdstr[1]) {
+ switch (argv[0][1]) {
case 'a':
case 'A':
- if (strncasecmp("man", tstr, tlen) == 0)
- rosh_help(2, cmdstr);
+ if (strncasecmp("man", argv[0], tlen) == 0)
+ rosh_help(2, argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'o':
case 'O':
- if (strncasecmp("more", tstr, tlen) == 0)
- rosh_more(cmdstr);
+ if (strncasecmp("more", argv[0], tlen) == 0)
+ rosh_more(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
default:
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
}
break;
case 'p':
case 'P': /* run 'pwd' */
- if (strncasecmp("pwd", tstr, tlen) == 0)
- rosh_pwd(cmdstr);
+ if (strncasecmp("pwd", argv[0], tlen) == 0)
+ rosh_pwd();
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'r':
case 'R': /* run 'run' */
- switch (cmdstr[1]) {
+ switch (argv[0][1]) {
case 0:
- case ' ':
case 'e':
case 'E':
- if (strncasecmp("reboot", tstr, tlen) == 0)
- rosh_reboot();
+ if (strncasecmp("reboot", argv[0], tlen) == 0)
+ rosh_reboot(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'u':
case 'U':
- if (strncasecmp("run", tstr, tlen) == 0)
- rosh_run(cmdstr);
+ if (strncasecmp("run", argv[0], tlen) == 0)
+ rosh_run(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
+ default:
+ rosh_help(1, argv[0]);
}
break;
case 'v':
case 'V':
- if (strncasecmp("version", tstr, tlen) == 0)
+ if (strncasecmp("version", argv[0], tlen) == 0)
rosh_version(1);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 0:
case '\n':
break;
default:
- rosh_help(1, NULL);
- } /* switch(cmdstr[0]) */
+ rosh_help(1, argv[0]);
+ } /* switch(argv[0][0]) */
return do_exit;
} /* rosh_command */
@@ -1150,29 +1304,29 @@ char rosh_command(const char *cmdstr, const char *ipwdstr)
* icmdstr Initial command line string
* returns Exit status
*/
-int rosh_prompt(const char *icmdstr)
+int rosh_prompt(int iargc, char *iargv[])
{
int rv;
char cmdstr[ROSH_CMD_SZ];
char ipwdstr[ROSH_PATH_SZ];
char do_exit;
- char *c;
+ char **argv;
+ int argc;
rv = 0;
do_exit = false;
if (!getcwd(ipwdstr, ROSH_PATH_SZ))
strcpy(ipwdstr, "./");
- if (icmdstr[0] != '\0')
- do_exit = rosh_command(icmdstr, ipwdstr);
+ if (iargc > 1)
+ do_exit = rosh_command(iargc - 1, &iargv[1], ipwdstr);
while (!(do_exit)) {
/* Extra preceeding newline */
printf("\nrosh: ");
/* Read a line from console */
if (fgets(cmdstr, ROSH_CMD_SZ, stdin)) {
- /* remove newline from input string */
- c = strchr(cmdstr, '\n');
- *c = 0;
- do_exit = rosh_command(cmdstr, ipwdstr);
+ argc = rosh_str2argv(&argv, cmdstr);
+ do_exit = rosh_command(argc, argv, ipwdstr);
+ rosh_free_argv(&argv);
} else {
do_exit = false;
}
@@ -1183,19 +1337,21 @@ int rosh_prompt(const char *icmdstr)
int main(int argc, char *argv[])
{
int rv;
- char cmdstr[ROSH_CMD_SZ];
/* Initialization */
rv = 0;
rosh_console_std();
- if (argc != 1) {
- rv = rosh_argcat(cmdstr, argc, argv, 1);
- } else {
+ if (argc == 1) {
rosh_version(0);
print_beta();
- cmdstr[0] = '\0';
+ } else {
+#ifdef DO_DEBUG
+ char cmdstr[ROSH_CMD_SZ];
+ rosh_argcat(cmdstr, ROSH_CMD_SZ, argc, argv, 1);
+ ROSH_DEBUG("arg='%s'\n", cmdstr);
+#endif
}
- rv = rosh_prompt(cmdstr);
- printf("--Exiting '%s'\n", APP_NAME);
+ rv = rosh_prompt(argc, argv);
+ printf("--Exiting '" APP_NAME "'\n");
return rv;
}
diff --git a/com32/rosh/rosh.h b/com32/rosh/rosh.h
index b016e2f2..cabf556a 100644
--- a/com32/rosh/rosh.h
+++ b/com32/rosh/rosh.h
@@ -36,26 +36,32 @@
#include <sys/stat.h> /* fstat() */
#include <fcntl.h> /* open(); open mode macros */
#include <dirent.h> /* fdopendir() opendir() readdir() closedir() DIR */
-#include <unistd.h> /* getcwd() */
+#include <unistd.h> /* getcwd() getopt() */
#include <errno.h> /* errno; error macros */
#include <netinet/in.h> /* For htonl/ntohl/htons/ntohs */
#include <ctype.h> /* isspace() */
#include <getkey.h>
#include <consoles.h> /* console_ansi_raw() console_ansi_std() */
+// #include <getopt.h> /* getopt_long() */
#ifdef DO_DEBUG
# define ROSH_DEBUG printf
+# define ROSH_DEBUG_ARGV_V rosh_pr_argv_v
/* define ROSH_DEBUG(f, ...) printf (f, ## __VA_ARGS__) */
# ifdef DO_DEBUG2
# define ROSH_DEBUG2 printf
+# define ROSH_DEBUG2_ARGV_V rosh_pr_argv_v
# else /* DO_DEBUG2 */
/* This forces a format argument into the function call */
# define ROSH_DEBUG2(f, ...) ((void)0)
+# define ROSH_DEBUG2_ARGV_V(argc, argv) ((void)0)
# endif /* DO_DEBUG2 */
#else /* DO_DEBUG */
# define ROSH_DEBUG(f, ...) ((void)0)
+# define ROSH_DEBUG_ARGV_V(argc, argv) ((void)0)
# define ROSH_DEBUG2(f, ...) ((void)0)
+# define ROSH_DEBUG2_ARGV_V(argc, argv) ((void)0)
#endif /* DO_DEBUG */
#ifdef __COM32__
@@ -135,10 +141,10 @@ static inline int getscreensize(int fd, int *rows, int *cols)
str = NULL;
if (fd == 1) {
ioctl(0, TIOCGWINSZ, &ws);
-/* if (rows)
+ if (rows)
*rows = ws.ws_row;
if (cols)
- *cols = ws.ws_col;*/
+ *cols = ws.ws_col;
if (rows && !*rows) {
str = getenv("LINES");
if (str)
@@ -235,6 +241,10 @@ const char rosh_beta_str[] =
const char rosh_cd_norun_str[] =
" -- cd (Change Directory) not implemented for use with run and exit.\n";
+const char rosh_help_cd_str[] = "cd Change directory\n\
+ with no argument, return to original directory from entry to rosh\n\
+ with one argument, change to that directory";
+
const char rosh_help_ls_str[] = "ls List contents of current directory\n\
-l Long format\n\
-i Inode; print Inode of file\n\
@@ -259,4 +269,6 @@ const char rosh_help_str2[] =
const char rosh_help_str_adv[] = "No additional help available for '%s'";
+const char rosh_ls_opt_str[] = "lFi";
+
#endif /* Not ROSH_H */
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index a46b3da5..e8818a6c 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -365,6 +365,16 @@ pxenv:
pushfd
pushad
+ ; We may be removing ourselves from memory
+ cmp bx,0073h ; PXENV_RESTART_TFTP
+ jz .disable_timer
+ cmp bx,00E5h ; gPXE PXENV_FILE_EXEC
+ jnz .store_stack
+
+.disable_timer:
+ call timer_cleanup
+
+.store_stack:
mov [cs:PXEStack],sp
mov [cs:PXEStack+2],ss
lss sp,[cs:InitStack]
@@ -391,6 +401,17 @@ pxenv:
; This clobbers the AX return, but we already saved it into
; the PXEStatus variable.
popad
+
+ ; If the call failed, it could return.
+ cmp bx,0073h
+ jz .enable_timer
+ cmp bx,00E5h
+ jnz .pop_flags
+
+.enable_timer:
+ call timer_init
+
+.pop_flags:
popfd ; Restore flags (incl. IF, DF)
ret
diff --git a/core/writedec.inc b/core/writedec.inc
index bfac0997..19e47968 100644
--- a/core/writedec.inc
+++ b/core/writedec.inc
@@ -37,6 +37,7 @@ writedec_common:
xor cx,cx ; Number of digits
.cloop:
+ mov edx,0
div ebx
inc cx
push dx
@@ -53,5 +54,5 @@ writedec_common:
popad
ret
-writechr:
- ret
+; writechr:
+; ret
diff --git a/modules/Makefile b/modules/Makefile
index f3183641..9b50bb23 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -19,7 +19,7 @@ include $(topdir)/MCONFIG.embedded
INCLUDES = -I$(com32)/include
-BINS = pxechain.com poweroff.com int18.com
+BINS = pxechain.com poweroff.com int18.com ver.com
all: $(BINS)
diff --git a/modules/ver.asm b/modules/ver.asm
new file mode 100644
index 00000000..8ef63faf
--- /dev/null
+++ b/modules/ver.asm
@@ -0,0 +1,606 @@
+; ****************************************************************************
+;
+; ver.asm
+;
+; A COMBOOT/DOS COM program to display the version of the system
+; (Syslinux, DOS, or DRMK)
+;
+; Copyright (C) 2009-2010 Gene Cumm
+;
+; 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.
+;
+; ****************************************************************************
+
+; %define DEBUG
+
+ section .text
+ org 0x100
+
+_start:
+ call crlf
+ mov si,info_str
+ call writestr
+ call getdosver
+ call chkprn_dosver
+ jnz .end
+ call chkprn_syslinux
+ call crlf
+.end:
+; pop ds
+ ret
+
+
+; chkprn_syslinux
+chkprn_syslinux:
+%ifdef DEBUG
+ mov si,may_sysl_str
+ call writestr
+%endif
+ cmp eax,59530000h
+ jne .end
+ cmp ebx,4C530000h
+ jne .end
+ cmp ecx,4E490000h
+ jne .end
+ cmp edx,58550000h
+ jne .end
+.is_syslinux:
+ pushad
+%ifdef DEBUG
+ mov si,is_sysl_str
+ call writestr
+%endif
+.get_sysl_ver:
+ mov ax,0001h
+ int 22h
+; AX=0001h [2.00] Get Version
+;
+; Input: AX 0001h
+; Output: AX number of INT 22h API functions available
+; CH Syslinux major version number
+; CL Syslinux minor version number
+; DL Syslinux derivative ID (e.g. 32h = PXELINUX)
+; ES:SI Syslinux version string
+; ES:DI Syslinux copyright string
+%ifdef DEBUG
+ push si
+ push cs
+ pop ds
+ mov si,gotver_str
+ call writestr
+ pop si
+%endif
+
+.prn_ver_str:
+ mov si,syslban_str
+ call writestr
+ push ds
+ push es
+ pop ds
+ call writestr
+ call crlf
+ pop ds
+.prn_var:
+ cmp dl,31h
+ je .var_sysl
+ cmp dl,32h
+ je .var_pxel
+ cmp dl,33h
+ je .var_isol
+ cmp dl,34h
+ je .var_extl
+ jmp .var_unk
+.var_sysl:
+ mov si,sysl_str
+ call writestr
+ jmp .prn_lnxsp
+.var_pxel:
+ mov si,pxel_str
+ call writestr
+ jmp .prn_lnxsp
+.var_isol:
+ mov si,isol_str
+ call writestr
+ jmp .prn_lnxsp
+.var_extl:
+ mov si,extl_str
+ call writestr
+; jmp .prn_lnxsp
+.prn_lnxsp:
+ mov si,linsp_str
+ call writestr
+ jmp .prn_ver
+.var_unk:
+ mov si,unkvar_str
+ call writestr
+.prn_ver:
+%ifdef DEBUG
+ push si
+ push cs
+ pop ds
+ mov si,prn_ver_str
+ call writestr
+ pop si
+%endif
+.prn_ver_maj:
+ mov al,ch
+ call writedecb
+ mov dl,'.'
+ call writechr_dl
+.prn_ver_min:
+ mov al,cl
+; cmp al,10
+; jae .min_wri
+; mov al,'0'
+; call writechr
+; mov al,cl
+; .min_wri:
+; call writedecb
+ call writedecb2
+
+.end_prn:
+ popad
+.end:
+ ret
+
+; chkprn_dosver Check and print DOS version;
+; Input Data from INT21 AH=30h
+; AH Major version of DOS or 0
+; AL Minor Version
+; BH DOS type
+; BL:CX 24-bit OEM serial number
+; Return
+; ZF Unset if DOS, Set if not DOS (AX=0)
+chkprn_dosver:
+ and ax,ax ; cmp ax,0
+ jz .end
+.is_dos:
+ push eax
+ push edx
+ push si
+%ifdef DEBUG
+ mov si,is_dos_str
+ call writestr
+ call crlf
+ call prnreg_gp_l
+ call crlf
+%endif
+.var_prn:
+ cmp bh,0
+ je .var_pcdos
+ cmp bh,0FFh
+ je .var_msdos
+ cmp bh,0FDh
+ je .var_freedos
+ cmp bh,0DEh
+ je .var_drmk
+ jmp .var_unk
+.var_pcdos:
+ mov si,pcdos_str
+ call writestr
+ jmp .var_end
+.var_msdos:
+ mov si,msdos_str
+ call writestr
+ jmp .var_end
+.var_freedos:
+ mov si,freedos_str
+ call writestr
+ jmp .var_end
+.var_drmk:
+ mov si,drmk_str
+ call writestr
+ jmp .var_end
+.var_unk:
+ mov si,unkdos_str
+ call writestr
+ mov si,spparen_str
+ call writestr
+ push eax
+ mov al,bh
+ call writehex2
+ pop eax
+ mov si,parensp_str
+ call writestr
+; jmp .var_end
+.var_end:
+ call prn_dosver_num
+ call crlf
+.subver:
+ pop si
+ pop edx
+ pop eax
+ cmp bh,0FFh
+ je .msdos_ver
+ cmp bh,0DEh
+ jne .end_ver
+.drmk_ver:
+ call getprn_drmkver
+; jmp .end_ver ; DRMK returns Extended/True DOS
+.msdos_ver:
+ cmp al,5
+ jb .end_ver
+ call getprn_msdosver
+.end_ver:
+ and ax,ax ; Unset ZF
+.end:
+ ret
+
+; prn_dosver_num Print the numerical DOS version
+; Input Data from INT21 AH=30h
+; AH Major version of DOS or 0
+; AL Minor Version
+; BH DOS type
+; BL:CX 24-bit OEM serial number
+prn_dosver_num:
+ push eax
+ push edx
+ push si
+ pushfd
+.vmaj_prn:
+ call writedecb
+; call writehex2
+ mov dl,'.'
+ call writechr_dl
+.vmin_prn:
+ mov al,ah
+ call writedecb
+; call writehex2
+.serial: ; Skip if 0
+ cmp bl,0
+ jne .ser_start
+ cmp cx,0
+ je .end
+.ser_start:
+ mov si,spparen_str
+ call writestr
+ mov si,zerox_str
+ call writestr
+.ser_bl:
+ mov al,bl
+ call writehex2
+.ser_cx:
+ mov ax,cx
+ call writehex4
+.serial_end:
+ mov si,parensp_str
+ call writestr
+.end:
+ popfd
+ pop si
+ pop edx
+ pop eax
+ ret
+
+; getdosver Get the DOS version
+; Return Version or 0 + SYSLINUX message
+; EAX Part 1
+; EBX Part 2
+; ECX Part 3
+; EDX Part 4
+getdosver:
+ mov ecx,0
+ mov edx,0
+ mov ebx,0
+ mov eax,3000h
+ int 21h
+ ret
+
+; getmsdosver Get the Extended MS-DOS version
+; Returns Version
+; EAX Part 1
+; EBX Part 2
+; ECX Part 3
+; EDX Part 4
+getmsdosver:
+ mov ecx,0
+ mov edx,0
+ mov ebx,0
+ mov eax,3306h
+ int 21h
+ ret
+
+; getprn_msdosver
+getprn_msdosver:
+ pushad
+ pushfd
+ call getmsdosver
+%ifdef DEBUG
+ call prnreg_gp_l
+ call crlf
+%endif
+ mov si,dosext_str
+ call writestr
+ mov eax,ebx
+ mov ebx,0
+ mov ecx,edx
+ call prn_dosver_num
+.end:
+ popfd
+ popad
+ ret
+
+; getdrmkver: Get the DRMK-specifc OS version
+; Returns Version
+; AX OS Version
+; DX Patch Version
+getdrmkver:
+ mov ax,4452h
+ int 21h
+ ret
+
+; getdrmkver: Get the DRMK-specifc Kernel build info
+; Returns Kernel build info
+; AX Kernel build date in DOS 16-bit format
+; [ES:BX] Kernel private data
+getdrmkbld:
+ mov ax,4458h
+ int 21h
+ ret
+
+; getprn_drmkver: Get/Print DRMK-specific Version info
+getprn_drmkver:
+ pushad
+ pushfd
+.getver:
+ call getdrmkver
+.prnosver: ; "OS Version"
+ mov si,osver_str
+ call writestr
+ mov si,zerox_str
+ call writestr
+; mov ax,0
+ call writehex4
+ call crlf
+.prnpatchver: ; "Patch Version"
+ mov si,patchver_str
+ call writestr
+ mov si,zerox_str
+ call writestr
+ mov ax,dx
+ call writehex4
+ call crlf
+.getbld:
+ call getdrmkbld
+.prnkernbld: ; "Kernel Build Date"
+ mov si,kernbld_str
+ call writestr
+ call writedate_ax
+ call crlf
+.prnkernprvaddr:
+ mov si,prvdat_str
+ call writestr
+ mov ax,es
+ call writehex4
+ mov dl,':'
+ call writechr_dl
+ mov ax,bx
+ call writehex4
+ call crlf
+%ifdef DEBUG
+.prnkernprv:
+ mov di,[es:bx]
+ mov ax,di
+ call writehex4
+ call crlf
+ mov si,2
+ mov cx,8
+.prnkernprv2:
+ push cx
+ mov cx,8
+.prnkernprv1:
+ mov eax,[es:bx+si]
+ call writehex8
+ cmp cx,1
+ jbe .prnkern0dash
+ mov ax,'-'
+ call writechr
+.prnkern0dash:
+ add si,4
+ sub di,4
+ cmp di,0
+ jbe .prnkernprvend
+ loop .prnkernprv1
+ call crlf
+ pop cx
+ loop .prnkernprv2
+ jmp .end
+.prnkernprvend:
+ pop cx
+%endif
+.end:
+ popfd
+ popad
+ ret
+
+;writedate_ax Write a date in AX in ISO8601 big endian format
+; Input
+; AX Date in 16-bit DOS format
+; 2006-01-11
+; 0011010 0001 01011
+writedate_ax:
+ pushad
+ pushfd
+ mov dx,ax
+%ifdef DEBUG
+ call writehex4
+ call crlf
+%endif
+.year:
+ shr ax,9
+ add ax,1980
+ call writedecw
+ mov al,'-'
+ call writechr
+ mov ax,dx
+.month:
+ shr ax,5
+ and ax,0Fh
+; cmp ax,10
+; jae .month_wri
+; mov cx,ax
+; mov ax,'0'
+; call writechr
+; mov ax,cx
+; .month_wri:
+; call writedecb
+ call writedecb2
+ mov al,'-'
+ call writechr
+ mov ax,dx
+.day:
+ and ax,1Fh
+; cmp ax,10
+; jae .day_wri
+; mov cx,ax
+; mov ax,'0'
+; call writechr
+; mov ax,cx
+; .day_wri:
+; call writedecb
+ call writedecb2
+.end:
+ popfd
+ popad
+ ret
+
+; writechr_dl Write a character to the console saving AX
+; Input
+; DL character to write
+writechr_dl:
+ push ax
+ mov ah,02h
+ int 21h
+.end:
+ pop ax
+ ret
+
+; writechr_al Write a character to the console saving AX
+; Input
+; AL character to write
+writechr:
+writechr_al:
+ push dx
+ mov dl,al
+ call writechr_dl
+.end: pop dx
+ ret
+
+; writedecb[23] Print byte as fixed width
+; Input
+; AL number to write
+writedecb3:
+ pushfd
+ cmp al,100
+ jae .skip
+ push ax
+ mov ax,'0'
+ call writechr
+ pop ax
+.skip: popfd
+writedecb2:
+ pushfd
+ cmp al,10
+ jae .skip
+ push ax
+ mov ax,'0'
+ call writechr
+ pop ax
+.skip: popfd
+ call writedecb
+ ret
+
+
+; prnreg_gp_l Dump GP registers (Long)
+prnreg_gp_l:
+ push eax
+ push si
+ call crlf
+ mov si,sp2_str
+ call writestr
+ mov si,eax_str
+ call writestr
+ call writehex8
+ mov si,sp2_str
+ call writestr
+ mov si,ecx_str
+ call writestr
+ mov eax,ecx
+ call writehex8
+ mov si,sp2_str
+ call writestr
+ mov si,edx_str
+ call writestr
+ mov eax,edx
+ call writehex8
+ mov si,sp2_str
+ call writestr
+ mov si,ebx_str
+ call writestr
+ mov eax,ebx
+ call writehex8
+ call crlf
+ pop si
+ pop eax
+.end:
+ ret
+
+; is_zf
+is_zf:
+ push si
+ jz .true
+.false:
+ mov si,zero_not_str
+ call writestr
+ jmp .end
+.true:
+ mov si,zero_is_str
+ call writestr
+.end:
+ pop si
+ ret
+
+%include "../core/macros.inc" ; CR/LF
+%include "../core/writestr.inc" ; String output
+%include "../core/writehex.inc" ; Hexadecimal output
+%include "../core/writedec.inc" ; Decimal output
+
+ section .data
+info_str db 'Ver.com b026', CR, LF, 0
+is_dos_str db 'Found DOS', CR, LF, 0
+is_sysl_str db 'Found a Syslinux variant', CR, LF, 0
+is_drmk_str db 'Found DRMK', CR, LF, 0
+may_sysl_str db 'Maybe Syslinux variant', CR, LF, 0
+gotver_str db 'Got the version back', CR, LF, 0
+prn_ver_str db 'Printing version number', CR, LF, 0
+syslban_str db 'Syslinux banner: ',0
+sysl_str db 'SYS', 0
+pxel_str db 'PXE', 0
+isol_str db 'ISO', 0
+extl_str db 'EXT', 0
+linsp_str db 'LINUX ', 0
+unkvar_str db 'Unkown-Variant ', 0
+pcdos_str db 'PC-DOS ', 0
+msdos_str db 'MS-DOS ', 0
+freedos_str db 'FreeDOS ', 0
+unkdos_str db 'Unknown-DOS ', 0
+drmk_str db 'DRMK ', 0
+dosext_str db ' Extended DOS version: ', 0
+osver_str db ' OS Version: ', 0
+patchver_str db ' Patch Version: ', 0
+kernbld_str db ' Kernel Build Date: ', 0
+prvdat_str db ' Private Data Ptr: ', 0
+spparen_str db ' (', 0
+zerox_str db '0x', 0
+parensp_str db ') ', 0
+eax_str db 'EAX=', 0
+ebx_str db 'EBX=', 0
+ecx_str db 'ECX=', 0
+edx_str db 'EDX=', 0
+sp2_str db ' ', 0
+zero_not_str db ' NOT_Zero ',0
+zero_is_str db ' IS_Zero ',0