/* List Directory based on cmdstr and pwdstr * cmdstr command string to process * pwdstr Present Working Directory string */ void rosh_ls(const char *cmdstr) { 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]; 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); } } #ifdef DO_DEBUG if (!strchr(optstr, 'l')) strcat(optstr, "l"); #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_ls */
/* Concatenate multiple files to stdout * cmdstr command string to process */ void rosh_cat(const char *cmdstr) { FILE *f; char filestr[ROSH_PATH_SZ]; char buf[ROSH_BUF_SZ]; int numrd; int cmdpos; 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"); if (f != NULL) { numrd = fread(buf, 1, ROSH_BUF_SZ, f); while (numrd > 0) { fwrite(buf, 1, numrd, stdout); numrd = fread(buf, 1, ROSH_BUF_SZ, f); } fclose(f); } else { rosh_error(errno, "cat", filestr); errno = 0; } cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos); } } /* rosh_cat */
/* Simple directory listing for one argument (file/directory) based on * filestr and pwdstr * ifilstr input filename/directory name to list * pwdstr Present Working Directory string * optarr Option Array */ void rosh_ls_arg(const char *filestr, const int *optarr) { struct stat fdstat; int status; // char filestr[ROSH_PATH_SZ]; // int filepos; DIR *d; struct dirent de; /* Initialization; make filestr based on leading character of ifilstr and pwdstr */ // rosh_qualify_filestr(filestr, ifilstr, pwdstr); fdstat.st_mode = 0; fdstat.st_size = 0; ROSH_DEBUG("\topt[0]=%d\topt[1]=%d\topt[2]=%d\n", optarr[0], optarr[1], optarr[2]); /* Now, the real work */ errno = 0; status = stat(filestr, &fdstat); 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); } else { de.d_ino = rosh_ls_d_ino(&fdstat); de.d_type = (IFTODT(fdstat.st_mode)); strcpy(de.d_name, filestr); if (S_ISREG(fdstat.st_mode)) { ROSH_DEBUG("PATH '%s' is a regular file\n", filestr); } else { ROSH_DEBUG("PATH '%s' is some other file\n", filestr); } rosh_ls_arg_dir_de(&de, optarr); /* if (ifilstr[0] == SEP) rosh_ls_arg_dir_de(NULL, &de, optarr); else rosh_ls_arg_dir_de(pwdstr, &de, optarr);*/ } } else { rosh_error(errno, "ls", filestr); errno = 0; } return; } /* rosh_ls_arg */
/* Page through a buffer string * buf Buffer to page through */ void rosh_more_buf(char *buf, int buflen, int rows, int cols, char *scrbuf) { char *bufp, *bufeol, *bufeol2; /* Pointer to current and next end-of-line position in buffer */ int bufpos, bufcnt; /* current position, count characters */ int inc; int i, numln; /* Index, Number of lines */ int elpl; /* Extra lines per line read */ (void)cols; bufpos = 0; bufp = buf + bufpos; bufeol = bufp; numln = rows - 1; ROSH_DEBUG("--(%d)\n", buflen); while (bufpos < buflen) { for (i = 0; i < numln; i++) { bufeol2 = strchr(bufeol, '\n'); if (bufeol2 == NULL) { bufeol = buf + buflen; i = numln; } else { elpl = ((bufeol2 - bufeol - 1) / cols); if (elpl < 0) elpl = 0; i += elpl; ROSH_DEBUG2(" %d/%d ", elpl, i+1); /* If this will not push too much, use it */ /* but if it's the first line, use it */ /* //HERE: We should probably snip the line off */ if ((i < numln) || (i == elpl)) bufeol = bufeol2 + 1; } } ROSH_DEBUG2("\n"); bufcnt = bufeol - bufp; printf("--(%d/%d @%d)\n", bufcnt, buflen, bufpos); memcpy(scrbuf, bufp, bufcnt); scrbuf[bufcnt] = 0; printf("%s", scrbuf); bufp = bufeol; bufpos += bufcnt; if (bufpos == buflen) break; inc = rosh_getkey(); numln = 1; switch (inc) { case KEY_CTRL('c'): case 'q': case 'Q': bufpos = buflen; break; case ' ': numln = rows - 1; } } } /* rosh_more_buf */
/* Page through a file like the more command * cmdstr command string to process * ipwdstr Initial PWD */ void rosh_more(const char *cmdstr) { int fd; char filestr[ROSH_PATH_SZ]; int cmdpos; int rows, cols; ROSH_DEBUG("CMD: '%s'\n", cmdstr); /* Initialization */ filestr[0] = 0; cmdpos = 0; if (getscreensize(1, &rows, &cols)) { ROSH_DEBUG("getscreensize() fail; fall back\n"); ROSH_DEBUG("\tROWS='%d'\tCOLS='%d'\n", rows, cols); /* If either fail, go under normal size, just in case */ if (!rows) rows = 20; if (!cols) cols = 75; } ROSH_DEBUG("\tUSE ROWS='%d'\tCOLS='%d'\n", rows, cols); /* skip the first word */ cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos); cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos); if (strlen(filestr) > 0) { /* 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); if (fd != -1) { rosh_more_fd(fd, rows, cols); close(fd); } else { rosh_error(errno, "more", filestr); errno = 0; } cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos); } rosh_console_std(); } } /* rosh_more */
/* Output a single entry * filestr directory name to list * de directory entry * optarr Array of options */ void rosh_ls_arg_dir_de(struct dirent *de, const int *optarr) { int de_size; mode_t st_mode; char st_mode_str[11]; st_mode = 0; if (optarr[2] > -1) printf("%10d ", (int)de->d_ino); if (optarr[0] > -1) { de_size = rosh_ls_de_size_mode(de, &st_mode); rosh_st_mode2str(st_mode, st_mode_str); ROSH_DEBUG2("%04X ", st_mode); printf("%s %10d ", st_mode_str, de_size); } ROSH_DEBUG("'"); printf("%s", de->d_name); ROSH_DEBUG("'"); if (optarr[1] > -1) printf("%c", rosh_d_type2char_lssuf(de->d_type)); printf("\n"); } /* rosh_ls_arg_dir_de */
/* Parse options that may be present in the cmdstr * filestr Possible option string to parse * optstr Current options * returns 1 if filestr does not begin with '-' else 0 */ int rosh_ls_parse_opt(const char *filestr, char *optstr) { int ret; if (filestr[0] == '-') { ret = 0; if (optstr) strcat(optstr, filestr + 1); } else { ret = 1; } ROSH_DEBUG("ParseOpt: '%s'\n\topt: '%s'\n\tret: %d\n", filestr, optstr, ret); return ret; } /* rosh_ls_parse_opt */
//HERE: minor pagination issue; sometimes prints 1 less than rows void rosh_more_buf(char *buf, int buflen, int rows, int cols) { char *bufp, *bufeol, *bufeol2; /* Pointer to current and next end-of-line position in buffer */ int bufpos, bufcnt; /* current position, count characters */ char scrbuf[ROSH_SBUF_SZ]; int inc; int i, numln; /* Index, Number of lines */ (void)cols; bufpos = 0; bufp = buf + bufpos; bufeol = bufp; numln = rows - 1; ROSH_DEBUG("--(%d)\n", buflen); while (bufpos < buflen) { for (i = 0; i < numln; i++) { bufeol2 = strchr(bufeol, '\n'); if (bufeol2 == NULL) { bufeol = buf + buflen; i = numln; } else { i += ((bufeol2 - bufeol) / cols); bufeol = bufeol2 + 1; } } bufcnt = bufeol - bufp; printf("--(%d/%d @%d)\n", bufcnt, buflen, bufpos); memcpy(scrbuf, bufp, bufcnt); scrbuf[bufcnt] = 0; printf("%s", scrbuf); bufp = bufeol; bufpos += bufcnt; if (bufpos == buflen) break; inc = rosh_getkey(); numln = 1; switch (inc) { case KEY_CTRL('c'): case 'q': case 'Q': bufpos = buflen; break; case ' ': numln = rows - 1; } } } /* rosh_more_buf */
/* Run a boot string, calling syslinux_run_command * cmdstr command string to process */ void rosh_run(const char *cmdstr) { int cmdpos; char *cmdptr; 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); } /* rosh_run */
/* Output listing of a regular directory * filestr directory name to list * d the open DIR * optarr Array of options NOTE:This is where I could use qsort */ void rosh_ls_arg_dir(const char *filestr, DIR * d, const int *optarr) { struct dirent *de; int filepos; filepos = 0; while ((de = readdir(d))) { filepos++; rosh_ls_arg_dir_de(de, optarr); } if (errno) rosh_error(errno, "ls:arg_dir", filestr); else if (filepos == 0) ROSH_DEBUG("0 files found"); } /* rosh_ls_arg_dir */
/* * Qualifies a filename relative to the working directory * filestr Filename to qualify * pwdstr working directory * returns qualified file name string */ void rosh_qualify_filestr(char *filestr, const char *ifilstr, const char *pwdstr) { int filepos = 0; if ((filestr) && (pwdstr) && (ifilstr)) { if (ifilstr[0] != SEP) { strcpy(filestr, pwdstr); filepos = strlen(pwdstr); if (filestr[filepos - 1] != SEP) filestr[filepos++] = SEP; } strcpy(filestr + filepos, ifilstr); ROSH_DEBUG("--'%s'\n", filestr); } }
/* Show PWD * cmdstr command string to process */ void rosh_pwd(const char *cmdstr) { 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); } else { rosh_error(errno, "pwd", ""); errno = 0; } istr = htonl(*(int *)pwdstr); ROSH_DEBUG2(" --%08X\n", istr); } /* rosh_pwd */
/* Process a single command string and call handling function * cmdstr command string to process * ipwdstr Initial Present Working Directory string * returns Whether to exit prompt */ char rosh_command(const char *cmdstr, const char *ipwdstr) { char do_exit; char tstr[ROSH_CMD_SZ]; int tlen; do_exit = false; ROSH_DEBUG("--cmd:'%s'\n", cmdstr); tlen = rosh_parse_sp_1(tstr, cmdstr, 0); switch (cmdstr[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); break; case 'c': case 'C': /* run 'cd' 'cat' 'cfg' */ switch (cmdstr[1]) { case 'a': case 'A': if (strncasecmp("cat", tstr, tlen) == 0) rosh_cat(cmdstr); else rosh_help(1, NULL); break; case 'd': case 'D': if (strncasecmp("cd", tstr, tlen) == 0) rosh_cd(cmdstr, ipwdstr); else rosh_help(1, NULL); break; case 'f': case 'F': if (strncasecmp("cfg", tstr, tlen) == 0) rosh_cfg(); else rosh_help(1, NULL); break; default: rosh_help(1, NULL); } break; case 'd': case 'D': /* run 'dir' */ if (strncasecmp("dir", tstr, tlen) == 0) rosh_dir(cmdstr); else rosh_help(1, NULL); break; case 'h': case 'H': case '?': if ((strncasecmp("help", tstr, tlen) == 0) || (tlen == 1)) rosh_help(2, cmdstr); else rosh_help(1, NULL); break; case 'l': case 'L': /* run 'ls' 'less' */ switch (cmdstr[1]) { case 0: case ' ': case 's': case 'S': if (strncasecmp("ls", tstr, tlen) == 0) rosh_ls(cmdstr); else rosh_help(1, NULL); break; case 'e': case 'E': if (strncasecmp("less", tstr, tlen) == 0) rosh_less(cmdstr); else rosh_help(1, NULL); break; default: rosh_help(1, NULL); } break; case 'm': case 'M': switch (cmdstr[1]) { case 'a': case 'A': if (strncasecmp("man", tstr, tlen) == 0) rosh_help(2, cmdstr); else rosh_help(1, NULL); break; case 'o': case 'O': if (strncasecmp("more", tstr, tlen) == 0) rosh_more(cmdstr); else rosh_help(1, NULL); break; default: rosh_help(1, NULL); } break; case 'p': case 'P': /* run 'pwd' */ if (strncasecmp("pwd", tstr, tlen) == 0) rosh_pwd(cmdstr); else rosh_help(1, NULL); break; case 'r': case 'R': /* run 'run' */ switch (cmdstr[1]) { case 0: case ' ': case 'e': case 'E': if (strncasecmp("reboot", tstr, tlen) == 0) rosh_reboot(); else rosh_help(1, NULL); break; case 'u': case 'U': if (strncasecmp("run", tstr, tlen) == 0) rosh_run(cmdstr); else rosh_help(1, NULL); break; } break; case 'v': case 'V': if (strncasecmp("version", tstr, tlen) == 0) rosh_version(1); else rosh_help(1, NULL); break; case 0: case '\n': break; default: rosh_help(1, NULL); } /* switch(cmdstr[0]) */ return do_exit; } /* rosh_command */
/* Simple directory listing; calls rosh_ls() * cmdstr command string to process * pwdstr Present Working Directory string */ void rosh_dir(const char *cmdstr) { ROSH_DEBUG(" dir implemented as ls\n"); rosh_ls(cmdstr); } /* rosh_dir */
void print_beta(void) { puts(rosh_beta_str); ROSH_DEBUG("DO_DEBUG active\n"); ROSH_DEBUG2("DO_DEBUG2 active\n"); }