#include #include #include #include #include #include #include Dir *cwd_f; String cwd; void about() { stdio << "Trivial/Computing Environment v0.1.0 - yosh 3.\n"; } void help(String *args) { if (!args[1]) { stdio << "Available commands: about, help, exit, ls, cd, goto.\n"; } else if (args[1] == "about") { stdio << "Usage:\tabout\nShows some info about yosh. Very usefull.\n"; } else if (args[1] == "help") { stdio << "Usage:\thelp\n\thelp \n" << "Shows some info about the command you want, or commands in general.\n"; } else if (args[1] == "exit") { stdio << "Usage:\texit\n" << "Exits the shell.\nWill probably make your system panic if you only have a shell running.\n"; } else if (args[1] == "cd") { stdio << "Usage:\tcd \nGoes to the location specified.\n"; } else if (args[1] == "ls") { stdio << "Usage:\tls\n\tls ...\nShows the content of the current/specified directory.\n"; } else if (args[1] == "goto") { stdio << "Usage:\tgoto \nSwitchs focus to specified virtual terminal.\n" << "Type `ls /.ui` to see available terminals.\n"; } else { stdio.printf("No such command: %s\n", args[1].c_str()); } } void cd(String *args) { if (!args[1]) { stdio << "Usage: cd \n"; } if (args[1] == ".") return; String newcwd = path_cat(cwd, args[1]); Dir *newdir = new Dir(newcwd.c_str(), 0); if (newdir->error == E_NOT_FOUND) { stdio << "No such file or directory.\n"; } else if (newdir->error == E_INVALID_TYPE) { stdio << "Not a directory.\n"; } else if (newdir->error != 0) { stdio.printf("Error stating: %i\n", newdir->error); } else { cwd_f->close(); cwd = newcwd; cwd_f = newdir; } } void ls_dir(Dir *d) { if (d->error != 0) { return; } d->pos = 0; for (String name = d->read_ent(); name; name = d->read_ent()) { if (name == "." || name == "..") continue; stdio.printf(" %s", name.c_str()); Node child(d->fd, name.c_str(), 0); if (child.info.type & FT_DIR) stdio << "/"; stdio << " \t"; if (child.info.type & FT_FILE) stdio << "file "; if (child.info.type & FT_DIR) stdio << "dir "; if (child.info.type & FT_SYMLINK) stdio << "symlink "; if (child.info.type & FT_DEV) stdio << "dev "; if (child.info.type & FT_TERMINAL) stdio << "term "; stdio << "\t"; if (child.info.type & FT_TERMINAL) { stdio.printf("%ix%i", child.info.size >> 16, child.info.size & 0xFFFF); } else if ((child.info.type & FT_DEV) == 0) { stdio.printf("%i", child.info.size); } stdio << "\n"; } } void ls(String *args) { if (!args[1]) { ls_dir(cwd_f); } else { int i; for (i = 1; args[i]; i++) { stdio.printf("Contents of %s :\n", args[i].c_str()); String d = path_cat(cwd, args[i].c_str()); Dir dir(d.c_str(), 0); if (dir.error == E_NOT_FOUND) { stdio << " No such file or directory\n"; } else if (dir.error == E_INVALID_TYPE) { stdio.printf(" Not a directory.\n"); } else if (dir.error < 0) { stdio.printf(" Error stating: %i\n", dir.error); } else { ls_dir(&dir); dir.close(); } } } } void cat(String *args) { int i; for (i = 1; args[i]; i++) { String d = path_cat(cwd, args[i], false); file_info info; int e = libc::stat(d.c_str(), &info); if (e == E_NOT_FOUND) { stdio.printf("No such file: %s\n", d.c_str()); } else if (e < 0) { stdio.printf("Error stating %s : %i\n", d.c_str(), e); } else if ((info.type & FT_FILE) == 0) { stdio.printf("Not a file: %s\n", d.c_str()); } else { FILE ff = libc::open(d.c_str(), 0); char* buff = (char*)malloc(info.size); libc::read(ff, 0, info.size, buff); libc::close(ff); libc::write(stdio.term->fd, 0, info.size, buff); free(buff); } } } void t_goto(String *args) { if (!args[1]) { stdio << "Usage: goto \n"; return; } String p = path_cat("/.ui/", args[1], false); int i; if ((i = libc::link(p.c_str(), "/.dev/vgatxt", LM_OUTPUT_TO)) == 0) { libc::link("/.dev/ps2kbd", p.c_str(), LM_OUTPUT_TO); } else { stdio.printf("Error %i\n", i); } } int Main(String *sh_args) { about(); cwd = "/"; cwd_f = new Dir("/", 0); String path = path_cat(sh_args[0], ".."); int bg_pr[128], bg_pr_c = 0; Term *term = stdio.term; if (term == 0) { stdio << "Error: no terminal...\n"; return -1; } while (1) { // check for background processes that may have finished int p = 0; while (p < bg_pr_c) { int ret = libc::waitpid(bg_pr[p], 0); if (ret != E_NOT_FINISHED) { stdio.printf("(yosh) child (pid %i) exited with status %i\n", bg_pr[p], ret); bg_pr_c--; bg_pr[p] = bg_pr[bg_pr_c]; } else { p++; } } // show prompt stdio.printf("\x1b[33m %s \x1b[1m", cwd.c_str()); String s = term->readline(); stdio.printf("\x1b[0m"); if (s.size() == 0) continue; String c_args[16]; int argc = 0, start = 0; for (int i = 0; i < s.size(); i++) { if (s[i] == ' ') { if (start == i) { start++; } else { c_args[argc] = s.substr(start, i - start); argc++; start = i + 1; if (argc == 15) { break; } } } } c_args[argc++] = s.substr(start, s.size() - start); if (c_args[0] == "about") { about(); } else if (c_args[0] == "help") { help(c_args); } else if (c_args[0] == "exit") { stdio << "Exiting the shell. See you later!\n"; break; } else if (c_args[0] == "cd") { cd(c_args); } else if (c_args[0] == "ls") { ls(c_args); } else if (c_args[0] == "goto") { t_goto(c_args); } else if (c_args[0] == "cat") { cat(c_args); } else { FILE vt = term->fd; String *first_arg = c_args ; String t; if (c_args[0] == "on") { if (!c_args[1] || !c_args[2]) { stdio.printf("Usage:\ton \n"); continue; } t = path_cat("/.ui/", c_args[1], false); vt = libc::open(t.c_str(), 0); if (vt < 0 || vt == term->fd) { stdio.printf("Error: cannot open terminal %s (%i)\n", t.c_str(), vt); continue; } first_arg += 2; } String c; if (libc::strchr(first_arg->c_str(), '/')) { c = path_cat(cwd, *first_arg, false); } else { c = path_cat(path, *first_arg, false); } first_arg++; const char *run_args[15] = {0}; for (int i = 0; first_arg[i]; i++) run_args[i] = first_arg[i].c_str(); int pid = libc::run(c.c_str(), run_args, vt); if (pid <= 0) { if (pid == E_NOT_FOUND) { stdio.printf("Error: no such file %s\n", c.c_str()); } else { stdio.printf("Error %i\n", pid); } } else { if (vt == term->fd) { int ret = libc::waitpid(pid, 1); stdio.printf("(yosh) child (pid %i) exited with status %i\n", pid, ret); } else { stdio.printf("(yosh) running on terminal %s, pid:%i\n", t.c_str(), pid); bg_pr[bg_pr_c++] = pid; } } } } return 0; }