1 /* ----------------------------------------------------------------------- *
3 * Copyright 2008-2011 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 * ----------------------------------------------------------------------- */
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.
23 * prompt: Allow left/right arrow, home/end and more?
24 * commands Break into argv/argc-like array
25 * rosh_cfg: allow -s <file> to change config
26 * rosh_ls(): sorted; then multiple columns
27 * prompt: Possibly honor timeout on initial entry for usage as UI
28 * Also possibly honor totaltimeout
33 /* Uncomment the above line for debugging output; Comment to remove */
36 /* Uncomment the above line for super-debugging output; Must have regular
37 * debugging enabled; Comment to remove.
42 #define APP_LONGNAME "Read-Only Shell"
43 #define APP_NAME "rosh"
44 #define APP_AUTHOR "Gene Cumm"
45 #define APP_YEAR "2010"
46 #define APP_VER "beta-b090"
48 /* Print version information to stdout
50 void rosh_version(int vtype
)
54 printf("%s v %s; (c) %s %s.\n\tFrom Syslinux %s, %s\n", APP_LONGNAME
, APP_VER
, APP_YEAR
, APP_AUTHOR
, VERSION_STR
, DATE
);
57 rosh_get_env_ver(env
, 256);
58 printf("\tRunning on %s\n", env
);
62 /* Print beta message and if DO_DEBUG/DO_DEBUG2 are active
67 ROSH_DEBUG("DO_DEBUG active\n");
68 ROSH_DEBUG2("DO_DEBUG2 active\n");
71 /* Search a string for first non-space (' ') character, starting at ipos
72 * istr input string to parse
73 * ipos input position to start at
75 int rosh_search_nonsp(const char *istr
, const int ipos
)
82 while (c
&& isspace(c
))
87 /* Search a string for space (' '), returning the position of the next space
88 * or the '\0' at end of string
89 * istr input string to parse
90 * ipos input position to start at
92 int rosh_search_sp(const char *istr
, const int ipos
)
99 while (c
&& !(isspace(c
)))
104 /* Parse a string for the first non-space string, returning the end position
106 * dest string to contain the first non-space string
107 * src string to parse
108 * ipos Position to start in src
110 int rosh_parse_sp_1(char *dest
, const char *src
, const int ipos
)
112 int bpos
, epos
; /* beginning and ending position of source string
113 to copy to destination string */
117 /* //HERE-error condition checking */
118 bpos
= rosh_search_nonsp(src
, ipos
);
119 epos
= rosh_search_sp(src
, bpos
);
121 memcpy(dest
, src
+ bpos
, epos
- bpos
);
122 if (dest
[epos
- bpos
] != 0)
123 dest
[epos
- bpos
] = 0;
132 * parse_args1: Try 1 at parsing a string to an argc/argv pair. use free_args1 to free memory malloc'd
134 * Derived from com32/lib/sys/argv.c:__parse_argv()
135 * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
136 * Copyright 2009 Intel Corporation; author: H. Peter Anvin
138 int parse_args1(char ***iargv
, const char *istr
)
142 char *q
, *r
, *args
, **arg
;
143 int sp
= 1; //, qt = 0; /* Was a space; inside a quote */
146 /* I could eliminate this if I knew a max length, like strncpy() */
147 int len
= strlen(istr
);
149 /* Scan 2: Copy, nullify and make argc */
150 if (!(args
= malloc(len
+ 1)))
153 for (p
= istr
;; p
++) {
170 q
--; /* Point q to final null */
171 /* Scan 3: Build array of pointers */
172 if (!(*iargv
= malloc((argc
+ 1) * sizeof(char *))))
175 arg
[argc
] = NULL
; /* Nullify the last pointer */
178 for (r
= args
; r
< q
; r
++) {
191 /* Free argv created by parse_args1()
192 * argv Argument Values
194 void free_args1(char ***argv
)
202 /* Convert a string to an argc/argv pair
203 * str String to parse
204 * argv Argument Values
205 * returns Argument Count
207 int rosh_str2argv(char ***argv
, const char *str
)
209 return parse_args1(argv
, str
);
212 /* Free an argv created by rosh_str2argv()
213 * argv Argument Values to free
215 void rosh_free_argv(char ***argv
)
220 /* Print the contents of an argc/argv pair
221 * argc Argument Count
222 * argv Argument Values
224 void rosh_pr_argv(int argc
, char *argv
[])
227 for (i
= 0; i
< argc
; i
++) {
228 printf("%s%s", argv
[i
], (i
< argc
)? " " : "");
233 /* Print the contents of an argc/argv pair verbosely
234 * argc Argument Count
235 * argv Argument Values
237 void rosh_pr_argv_v(int argc
, char *argv
[])
240 for (i
= 0; i
< argc
; i
++) {
241 printf("%4d '%s'\n", i
, argv
[i
]);
245 /* Reset the getopt() environment
247 void rosh_getopt_reset(void)
255 * cmdstr Command for which help is requested
257 void rosh_help(int type
, const char *cmdstr
)
261 if ((cmdstr
== NULL
) || (strcmp(cmdstr
, "") == 0)) {
263 puts(rosh_help_str2
);
267 puts(rosh_help_cd_str
);
270 puts(rosh_help_ls_str
);
273 printf(rosh_help_str_adv
, cmdstr
);
280 printf("%s: %s: unknown command\n", APP_NAME
, cmdstr
);
282 puts(rosh_help_str1
);
286 /* Handle most/all errors
287 * ierrno Input Error number
288 * cmdstr Command being executed to cause error
289 * filestr File/parameter causing error
291 void rosh_error(const int ierrno
, const char *cmdstr
, const char *filestr
)
293 printf("--ERROR: %s '%s': ", cmdstr
, filestr
);
300 /* SYSLinux-3.72 COM32 API returns this for a
301 directory or empty file */
302 ROSH_COM32(" (COM32) could be a directory or empty file\n");
308 puts("Bad File Descriptor");
311 puts("Access DENIED");
314 puts("not a directory");
315 ROSH_COM32(" (COM32) could be directory\n");
318 puts("IS a directory");
321 puts("not implemented");
324 printf("returns error; errno=%d\n", ierrno
);
328 /* Concatenate command line arguments into one string
329 * cmdstr Output command string
330 * cmdlen Length of cmdstr
331 * argc Argument Count
332 * argv Argument Values
333 * barg Beginning Argument
335 int rosh_argcat(char *cmdstr
, const int cmdlen
, const int argc
, char *argv
[],
338 int i
, arglen
, curpos
; /* index, argument length, current position
341 cmdstr
[0] = '\0'; /* Nullify string just to be sure */
342 for (i
= barg
; i
< argc
; i
++) {
343 arglen
= strlen(argv
[i
]);
344 /* Theoretically, this should never be met in SYSLINUX */
345 if ((curpos
+ arglen
) > (cmdlen
- 1))
346 arglen
= (cmdlen
- 1) - curpos
;
347 memcpy(cmdstr
+ curpos
, argv
[i
], arglen
);
349 if (curpos
>= (cmdlen
- 1)) {
350 /* Hopefully, curpos should not be greater than
352 /* Still need a '\0' at the last character */
353 cmdstr
[(cmdlen
- 1)] = 0;
354 break; /* Escape out of the for() loop;
355 We can no longer process anything more */
357 cmdstr
[curpos
] = ' ';
362 /* If there's a ' ' at the end, remove it. This is normal unless
363 the maximum length is met/exceeded. */
364 if (cmdstr
[curpos
- 1] == ' ')
365 cmdstr
[--curpos
] = 0;
370 * Prints a lot of the data in a struct termios
373 void rosh_print_tc(struct termios *tio)
375 printf(" -- termios: ");
376 printf(".c_iflag=%04X ", tio->c_iflag);
377 printf(".c_oflag=%04X ", tio->c_oflag);
378 printf(".c_cflag=%04X ", tio->c_cflag);
379 printf(".c_lflag=%04X ", tio->c_lflag);
380 printf(".c_cc[VTIME]='%d' ", tio->c_cc[VTIME]);
381 printf(".c_cc[VMIN]='%d'", tio->c_cc[VMIN]);
387 * Attempts to get a single key from the console
388 * returns key pressed
390 int rosh_getkey(void)
395 while (inc
== KEY_NONE
)
396 inc
= get_key(stdin
, 6000);
401 * Qualifies a filename relative to the working directory
402 * filestr Filename to qualify
403 * pwdstr working directory
404 * returns qualified file name string
406 void rosh_qualify_filestr(char *filestr
, const char *ifilstr
,
410 if ((filestr
) && (pwdstr
) && (ifilstr
)) {
411 if (ifilstr
[0] != SEP
) {
412 strcpy(filestr
, pwdstr
);
413 filepos
= strlen(pwdstr
);
414 if (filestr
[filepos
- 1] != SEP
)
415 filestr
[filepos
++] = SEP
;
417 strcpy(filestr
+ filepos
, ifilstr
);
418 ROSH_DEBUG("--'%s'\n", filestr
);
422 /* Concatenate multiple files to stdout
423 * argc Argument Count
424 * argv Argument Values
426 void rosh_cat(int argc
, char *argv
[])
429 char buf
[ROSH_BUF_SZ
];
432 for (i
= 0; i
< argc
; i
++) {
433 printf("--File = '%s'\n", argv
[i
]);
435 f
= fopen(argv
[i
], "r");
437 numrd
= fread(buf
, 1, ROSH_BUF_SZ
, f
);
439 fwrite(buf
, 1, numrd
, stdout
);
440 numrd
= fread(buf
, 1, ROSH_BUF_SZ
, f
);
444 rosh_error(errno
, "cat", argv
[i
]);
450 /* Change PWD (Present Working Directory)
451 * argc Argument count
452 * argv Argument values
453 * ipwdstr Initial PWD
455 void rosh_cd(int argc
, char *argv
[], const char *ipwdstr
)
459 char filestr
[ROSH_PATH_SZ
];
460 #endif /* DO_DEBUG */
461 ROSH_DEBUG("CMD: \n");
462 ROSH_DEBUG_ARGV_V(argc
, argv
);
469 rosh_help(2, argv
[0]);
472 rosh_error(errno
, "cd", argv
[1]);
474 rosh_error(errno
, "cd", ipwdstr
);
478 if (getcwd(filestr
, ROSH_PATH_SZ
))
479 ROSH_DEBUG(" %s\n", filestr
);
480 #endif /* DO_DEBUG */
484 /* Print the syslinux config file name
488 printf("CFG: '%s'\n", syslinux_config_file());
491 /* Echo a string back to the screen
492 * cmdstr command string to process
494 void rosh_echo(const char *cmdstr
)
497 ROSH_DEBUG("CMD: '%s'\n", cmdstr
);
498 bpos
= rosh_search_nonsp(cmdstr
, rosh_search_sp(cmdstr
, 0));
500 ROSH_DEBUG(" bpos=%d\n", bpos
);
501 printf("'%s'\n", cmdstr
+ bpos
);
507 /* Process argc/argv to optarr
508 * argc Argument count
509 * argv Argument values
510 * optarr option array to populate
512 void rosh_ls_arg_opt(int argc
, char *argv
[], int optarr
[])
521 ROSH_DEBUG2("getopt optind=%d rv=%d\n", optind
, rv
);
522 rv
= getopt(argc
, argv
, rosh_ls_opt_str
);
539 ROSH_DEBUG2("getopt optind=%d rv=%d\n", optind
, rv
);
543 ROSH_DEBUG2(" end getopt optind=%d rv=%d\n", optind
, rv
);
544 ROSH_DEBUG2("\tIn rosh_ls_arg_opt() opt[0]=%d\topt[1]=%d\topt[2]=%d\n", optarr
[0], optarr
[1],
546 } /* rosh_ls_arg_opt */
548 /* Retrieve the size of a file argument
549 * filestr directory name of directory entry
552 int rosh_ls_de_size(const char *filestr
, struct dirent
*de
)
555 char filestr2
[ROSH_PATH_SZ
];
562 file2pos
= strlen(filestr
);
563 memcpy(filestr2
, filestr
, file2pos
);
564 filestr2
[file2pos
] = '/';
566 strcpy(filestr2
+ file2pos
+ 1, de
->d_name
);
567 fd2
= open(filestr2
, O_RDONLY
);
570 de_size
= (int)fdstat
.st_size
;
572 } /* rosh_ls_de_size */
574 /* Retrieve the size and mode of a file
575 * filestr directory name of directory entry
578 int rosh_ls_de_size_mode(const char *filestr
, struct dirent
*de
, mode_t
* st_mode
)
581 char filestr2
[ROSH_PATH_SZ
];
588 memset(&fdstat
, 0, sizeof fdstat
);
589 ROSH_DEBUG2("ls:dsm(%s, %s) ", filestr
, de
->d_name
);
591 /* FIXME: prevent string overflow */
592 file2pos
= strlen(filestr
);
593 memcpy(filestr2
, filestr
, file2pos
);
594 if (( filestr2
[file2pos
- 1] == SEP
)) {
597 filestr2
[file2pos
] = SEP
;
600 strcpy(filestr2
+ file2pos
+ 1, de
->d_name
);
602 ROSH_DEBUG2("stat(%s) ", filestr2
);
603 status
= stat(filestr2
, &fdstat
);
605 ROSH_DEBUG2("\t--stat()=%d\terr=%d\n", status
, errno
);
607 rosh_error(errno
, "ls:szmd.stat", de
->d_name
);
610 de_size
= (int)fdstat
.st_size
;
611 *st_mode
= fdstat
.st_mode
;
613 } /* rosh_ls_de_size_mode */
615 /* Returns the Inode number if fdstat contains it
616 * fdstat struct to extract inode from if not COM32, for now
618 long rosh_ls_d_ino(struct stat
*fdstat
)
626 #else /* __COM32__ */
627 de_ino
= fdstat
->st_ino
;
628 #endif /* __COM32__ */
632 /* Convert a d_type to a single char in human readable format
633 * d_type d_type to convert
634 * returns human readable single character; a space if other
636 char rosh_d_type2char_human(unsigned char d_type
)
648 break; /* Char Dev */
651 break; /* Directory */
654 break; /* Block Dev */
657 break; /* Regular File */
660 break; /* Link, Symbolic */
666 break; /* UnionFS Whiteout */
671 } /* rosh_d_type2char_human */
673 /* Convert a d_type to a single char by ls's prefix standards for -l
674 * d_type d_type to convert
675 * returns ls style single character; a space if other
677 char rosh_d_type2char_lspre(unsigned char d_type
)
706 } /* rosh_d_type2char_lspre */
708 /* Convert a d_type to a single char by ls's classify (-F) suffix standards
709 * d_type d_type to convert
710 * returns ls style single character; a space if other
712 char rosh_d_type2char_lssuf(unsigned char d_type
)
732 } /* rosh_d_type2char_lssuf */
734 /* Converts data in the "other" place of st_mode to a ls-style string
735 * st_mode Mode in other to analyze
736 * st_mode_str string to hold converted string
738 void rosh_st_mode_am2str(mode_t st_mode
, char *st_mode_str
)
740 st_mode_str
[0] = ((st_mode
& S_IROTH
) ? 'r' : '-');
741 st_mode_str
[1] = ((st_mode
& S_IWOTH
) ? 'w' : '-');
742 st_mode_str
[2] = ((st_mode
& S_IXOTH
) ? 'x' : '-');
745 /* Converts st_mode to an ls-style string
746 * st_mode mode to convert
747 * st_mode_str string to hold converted string
749 void rosh_st_mode2str(mode_t st_mode
, char *st_mode_str
)
751 st_mode_str
[0] = rosh_d_type2char_lspre(IFTODT(st_mode
));
752 rosh_st_mode_am2str((st_mode
& S_IRWXU
) >> 6, st_mode_str
+ 1);
753 rosh_st_mode_am2str((st_mode
& S_IRWXG
) >> 3, st_mode_str
+ 4);
754 rosh_st_mode_am2str(st_mode
& S_IRWXO
, st_mode_str
+ 7);
756 } /* rosh_st_mode2str */
758 /* Output a single entry
759 * filestr directory name to list
761 * optarr Array of options
763 void rosh_ls_arg_dir_de(const char *filestr
, struct dirent
*de
, const int *optarr
)
767 char st_mode_str
[11];
771 printf("%10d ", (int)(de
->d_ino
));
772 if (optarr
[0] > -1) {
773 de_size
= rosh_ls_de_size_mode(filestr
, de
, &st_mode
);
774 rosh_st_mode2str(st_mode
, st_mode_str
);
775 ROSH_DEBUG2("%04X ", st_mode
);
776 printf("%s %10d ", st_mode_str
, de_size
);
779 printf("%s", de
->d_name
);
782 printf("%c", rosh_d_type2char_lssuf(de
->d_type
));
784 } /* rosh_ls_arg_dir_de */
786 /* Output listing of a regular directory
787 * filestr directory name to list
789 * optarr Array of options
790 NOTE:This is where I could use qsort
792 void rosh_ls_arg_dir(const char *filestr
, DIR * d
, const int *optarr
)
799 while ((de
= readdir(d
))) {
801 rosh_ls_arg_dir_de(filestr
, de
, optarr
);
804 rosh_error(errno
, "ls:arg_dir", filestr
);
806 } else { if (filepos
== 0)
807 ROSH_DEBUG("0 files found");
809 } /* rosh_ls_arg_dir */
811 /* Simple directory listing for one argument (file/directory) based on
813 * ifilstr input filename/directory name to list
814 * pwdstr Present Working Directory string
815 * optarr Option Array
817 void rosh_ls_arg(const char *filestr
, const int *optarr
)
821 // char filestr[ROSH_PATH_SZ];
826 /* Initialization; make filestr based on leading character of ifilstr
828 // rosh_qualify_filestr(filestr, ifilstr, pwdstr);
831 ROSH_DEBUG("\topt[0]=%d\topt[1]=%d\topt[2]=%d\n", optarr
[0], optarr
[1],
834 /* Now, the real work */
836 status
= stat(filestr
, &fdstat
);
838 if (S_ISDIR(fdstat
.st_mode
)) {
839 ROSH_DEBUG("PATH '%s' is a directory\n", filestr
);
840 if ((d
= opendir(filestr
))) {
841 rosh_ls_arg_dir(filestr
, d
, optarr
);
844 rosh_error(errno
, "ls", filestr
);
848 de
.d_ino
= rosh_ls_d_ino(&fdstat
);
849 de
.d_type
= (IFTODT(fdstat
.st_mode
));
850 strcpy(de
.d_name
, filestr
);
851 if (S_ISREG(fdstat
.st_mode
)) {
852 ROSH_DEBUG("PATH '%s' is a regular file\n", filestr
);
854 ROSH_DEBUG("PATH '%s' is some other file\n", filestr
);
856 rosh_ls_arg_dir_de(NULL
, &de
, optarr
);
857 /* if (ifilstr[0] == SEP)
858 rosh_ls_arg_dir_de(NULL, &de, optarr);
860 rosh_ls_arg_dir_de(pwdstr, &de, optarr);*/
863 rosh_error(errno
, "ls", filestr
);
869 /* Parse options that may be present in the cmdstr
870 * filestr Possible option string to parse
871 * optstr Current options
872 * returns 1 if filestr does not begin with '-' else 0
874 int rosh_ls_parse_opt(const char *filestr
, char *optstr
)
877 if (filestr
[0] == '-') {
880 strcat(optstr
, filestr
+ 1);
884 ROSH_DEBUG("ParseOpt: '%s'\n\topt: '%s'\n\tret: %d\n", filestr
, optstr
,
887 } /* rosh_ls_parse_opt */
890 * argc Argument count
891 * argv Argument values
893 void rosh_ls(int argc
, char *argv
[])
898 rosh_ls_arg_opt(argc
, argv
, optarr
);
899 ROSH_DEBUG2("In ls()\n");
900 ROSH_DEBUG2_ARGV_V(argc
, argv
);
903 #endif /* DO_DEBUG */
904 ROSH_DEBUG2(" argc=%d; optind=%d\n", argc
, optind
);
906 rosh_ls_arg(".", optarr
);
907 for (i
= optind
; i
< argc
; i
++) {
908 rosh_ls_arg(argv
[i
], optarr
);
912 /* Simple directory listing; calls rosh_ls()
913 * argc Argument count
914 * argv Argument values
916 void rosh_dir(int argc
, char *argv
[])
918 ROSH_DEBUG(" dir implemented as ls\n");
922 /* Page through a buffer string
923 * buf Buffer to page through
925 void rosh_more_buf(char *buf
, int buflen
, int rows
, int cols
, char *scrbuf
)
927 char *bufp
, *bufeol
, *bufeol2
; /* Pointer to current and next
928 end-of-line position in buffer */
929 int bufpos
, bufcnt
; /* current position, count characters */
931 int i
, numln
; /* Index, Number of lines */
932 int elpl
; /* Extra lines per line read */
940 ROSH_DEBUG("--(%d)\n", buflen
);
941 while (bufpos
< buflen
) {
942 for (i
= 0; i
< numln
; i
++) {
943 bufeol2
= strchr(bufeol
, '\n');
944 if (bufeol2
== NULL
) {
945 bufeol
= buf
+ buflen
;
948 elpl
= ((bufeol2
- bufeol
- 1) / cols
);
952 ROSH_DEBUG2(" %d/%d ", elpl
, i
+1);
953 /* If this will not push too much, use it */
954 /* but if it's the first line, use it */
955 /* //HERE: We should probably snip the line off */
956 if ((i
< numln
) || (i
== elpl
))
957 bufeol
= bufeol2
+ 1;
961 bufcnt
= bufeol
- bufp
;
962 printf("--(%d/%d @%d)\n", bufcnt
, buflen
, bufpos
);
963 memcpy(scrbuf
, bufp
, bufcnt
);
965 printf("%s", scrbuf
);
968 if (bufpos
== buflen
)
982 } /* rosh_more_buf */
984 /* Page through a single file using the open file stream
987 void rosh_more_fd(int fd
, int rows
, int cols
, char *scrbuf
)
996 if (S_ISREG(fdstat
.st_mode
)) {
997 buf
= malloc((int)fdstat
.st_size
);
1001 numrd
= fread(buf
, 1, (int)fdstat
.st_size
, f
);
1004 numrd
= fread(buf
+ bufpos
, 1,
1005 ((int)fdstat
.st_size
- bufpos
), f
);
1008 rosh_more_buf(buf
, bufpos
, rows
, cols
, scrbuf
);
1013 } /* rosh_more_fd */
1015 /* Page through a file like the more command
1016 * argc Argument Count
1017 * argv Argument Values
1019 void rosh_more(int argc
, char *argv
[])
1022 /* char filestr[ROSH_PATH_SZ];
1028 ROSH_DEBUG_ARGV_V(argc
, argv
);
1029 ret
= getscreensize(1, &rows
, &cols
);
1031 ROSH_DEBUG("getscreensize() fail(%d); fall back\n", ret
);
1032 ROSH_DEBUG("\tROWS='%d'\tCOLS='%d'\n", rows
, cols
);
1033 /* If either fail, go under normal size, just in case */
1039 ROSH_DEBUG("\tUSE ROWS='%d'\tCOLS='%d'\n", rows
, cols
);
1040 /* 32 bit align beginning of row and over allocate */
1041 scrbuf
= malloc(rows
* ((cols
+3)&(INT_MAX
- 3)));
1046 /* There is no need to mess up the console if we don't have a
1049 for (i
= 0; i
< argc
; i
++) {
1050 printf("--File = '%s'\n", argv
[i
]);
1052 fd
= open(argv
[i
], O_RDONLY
);
1054 rosh_more_fd(fd
, rows
, cols
, scrbuf
);
1057 rosh_error(errno
, "more", argv
[i
]);
1066 /* Page a file with rewind
1067 * argc Argument Count
1068 * argv Argument Values
1070 void rosh_less(int argc
, char *argv
[])
1072 printf(" less implemented as more (for now)\n");
1073 rosh_more(argc
, argv
);
1080 char pwdstr
[ROSH_PATH_SZ
];
1082 if (getcwd(pwdstr
, ROSH_PATH_SZ
)) {
1083 printf("%s\n", pwdstr
);
1085 rosh_error(errno
, "pwd", "");
1090 /* Reboot; use warm reboot if one of certain options set
1091 * argc Argument count
1092 * argv Argument values
1094 void rosh_reboot(int argc
, char *argv
[])
1098 /* For now, just use the first */
1099 switch (argv
[0][0]) {
1106 switch (argv
[0][1]) {
1116 syslinux_reboot(rtype
);
1119 /* Run a boot string, calling syslinux_run_command
1120 * argc Argument count
1121 * argv Argument values
1123 void rosh_run(int argc
, char *argv
[])
1125 char cmdstr
[ROSH_CMD_SZ
];
1128 len
= rosh_argcat(cmdstr
, ROSH_CMD_SZ
, argc
, argv
, 0);
1130 printf("--run: '%s'\n", cmdstr
);
1131 syslinux_run_command(cmdstr
);
1133 printf(APP_NAME
":run: No arguments\n");
1137 /* Process an argc/argv pair and call handling function
1138 * argc Argument count
1139 * argv Argument values
1140 * ipwdstr Initial Present Working Directory string
1141 * returns Whether to exit prompt
1143 char rosh_command(int argc
, char *argv
[], const char *ipwdstr
)
1145 char do_exit
= false;
1147 tlen
= strlen(argv
[0]);
1148 ROSH_DEBUG_ARGV_V(argc
, argv
);
1149 switch (argv
[0][0]) {
1154 switch (argv
[0][1]) {
1160 if ((strncasecmp("exit", argv
[0], tlen
) == 0) ||
1161 (strncasecmp("quit", argv
[0], tlen
) == 0))
1164 rosh_help(1, argv
[0]);
1168 if (strncasecmp("echo", argv
[0], tlen
) == 0)
1169 rosh_pr_argv(argc
- 1, &argv
[1]);
1171 rosh_help(1, argv
[0]);
1174 rosh_help(1, argv
[0]);
1178 case 'C': /* run 'cd' 'cat' 'cfg' */
1179 switch (argv
[0][1]) {
1182 if (strncasecmp("cat", argv
[0], tlen
) == 0)
1183 rosh_cat(argc
- 1, &argv
[1]);
1185 rosh_help(1, argv
[0]);
1189 if (strncasecmp("cd", argv
[0], tlen
) == 0)
1190 rosh_cd(argc
, argv
, ipwdstr
);
1192 rosh_help(1, argv
[0]);
1196 if (strncasecmp("cfg", argv
[0], tlen
) == 0)
1199 rosh_help(1, argv
[0]);
1202 rosh_help(1, argv
[0]);
1206 case 'D': /* run 'dir' */
1207 if (strncasecmp("dir", argv
[0], tlen
) == 0)
1208 rosh_dir(argc
- 1, &argv
[1]);
1210 rosh_help(1, argv
[0]);
1215 if ((strncasecmp("help", argv
[0], tlen
) == 0) || (tlen
== 1))
1216 rosh_help(2, argv
[1]);
1221 case 'L': /* run 'ls' 'less' */
1222 switch (argv
[0][1]) {
1226 if (strncasecmp("ls", argv
[0], tlen
) == 0)
1227 rosh_ls(argc
, argv
);
1229 rosh_help(1, argv
[0]);
1233 if (strncasecmp("less", argv
[0], tlen
) == 0)
1234 rosh_less(argc
- 1, &argv
[1]);
1236 rosh_help(1, argv
[0]);
1239 rosh_help(1, argv
[0]);
1244 switch (argv
[0][1]) {
1247 if (strncasecmp("man", argv
[0], tlen
) == 0)
1248 rosh_help(2, argv
[1]);
1250 rosh_help(1, argv
[0]);
1254 if (strncasecmp("more", argv
[0], tlen
) == 0)
1255 rosh_more(argc
- 1, &argv
[1]);
1257 rosh_help(1, argv
[0]);
1260 rosh_help(1, argv
[0]);
1264 case 'P': /* run 'pwd' */
1265 if (strncasecmp("pwd", argv
[0], tlen
) == 0)
1268 rosh_help(1, argv
[0]);
1271 case 'R': /* run 'run' */
1272 switch (argv
[0][1]) {
1276 if (strncasecmp("reboot", argv
[0], tlen
) == 0)
1277 rosh_reboot(argc
- 1, &argv
[1]);
1279 rosh_help(1, argv
[0]);
1283 if (strncasecmp("run", argv
[0], tlen
) == 0)
1284 rosh_run(argc
- 1, &argv
[1]);
1286 rosh_help(1, argv
[0]);
1289 rosh_help(1, argv
[0]);
1294 if (strncasecmp("version", argv
[0], tlen
) == 0)
1297 rosh_help(1, argv
[0]);
1303 rosh_help(1, argv
[0]);
1304 } /* switch(argv[0][0]) */
1306 } /* rosh_command */
1308 /* Process the prompt for commands as read from stdin and call rosh_command
1309 * to process command line string
1310 * icmdstr Initial command line string
1311 * returns Exit status
1313 int rosh_prompt(int iargc
, char *iargv
[])
1316 char cmdstr
[ROSH_CMD_SZ
];
1317 char ipwdstr
[ROSH_PATH_SZ
];
1324 if (!getcwd(ipwdstr
, ROSH_PATH_SZ
))
1325 strcpy(ipwdstr
, "./");
1327 do_exit
= rosh_command(iargc
- 1, &iargv
[1], ipwdstr
);
1328 while (!(do_exit
)) {
1329 /* Extra preceeding newline */
1331 /* Read a line from console */
1332 if (fgets(cmdstr
, ROSH_CMD_SZ
, stdin
)) {
1333 argc
= rosh_str2argv(&argv
, cmdstr
);
1334 do_exit
= rosh_command(argc
, argv
, ipwdstr
);
1335 rosh_free_argv(&argv
);
1343 int main(int argc
, char *argv
[])
1347 /* Initialization */
1355 char cmdstr
[ROSH_CMD_SZ
];
1356 rosh_argcat(cmdstr
, ROSH_CMD_SZ
, argc
, argv
, 1);
1357 ROSH_DEBUG("arg='%s'\n", cmdstr
);
1360 rv
= rosh_prompt(argc
, argv
);
1361 printf("--Exiting '" APP_NAME
"'\n");