Adding upstream version 3.86+dfsg.
[syslinux-debian/hramrach.git] / com32 / rosh / rosh.c
blob720d86440458200012401b7636f6af35a2ed7d46
1 /* ----------------------------------------------------------------------- *
3 * Copyright 2008 Gene Cumm - All Rights Reserved
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 * Boston MA 02111-1307, USA; either version 2 of the License, or
9 * (at your option) any later version; incorporated herein by reference.
11 * ----------------------------------------------------------------------- */
14 * rosh.c
16 * Read-Only shell; Simple shell system designed for SYSLINUX-derivitives.
17 * Provides minimal commands utilizing the console via stdout/stderr as the
18 * sole output devices. Designed to compile for Linux for testing/debugging.
22 * ToDos:
23 * Change functions to use pwdstr
24 * In rosh_run() Reparse cmdstr relative to pwdstr
27 // #define DO_DEBUG 1
28 /* Uncomment the above line for debugging output; Comment to remove */
29 // #define DO_DEBUG2 1
30 /* Uncomment the above line for super-debugging output; Must have regular debugging enabled; Comment to remove */
32 #include "rosh.h"
34 #define APP_LONGNAME "Read-Only Shell"
35 #define APP_NAME "rosh"
36 #define APP_AUTHOR "Gene Cumm"
37 #define APP_YEAR "2008"
38 #define APP_VER "beta-b032"
40 void rosh_version(void)
42 printf("%s v %s; (c) %s %s.\n", APP_LONGNAME, APP_VER, APP_YEAR,
43 APP_AUTHOR);
46 void rosh_help(int type)
48 rosh_version();
49 switch (type) {
50 case 2:
51 puts(rosh_help_str2);
52 break;
53 case 1:
54 default:
55 puts(rosh_help_str1);
59 /* Determine if a character is whitespace
60 * inc input character
61 * returns 0 if not whitespace
63 int rosh_issp(char inc)
65 int rv;
66 switch (inc) {
67 case ' ':
68 case '\t':
69 rv = 1;
70 break;
71 default:
72 rv = 0;
74 return rv;
75 } /* ros_issp */
77 /* Search a string for first non-space (' ') character, starting at ipos
78 * istr input string to parse
79 * ipos input position to start at
81 int rosh_search_nonsp(const char *istr, const int ipos)
83 int curpos;
84 char c;
86 curpos = ipos;
87 c = istr[curpos];
88 while (rosh_issp(c) && c != 0)
89 c = istr[++curpos];
90 return curpos;
93 /* Search a string for space (' '), returning the position of the next space
94 * or the '\0' at end of string
95 * istr input string to parse
96 * ipos input position to start at
98 int rosh_search_sp(const char *istr, const int ipos)
100 int curpos;
101 char c;
103 curpos = ipos;
104 c = istr[curpos];
105 while (!(rosh_issp(c)) && c != 0)
106 c = istr[++curpos];
107 return curpos;
110 /* Parse a string for the first non-space string, returning the end position
111 * from src
112 * dest string to contain the first non-space string
113 * src string to parse
114 * ipos Position to start in src
116 int rosh_parse_sp_1(char *dest, const char *src, const int ipos)
118 int bpos, epos; /* beginning and ending position of source string
119 to copy to destination string */
121 bpos = 0;
122 epos = 0;
123 /* //HERE-error condition checking */
124 bpos = rosh_search_nonsp(src, ipos);
125 epos = rosh_search_sp(src, bpos);
126 if (epos > bpos) {
127 memcpy(dest, src + bpos, epos - bpos);
128 if (dest[epos - bpos] != 0)
129 dest[epos - bpos] = 0;
130 } else {
131 epos = strlen(src);
132 dest[0] = 0;
134 return epos;
137 /* Handle most/all errors
138 * ierrno Input Error number
139 * cmdstr Command being executed to cause error
140 * filestr File/parameter causing error
142 void rosh_error(const int ierrno, const char *cmdstr, const char *filestr)
144 printf("--ERROR: %s '%s': ", cmdstr, filestr);
145 switch (ierrno) {
146 case EACCES:
147 printf("Access DENIED\n");
148 break;
149 case ENOENT:
150 printf("not found\n");
151 /* SYSLinux-3.72 COM32 API returns this for a
152 directory or empty file */
153 ROSH_COM32(" (COM32) could be a directory or empty file\n");
154 break;
155 case ENOTDIR:
156 printf("not a directory\n");
157 ROSH_COM32(" (COM32) could be directory\n");
158 break;
159 case ENOSYS:
160 printf("not implemented");
161 break;
162 default:
163 printf("returns error; errno=%d\n", ierrno);
167 /* Concatenate command line arguments into one string
168 * cmdstr Output command string
169 * argc Argument Count
170 * argv Argument Values
171 * barg Beginning Argument
173 int rosh_argcat(char *cmdstr, const int argc, char *argv[], const int barg)
175 int i, arglen, curpos; /* index, argument length, current position
176 in cmdstr */
177 curpos = 0;
178 cmdstr[0] = '\0'; /* Nullify string just to be sure */
179 for (i = barg; i < argc; i++) {
180 arglen = strlen(argv[i]);
181 /* Theoretically, this should never be met in SYSLINUX */
182 if ((curpos + arglen) > (ROSH_CMD_SZ - 1))
183 arglen = (ROSH_CMD_SZ - 1) - curpos;
184 memcpy(cmdstr + curpos, argv[i], arglen);
185 curpos += arglen;
186 if (curpos >= (ROSH_CMD_SZ - 1)) {
187 /* Hopefully, curpos should not be greater than
188 (ROSH_CMD_SZ - 1) */
189 /* Still need a '\0' at the last character */
190 cmdstr[(ROSH_CMD_SZ - 1)] = 0;
191 break; /* Escape out of the for() loop;
192 We can no longer process anything more */
193 } else {
194 cmdstr[curpos] = ' ';
195 curpos += 1;
196 cmdstr[curpos] = 0;
199 /* If there's a ' ' at the end, remove it. This is normal unless
200 the maximum length is met/exceeded. */
201 if (cmdstr[curpos - 1] == ' ')
202 cmdstr[--curpos] = 0;
203 return curpos;
204 } /* rosh_argcat */
207 * Prints a lot of the data in a struct termios
210 void rosh_print_tc(struct termios *tio)
212 printf(" -- termios: ");
213 printf(".c_iflag=%04X ", tio->c_iflag);
214 printf(".c_oflag=%04X ", tio->c_oflag);
215 printf(".c_cflag=%04X ", tio->c_cflag);
216 printf(".c_lflag=%04X ", tio->c_lflag);
217 printf(".c_cc[VTIME]='%d' ", tio->c_cc[VTIME]);
218 printf(".c_cc[VMIN]='%d'", tio->c_cc[VMIN]);
219 printf("\n");
224 * Switches console over to raw input mode. Allows get_key to get just
225 * 1 key sequence (without delay or display)
227 void rosh_console_raw(void)
229 // struct termios itio, ntio;
230 // tcgetattr(0, &itio);
231 // rosh_print_tc(&itio);
232 /* ntio = itio;
233 ntio.c_lflag &= ~(ICANON|ECHO);
234 tcsetattr(0, TCSAFLUSH, &ntio);*/
235 console_ansi_raw(); /* Allows get_key to get just 1 key sequence
236 (w/o delay or display */
237 // tcgetattr(0, &ntio);
238 // rosh_print_tc(&ntio);
242 * Switches back to standard getline mode.
244 void rosh_console_std(void)
246 // struct termios itio, ntio;
247 console_ansi_std();
248 // tcsetattr(0, TCSANOW, &itio);
252 * Attempts to get a single key from the console
253 * returns key pressed
255 int rosh_getkey(void)
257 int inc;
259 inc = KEY_NONE;
260 // rosh_console_raw();
261 while (inc == KEY_NONE) {
262 inc = get_key(stdin, 6000);
264 // rosh_console_std();
265 return inc;
266 } /* rosh_getkey */
268 /* Template for command functions
269 * cmdstr command string to process
270 * pwdstr Present Working Directory string
271 * ipwdstr Initial PWD
273 void rosh_1(const char *cmdstr, const char *pwdstr, const char *ipwdstr)
275 ROSH_DEBUG("CMD: '%s'\npwd: '%s'\npwd: '%s'\n", cmdstr, pwdstr, ipwdstr);
276 } /* rosh_1 */
278 /* Concatenate multiple files to stdout
279 * cmdstr command string to process
280 * pwdstr Present Working Directory string
282 void rosh_cat(const char *cmdstr, const char *pwdstr)
284 FILE *f;
285 char filestr[ROSH_PATH_SZ + 1];
286 char buf[ROSH_BUF_SZ];
287 int numrd;
288 int cmdpos;
290 ROSH_DEBUG("CMD: '%s'\npwd: '%s'\n", cmdstr, pwdstr);
291 /* Initialization */
292 filestr[0] = 0;
293 cmdpos = 0;
294 /* skip the first word */
295 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
296 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
297 while (strlen(filestr) > 0) {
298 printf("--File = '%s'\n", filestr);
299 f = fopen(filestr, "r");
300 if (f != NULL) {
301 numrd = fread(buf, 1, ROSH_BUF_SZ, f);
302 while (numrd > 0) {
303 fwrite(buf, 1, numrd, stdout);
304 numrd = fread(buf, 1, ROSH_BUF_SZ, f);
306 fclose(f);
307 } else {
308 rosh_error(errno, "cat", filestr);
310 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
312 } /* rosh_cat */
314 /* Change PWD (Present Working Directory)
315 * cmdstr command string to process
316 * pwdstr Present Working Directory string
317 * ipwdstr Initial PWD
319 void rosh_cd(const char *cmdstr, char *pwdstr, const char *ipwdstr)
321 int rv;
322 char filestr[ROSH_PATH_SZ + 1];
323 int cmdpos;
324 ROSH_DEBUG("CMD: '%s'\npwd: '%s'\n", cmdstr, pwdstr);
325 /* Initialization */
326 filestr[0] = 0;
327 cmdpos = 0;
328 rv = 0;
329 /* skip the first word */
330 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
331 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
332 ROSH_COM32
333 (" -- cd (Change Directory) not implemented for use with run and exit.\n");
334 if (strlen(filestr) != 0)
335 rv = chdir(filestr);
336 else
337 rv = chdir(ipwdstr);
338 if (rv != 0) {
339 rosh_error(errno, "cd", filestr);
340 } else {
341 getcwd(pwdstr, ROSH_PATH_SZ + 1);
342 printf(" %s\n", pwdstr);
344 } /* rosh_cd */
346 /* Print the syslinux config file name
347 * cmdstr command string to process
348 * pwdstr Present Working Directory string
350 void rosh_cfg(const char *cmdstr, const char *pwdstr)
352 ROSH_DEBUG("CMD: '%s'\npwd: '%s'\n", cmdstr, pwdstr);
353 printf("CFG: '%s'\n", syslinux_config_file());
354 } /* rosh_cfg */
356 /* Simple directory listing for one argument (file/directory) based on
357 * filestr and pwdstr
358 * ifilstr input filename/directory name to list
359 * pwdstr Present Working Directory string
361 void rosh_dir_arg(const char *ifilstr, const char *pwdstr)
363 struct stat fdstat;
364 int status;
365 int fd;
366 char filestr[ROSH_PATH_SZ + 1];
367 int filepos;
368 DIR *d;
369 struct dirent *de;
370 #ifdef DO_DEBUG
371 char filestr2[ROSH_PATH_SZ + 1];
372 int fd2, file2pos;
373 #ifdef __COM32__
374 // int inchar;
375 char ty;
376 #endif /* __COM32__ */
377 #endif /* DO_DEBUG */
379 /* Initialization; make filestr based on leading character of ifilstr
380 and pwdstr */
381 if (ifilstr[0] == SEP) {
382 strcpy(filestr, ifilstr);
383 } else {
384 strcpy(filestr, pwdstr);
385 filepos = strlen(pwdstr);
386 if (filestr[filepos - 1] != SEP)
387 filestr[filepos++] = SEP;
388 strcpy(filestr + filepos, ifilstr);
389 ROSH_DEBUG("--'%s'\n", filestr);
391 fd = open(filestr, O_RDONLY);
392 if (fd != -1) {
393 status = fstat(fd, &fdstat);
394 if (S_ISDIR(fdstat.st_mode)) {
395 ROSH_DEBUG("PATH '%s' is a directory\n", ifilstr);
396 d = fdopendir(fd);
397 de = readdir(d);
398 while (de != NULL) {
399 #ifdef DO_DEBUG
400 filestr2[0] = 0;
401 file2pos = strlen(filestr);
402 memcpy(filestr2, filestr, file2pos);
403 filestr2[file2pos] = '/';
404 strcpy(filestr2 + file2pos + 1, de->d_name);
405 fd2 = open(filestr2, O_RDONLY);
406 status = fstat(fd2, &fdstat);
407 printf("@%8d:%8d:", (int)de->d_ino, (int)fdstat.st_size);
408 fd2 = close(fd2);
409 #endif /* DO_DEBUG */
410 printf("%s\n", de->d_name);
411 #ifdef DO_DEBUG
412 // inchar = fgetc(stdin);
413 #endif /* DO_DEBUG */
414 de = readdir(d);
416 closedir(d);
417 } else if (S_ISREG(fdstat.st_mode)) {
418 ROSH_DEBUG("PATH '%s' is a regular file\n", ifilstr);
419 printf("%8d:%s\n", (int)fdstat.st_size, ifilstr);
420 } else {
421 ROSH_DEBUG("PATH '%s' is some other file\n", ifilstr);
422 printf(" :%s\n", ifilstr);
424 } else {
425 #ifdef __COM32__
426 if (filestr[strlen(filestr) - 1] == SEP) {
427 /* Directory */
428 filepos = 0;
429 d = opendir(filestr);
430 if (d != NULL) {
431 printf("DIR:'%s' %8d %8d\n", d->dd_name, d->dd_fd,
432 d->dd_sect);
433 de = readdir(d);
434 while (de != NULL) {
435 filepos++;
436 #ifdef DO_DEBUG
437 // if (strlen(de->d_name) > 25) de->d_name[25] = 0;
438 switch (de->d_mode) {
439 case 16:
440 ty = 'D';
441 break;
442 case 32:
443 ty = 'F';
444 break;
445 default:
446 ty = '*';
448 printf("@%8d:%8d:%4d ", (int)de->d_ino, (int)de->d_size,
449 de->d_mode);
450 #endif /* DO_DEBUG */
451 // printf("%s\n", de->d_name);
452 printf("'%s'\n", de->d_name);
453 #ifdef DO_DEBUG
454 // inchar = fgetc(stdin);
455 // fgets(instr, ROSH_CMD_SZ, stdin);
456 #endif /* DO_DEBUG */
457 free(de);
458 de = readdir(d);
459 // if(filepos>15){ de = NULL; printf("Force Break\n");}
461 printf("Dir.dd_fd: '%8d'\n", d->dd_fd);
462 closedir(d);
463 } else {
464 rosh_error(0, "dir:NULL", filestr);
466 } else {
467 rosh_error(errno, "dir_c32", filestr);
469 #else
470 rosh_error(errno, "dir", filestr);
471 #endif /* __COM32__ */
473 } /* rosh_dir_arg */
475 /* Simple directory listing based on cmdstr and pwdstr
476 * cmdstr command string to process
477 * pwdstr Present Working Directory string
479 void rosh_dir(const char *cmdstr, const char *pwdstr)
481 char filestr[ROSH_PATH_SZ + 1];
482 int cmdpos; /* Position within cmdstr */
484 ROSH_DEBUG("CMD: '%s'\npwd: '%s'\n", cmdstr, pwdstr);
485 /* Initialization */
486 filestr[0] = 0;
487 cmdpos = 0;
488 /* skip the first word */
489 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
490 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
491 /* If there are no real arguments, substitute PWD */
492 if (strlen(filestr) == 0)
493 strcpy(filestr, pwdstr);
494 while (strlen(filestr) > 0) {
495 rosh_dir_arg(filestr, pwdstr);
496 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
498 } /* rosh_dir */
500 /* List Directory; Calls rosh_dir() for now.
501 * cmdstr command string to process
502 * pwdstr Present Working Directory string
504 void rosh_ls(const char *cmdstr, const char *pwdstr)
506 printf(" ls implemented as dir (for now)\n");
507 rosh_dir(cmdstr, pwdstr);
508 } /* rosh_ls */
510 /* Page through a buffer string
511 * buf Buffer to page through
513 void rosh_more_buf(char *buf, int buflen, int rows, int cols)
515 char *bufp, *bufeol; /* Pointer to current and next end-of-line
516 position in buffer */
517 int bufpos, bufcnt; /* current position, count characters */
518 char scrbuf[ROSH_SBUF_SZ];
519 int inc;
520 int i, numln; /* Index, Number of lines */
522 bufpos = 0;
523 bufp = buf + bufpos;
524 bufeol = bufp;
525 numln = rows - 1;
526 printf("--(%d)\n", buflen);
527 // printf("--termIOS CONSTS: ");
528 // printf("ISIG=%08X ", ISIG);
529 // printf("ICANON=%08X ", ICANON);
530 // printf("ECHO=%08X ", ECHO);
531 // printf("=%08X", );
532 // printf("\n");
533 while (bufpos < buflen) {
534 for (i = 0; i < numln; i++) {
535 bufeol = strchr(bufeol, '\n');
536 if (bufeol == NULL) {
537 bufeol = buf + buflen;
538 i = numln;
539 } else {
540 bufeol++;
542 // printf("--readln\n");
544 bufcnt = bufeol - bufp;
545 printf("--(%d/%d @%d)\n", bufcnt, buflen, bufpos);
546 memcpy(scrbuf, bufp, bufcnt);
547 scrbuf[bufcnt] = 0;
548 printf("%s", scrbuf);
549 bufp = bufeol;
550 bufpos += bufcnt;
551 if (bufpos == buflen)
552 break;
553 inc = rosh_getkey();
554 numln = 1;
555 switch (inc) {
556 case KEY_CTRL('c'):
557 case 'q':
558 case 'Q':
559 bufpos = buflen;
560 break;
561 case ' ':
562 numln = rows - 1;
563 // default:
566 /*tcgetattr(0, &tio);
567 rosh_print_tc(&tio);
568 printf("\n--END\n");*/
569 } /* rosh_more_buf */
571 /* Page through a single file using the open file stream
572 * fd File Descriptor
574 void rosh_more_fd(int fd, int rows, int cols)
576 struct stat fdstat;
577 int status;
578 char *buf;
579 int bufpos;
580 int numrd;
581 FILE *f;
583 status = fstat(fd, &fdstat);
584 if (S_ISREG(fdstat.st_mode)) {
585 buf = malloc((int)fdstat.st_size);
586 if (buf != NULL) {
587 f = fdopen(fd, "r");
588 bufpos = 0;
589 numrd = fread(buf, 1, (int)fdstat.st_size, f);
590 while (numrd > 0) {
591 bufpos += numrd;
592 numrd = fread(buf + bufpos, 1,
593 ((int)fdstat.st_size - bufpos), f);
595 fclose(f);
596 rosh_more_buf(buf, bufpos, rows, cols);
598 } else {
601 } /* rosh_more_fd */
603 /* Page through a file like the more command
604 * cmdstr command string to process
605 * pwdstr Present Working Directory string
606 * ipwdstr Initial PWD
608 void rosh_more(const char *cmdstr, const char *pwdstr)
609 /*, const char *ipwdstr) */
611 int fd;
612 char filestr[ROSH_PATH_SZ + 1];
613 int cmdpos;
614 int rows, cols;
616 ROSH_DEBUG("CMD: '%s'\npwd: '%s'\n", cmdstr, pwdstr);
617 /* Initialization */
618 filestr[0] = 0;
619 cmdpos = 0;
620 if (getscreensize(1, &rows, &cols)) {
621 ROSH_DEBUG("getscreensize() fail; fall back\n");
622 ROSH_DEBUG("\tROWS='%d'\tCOLS='%d'\n", rows, cols);
623 /* If either fail, go under normal size, just in case */
624 if (!rows)
625 rows = 20;
626 if (!cols)
627 cols = 75;
629 ROSH_DEBUG("\tROWS='%d'\tCOLS='%d'\n", rows, cols);
631 /* skip the first word */
632 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
633 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
634 if (strlen(filestr) > 0) {
635 /* There is no need to mess up the console if we don't have a
636 file */
637 rosh_console_raw();
638 while (strlen(filestr) > 0) {
639 printf("--File = '%s'\n", filestr);
640 fd = open(filestr, O_RDONLY);
641 if (fd != -1) {
642 rosh_more_fd(fd, rows, cols);
643 close(fd);
644 } else {
645 rosh_error(errno, "more", filestr);
647 cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
649 rosh_console_std();
651 } /* rosh_more */
653 /* Page a file with rewind
654 * cmdstr command string to process
655 * pwdstr Present Working Directory string
656 * ipwdstr Initial PWD
658 void rosh_less(const char *cmdstr, const char *pwdstr)
660 printf(" less implemented as more (for now)\n");
661 rosh_more(cmdstr, pwdstr);
662 } /* rosh_less */
664 /* Show PWD
665 * cmdstr command string to process
666 * pwdstr Present Working Directory string
668 void rosh_pwd(const char *cmdstr, const char *pwdstr)
670 int istr;
671 ROSH_DEBUG("CMD: '%s'\npwd: '%s'\n", cmdstr, pwdstr);
672 printf("%s\n", pwdstr);
673 istr = htonl(*(int *)pwdstr);
674 ROSH_DEBUG(" --%08X\n", istr);
675 } /* rosh_pwd */
677 /* Run a boot string, calling syslinux_run_command
678 * cmdstr command string to process
679 * pwdstr Present Working Directory string
680 * ipwdstr Initial PWD
682 void rosh_run(const char *cmdstr, const char *pwdstr, const char *ipwdstr)
684 int cmdpos;
685 char *cmdptr;
686 char istr[ROSH_CMD_SZ]; /* input command string */
688 cmdpos = 0;
689 ROSH_DEBUG("CMD: '%s'\npwd: '%s'\n", cmdstr, pwdstr);
690 /* skip the first word */
691 cmdpos = rosh_search_sp(cmdstr, cmdpos);
692 /* skip spaces */
693 cmdpos = rosh_search_nonsp(cmdstr, cmdpos);
694 cmdptr = (char *)(cmdstr + cmdpos);
695 printf("--run: '%s'\n", cmdptr);
696 /* //HERE--Reparse if pwdstr != ipwdstr; seems a little daunting as
697 detecting params vs filenames is difficult/impossible */
698 if (strcmp(pwdstr, ipwdstr) != 0) {
699 /* For now, just prompt for verification */
700 printf(" from directory '%s'? (y/N):", pwdstr);
701 fgets(istr, ROSH_CMD_SZ, stdin);
702 if ((istr[0] != 'y') && (istr[0] != 'Y')) {
703 printf("Aborting run\n");
704 return;
706 printf("Run anyways\n");
708 syslinux_run_command(cmdptr);
709 } /* rosh_run */
711 /* Process a single command string and call handling function
712 * cmdstr command string to process
713 * pwdstr Present Working Directory string
714 * ipwdstr Initial Present Working Directory string
715 * returns Whether to exit prompt
717 char rosh_command(const char *cmdstr, char *pwdstr, const char *ipwdstr)
719 char do_exit;
720 do_exit = false;
721 ROSH_DEBUG("--cmd:'%s'\n", cmdstr);
722 switch (cmdstr[0]) {
723 case 'e':
724 case 'E':
725 case 'q':
726 case 'Q':
727 do_exit = true;
728 break;
729 case 'c':
730 case 'C': /* run 'cd' 'cat' 'cfg' */
731 switch (cmdstr[1]) {
732 case 'a':
733 case 'A':
734 rosh_cat(cmdstr, pwdstr);
735 break;
736 case 'd':
737 case 'D':
738 rosh_cd(cmdstr, pwdstr, ipwdstr);
739 break;
740 case 'f':
741 case 'F':
742 rosh_cfg(cmdstr, pwdstr);
743 break;
744 default:
745 rosh_help(1);
747 break;
748 case 'd':
749 case 'D': /* run 'dir' */
750 rosh_dir(cmdstr, pwdstr);
751 break;
752 case 'h':
753 case 'H':
754 case '?':
755 rosh_help(2);
756 break;
757 case 'l':
758 case 'L': /* run 'ls' 'less' */
759 switch (cmdstr[1]) {
760 case 0:
761 case 's':
762 case 'S':
763 rosh_ls(cmdstr, pwdstr);
764 break;
765 case 'e':
766 case 'E':
767 rosh_less(cmdstr, pwdstr);
768 break;
769 default:
770 rosh_help(1);
772 break;
773 case 'm':
774 case 'M':
775 switch (cmdstr[1]) {
776 case 'a':
777 case 'A':
778 rosh_help(2);
779 break;
780 case 'o':
781 case 'O':
782 rosh_more(cmdstr, pwdstr);
783 break;
784 default:
785 rosh_help(1);
787 break;
788 case 'p':
789 case 'P': /* run 'pwd' */
790 rosh_pwd(cmdstr, pwdstr);
791 break;
792 case 'r':
793 case 'R': /* run 'run' */
794 rosh_run(cmdstr, pwdstr, ipwdstr);
795 break;
796 case 'v':
797 case 'V':
798 rosh_version();
799 break;
800 case 0:
801 case '\n':
802 break;
803 default:
804 rosh_help(1);
805 } /* switch(cmdstr[0]) */
806 return do_exit;
807 } /* rosh_command */
809 /* Process the prompt for commands as read from stdin and call rosh_command
810 * to process command line string
811 * icmdstr Initial command line string
812 * returns Exit status
814 int rosh_prompt(const char *icmdstr)
816 int rv;
817 char cmdstr[ROSH_CMD_SZ];
818 char pwdstr[ROSH_PATH_SZ + 1], ipwdstr[ROSH_PATH_SZ + 1];
819 /* int numchar;
820 */ char do_exit;
821 char *c;
823 rv = 0;
824 do_exit = false;
825 strcpy(pwdstr, "/");
826 getcwd(pwdstr, ROSH_PATH_SZ + 1);
827 strcpy(ipwdstr, pwdstr); /* Retain the original PWD */
828 if (icmdstr[0] != '\0')
829 do_exit = rosh_command(icmdstr, pwdstr, ipwdstr);
830 while (!(do_exit)) {
831 console_ansi_std();
832 printf("\nrosh: ");
833 /* Read a line from console */
834 fgets(cmdstr, ROSH_CMD_SZ, stdin);
835 /* remove newline from input string */
836 c = strchr(cmdstr, '\n');
837 *c = 0;
838 do_exit = rosh_command(cmdstr, pwdstr, ipwdstr);
840 if (strcmp(pwdstr, ipwdstr) != 0) {
841 /* Change directory to the original directory */
842 strcpy(cmdstr, "cd ");
843 strcpy(cmdstr + 3, ipwdstr);
844 rosh_cd(cmdstr, pwdstr, ipwdstr);
846 return rv;
849 int main(int argc, char *argv[])
851 int rv;
852 char cmdstr[ROSH_CMD_SZ];
854 /* Initialization */
855 rv = 0;
856 console_ansi_std();
857 // console_ansi_raw();
858 if (argc != 1) {
859 rv = rosh_argcat(cmdstr, argc, argv, 1);
860 } else {
861 rosh_version();
862 cmdstr[0] = '\0';
864 rv = rosh_prompt(cmdstr);
865 printf("--Exiting '%s'\n", APP_NAME);
866 console_ansi_std();
867 return rv;