aboutsummaryrefslogtreecommitdiffstats
path: root/com32
diff options
context:
space:
mode:
Diffstat (limited to 'com32')
-rw-r--r--com32/include/unistd.h4
-rw-r--r--com32/rosh/rosh.c658
-rw-r--r--com32/rosh/rosh.h18
3 files changed, 426 insertions, 254 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 */