summaryrefslogblamecommitdiff
path: root/src/user/app/yosh/main.cpp
blob: 160e7284617fadd0a4ea59cff1c04efda9c1abb8 (plain) (tree)
1
2
3
4
5
6
7
8
9



                        
                     
                        
                   
 
           
           

              
                                                                    

 

                         
                                                                                  
                                        
                                                                                      
                                       

                                                                                                   
                                       

                                                                                                                        
                                     
                                                                                    
                                     
                                                                                                                   
                                       

                                                                                                 
                
                                                                       


         


                                                   
         
                                   
 
                                               
 

                                                 
                                                        
                                                     
                                              

                                                                   
                


                               


         






                                                                       
 
                                                   
 
                                                   
 
                                                           
                                 
 




                                                                      
 
                              



                                                                                               

                 
                              


         

                       


                              

                                                                            
                                                                  

                                                       
                                                                         
                                                                 
                                                                     

                                                                                 
                                

                                             
                         



                 
                        
              
                                   
                                                         
                               
                                                     
                                       
                                                                      
                                   
                                                                              
                                                        
                                                                    
                        
                                                           
                                                              


                                                                        




                                   


                                                   

                       
                                                     
              

                                                                             
                
                                              


         
                           

                
                  
                                
 
                                                 


                                    




                                                   
 
                   











                                                                                                             
 

                                                                  
                                            
                                        









                                                                                  
                                               



                                                         


                                 
                                                                   
 
                                           
                                
                                                 
                                     

                                                                       
                              
                                               
                                   
                                               
                                   
                                                 
                                       
                                                

                                    
                                           
                                                    
                                 


                                                               
                                                                                    

                                                 

                                                                        
                                                               
                                                                                                             

                                                 
                                               

                         
                                 

                                                                     
                                
                                                                      
                         
                                    
                                                       

                                                                                              
                                                                     

                                                         
                                                                                            
                                        
                                                                        
                                 
                                
                                                     
                                                                        
                                                                                                                
                                        
                                                                                                                
                                                               
                                 
                         
                 



                 
#include <tce/syscall.h>
#include <tce/vfs.h>
#include <stdlib.h>
#include <stdio.h>
#include <readline.h>
#include <IO/IOStream.h>
#include <IO/Dir.h>

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 <command>\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 <location>\nGoes to the location specified.\n";
	} else if (args[1] == "ls") {
		stdio << "Usage:\tls\n\tls <location>...\nShows the content of the current/specified directory.\n";
	} else if (args[1] == "goto") {
		stdio << "Usage:\tgoto <vt name>\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 <directory>\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 <vt_name>\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 <vt> <command>\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;
}