#include #include #include #include #include char *cwd; void about() { printf("Trivial/Computing Environment v0.1.4 - yosh 4.\n"); } void help(char **args) { if (!args[1]) { printf("Available commands: about, help, exit, ls, cd, goto.\n"); } else if (!strcmp(args[1], "about")) { printf("Usage:\tabout\nShows some info about yosh. Very usefull.\n"); } else if (!strcmp(args[1], "help")) { printf("Usage:\thelp\n\thelp \n"); printf("Shows some info about the command you want, or commands in general.\n"); } else if (!strcmp(args[1], "exit")) { printf("Usage:\texit\n"); printf("Exits the shell.\nWill probably make your system panic if you only have a shell running.\n"); } else if (!strcmp(args[1], "cd")) { printf("Usage:\tcd \nGoes to the location specified.\n"); } else if (!strcmp(args[1], "ls")) { printf("Usage:\tls\n\tls ...\nShows the content of the current/specified directory.\n"); } else if (!strcmp(args[1], "goto")) { printf("Usage:\tgoto \nSwitchs focus to specified virtual terminal.\n"); printf("Type `ls /.ui` to see available terminals.\n"); } else { printf("No such command: %s\n", args[1]); } } void cd(char **args) { if (!args[1]) { printf("Usage: cd \n"); } if (!strcmp(args[1], ".")) return; char* newcwd = path_cat(cwd, args[1], 1); file_info f; int r = stat(newcwd, &f); if (r == E_NOT_FOUND) { printf("No such file or directory.\n"); } else if (r != 0) { printf("Error stating: %i\n", r); } else if (!(f.type & FT_DIR)) { printf("Not a directory.\n"); } else { free(cwd); cwd = newcwd; return; } free(newcwd); } void ls_dir(int fd) { char buf[256]; int pos = 0; while (read(fd, pos++, 256, buf) > 0) { if ((!strcmp(buf, ".")) || (!strcmp(buf, ".."))) continue; printf(" %s", buf); file_info info; stat_relative(fd, buf, &info); if (info.type & FT_DIR) printf("/"); printf(" \t"); if (info.type & FT_FILE) printf("file "); if (info.type & FT_DIR) printf("dir "); if (info.type & FT_SYMLINK) printf("symlink "); if (info.type & FT_DEV) printf("dev "); if (info.type & FT_TERMINAL) printf("term "); printf("\t"); if (info.type & FT_TERMINAL) { printf("%ix%i", info.size >> 16, info.size & 0xFFFF); } else if ((info.type & FT_DEV) == 0) { printf("%i", info.size); } printf("\n"); } } void ls(char **args) { if (!args[1]) { int fd = open(cwd, FM_READ); if (fd > 0) { ls_dir(fd); close(fd); } else { printf(" Could not open for read (%d).\n", fd); } } else { int i; for (i = 1; args[i]; i++) { printf("Contents of %s :\n", args[i]); char *d = path_cat(cwd, args[i], 1); file_info i; int r = stat(d, &i); if (r == E_NOT_FOUND) { printf(" No such file or directory\n"); } else if (r != 0) { printf(" Error stating: %i\n", r); } else if (!(i.type & FT_DIR)) { printf(" Not a directory.\n"); } else { int fd = open(d, FM_READ); if (fd > 0) { ls_dir(fd); close(fd); } else { printf(" Could not open for read (%d).\n", fd); } } free(d); } } } void cat(char **args) { int i; for (i = 1; args[i]; i++) { char *d = path_cat(cwd, args[i], 0); file_info info; int e = stat(d, &info); if (e == E_NOT_FOUND) { printf("No such file: %s\n", d); } else if (e < 0) { printf("Error stating %s : %i\n", d, e); } else if ((info.type & FT_FILE) == 0) { printf("Not a file: %s\n", d); } else { int ff = open(d, 0); char* buff = (char*)malloc(info.size); read(ff, 0, info.size, buff); close(ff); write(term.fd, 0, info.size, buff); free(buff); } free(d); } } void t_goto(char **args) { if (!args[1]) { printf("Usage: goto \n"); return; } char *p = path_cat("/.ui/", args[1], 0); int i; if ((i = link(p, "/.dev/vgatxt", LM_OUTPUT_TO)) == 0) { link("/.dev/ps2kbd", p, LM_OUTPUT_TO); } else { printf("Error %i\n", i); } free(p); } int main(int argc, char **sh_args) { about(); cwd = strdup("/"); char *path = path_cat(sh_args[0], "..", 1); int bg_pr[128], bg_pr_c = 0; readline_history hist; hist.str = 0; hist.max = 10; while (1) { // check for background processes that may have finished int p = 0; while (p < bg_pr_c) { int ret = waitpid(bg_pr[p], 0); if (ret != E_NOT_FINISHED) { 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 printf("\x1b[33m %s \x1b[1m", cwd); char *s = freadline(stdin, &hist); printf("\x1b[0m"); if (s == NULL) break; if (strlen(s) == 0) continue; char *a_c = strdup(s); // duplicate because we're gonna add '\0'es char *c_args[16]; char *start = a_c, *pos = a_c; int argc = 0; while (*pos) { if (*pos == ' ') { if (pos == start) { start++; } else { *pos = 0; c_args[argc] = start; argc++; start = pos + 1; if (argc == 14) { break; } } } pos++; } c_args[argc++] = start; c_args[argc] = 0; if (!strcmp(c_args[0], "about")) { about(); } else if (!strcmp(c_args[0], "help")) { help(c_args); } else if (!strcmp(c_args[0], "exit")) { printf("Exiting the shell. See you later!\n"); break; } else if (!strcmp(c_args[0], "cd")) { cd(c_args); } else if (!strcmp(c_args[0], "ls")) { ls(c_args); } else if (!strcmp(c_args[0], "goto")) { t_goto(c_args); } else if (!strcmp(c_args[0], "cat")) { cat(c_args); } else { char **first_arg = c_args; char *term_s = NULL; int vt_fd = term.fd; if (!strcmp(c_args[0], "on")) { if (!c_args[1] || !c_args[2]) { printf("Usage:\ton \n"); continue; } term_s = path_cat("/.ui/", c_args[1], 1); vt_fd = open(term_s, 0); if (vt_fd < 0 || vt_fd == term.fd) { printf("Error: cannot open terminal %s (%i)\n", term_s, vt_fd); continue; } first_arg += 2; } char *c; if (strchr(*first_arg, '/')) { c = path_cat(cwd, *first_arg, 0); } else { c = path_cat(path, *first_arg, 0); } first_arg++; int pid = run(c, first_arg, vt_fd); if (pid <= 0) { if (pid == E_NOT_FOUND) { printf("Error: no such file %s\n", c); } else { printf("Error %i\n", pid); } } else { if (term_s == NULL) { int ret = waitpid(pid, 1); printf("(yosh) child (pid %i) exited with status %i\n", pid, ret); } else { printf("(yosh) running on terminal %s, pid:%i\n", term_s, pid); bg_pr[bg_pr_c++] = pid; } } free(c); if (term_s) free(term_s); } free(a_c); } return 0; }