summaryrefslogblamecommitdiff
path: root/Source/Kernel/Shell/KernelShell.class.cpp
blob: f35b4dce7f7f87ca0c11def43e341cd7037fbdb9 (plain) (tree)
1
2
3
4
5
6
7
8


                                         
                             
                                     
                       
                                          
                                


                                    






                                           

                                                                  

                                          





                                                           




                                                                   
                                                                                   
                   
                          
                       

 





                             










                                                          
                                             





                                                     
                                                       
                                                   




                      
                                               
                                                   
                                               
                                                                    
                                            


















                                                                                                 


                                                         


































                                                                                                         
                                                                                               








                                                                               





                                                                                 
                                                                   












                                                                                                      
#include "KernelShell.class.h"
#include <VTManager/ScrollableVT.class.h>
#include <DeviceManager/Kbd.ns.h>
#include <SimpleList.class.h>
#include <MemoryManager/PhysMem.ns.h>
#include <VFS/VFS.ns.h>
#include <FileSystems/RamFS/RamFS.class.h>
#include <TaskManager/Task.ns.h>

u32int KernelShell::m_instances = 0;

u32int shellRun(void* ks) {
	KernelShell* sh = (KernelShell*)ks;
	u32int ret = sh->run();
	delete sh;
	return ret;
}

void KernelShell::setup(DirectoryNode* cwd, VirtualTerminal *vt) {
	m_vt = vt;
	Task::currProcess()->setInVT(vt);
	Task::currProcess()->setOutVT(vt);
	m_cwd = cwd;
	*m_vt << "Welcome to Melon's kernel shell !\n";
	m_thread = new Thread(shellRun, (void*)this, true);
	m_instances++;
}

KernelShell::KernelShell(DirectoryNode* cwd, VirtualTerminal* vt) {
	setup(cwd, vt);
}

KernelShell::KernelShell(DirectoryNode* cwd) {
	ScrollableVT* vt = new ScrollableVT(15, 76, 200, KVT_FGCOLOR, KVT_BGCOLOR);
	vt->map(9);
	Kbd::setFocus(vt);
	setup(cwd, vt);
}

KernelShell::~KernelShell() {
	delete m_vt;
	m_instances--;
}

u32int KernelShell::run() {
	struct {
		const char* name;
		void (KernelShell::*cmd)(Vector<String>&);
	} commands[]= {
		{"ls",    &KernelShell::ls},
		{"cd",    &KernelShell::cd},
		{"pwd",   &KernelShell::pwd},
		{"cat",   &KernelShell::cat},
		{"mkdir", &KernelShell::mkdir},
		{"rm",    &KernelShell::rm},
		{"wf",    &KernelShell::wf},
		{"run",	  &KernelShell::run},

		{"devices", &KernelShell::devices},
		{"loadkeys", &KernelShell::loadkeys},
		{"free", &KernelShell::free},
		{"uptime", &KernelShell::uptime},
		{"part", &KernelShell::part},
		{"readblock", &KernelShell::readblock},
		{"hexdump", &KernelShell::hexdump},

		{0, 0}
	};
	
	while (1) {
		m_vt->setColor(KVT_LIGHTCOLOR);
		*m_vt << VFS::path(m_cwd) << " # ";
		m_vt->setColor(KVT_ENTRYCOLOR);
		Vector<String> tokens = m_vt->readLine().split(" ");
		m_vt->setColor(KVT_FGCOLOR);
		if (tokens[0] == "help") {
			*m_vt << " - Command list for integrated kernel shell:\n";
			*m_vt << "  - help       shows this help screen\n";
			*m_vt << "  - reboot     reboots your computer\n";
			*m_vt << "  - halt       shuts down your computer\n";
			*m_vt << "  - panic      causes a kernel panic\n";
			*m_vt << "  - devices    shows all detected devices on your computer\n";
			*m_vt << "  - loadkeys   loads specified kekymap\n";
			*m_vt << "  - free       shows memory usage (frames and kheap)\n";
			*m_vt << "  - uptime     shows seconds since boot\n";
			*m_vt << "  - part       shows all detected block devs and partitions\n";
			*m_vt << "  - Standard UNIX commands : ls cd cat pwd rm mkdir wf\n";
			*m_vt << " - Scroll up with shift+pgup !\n";
		} else if (tokens[0] == "reboot") {
			Sys::reboot();
		} else if (tokens[0] == "halt") {
			Sys::halt();
		} else if (tokens[0] == "panic") {
			PANIC("This is what happens when you say 'panic'.");
		} else if (tokens[0] == "exit") {
			if (tokens.size() == 1) return 0;
			return tokens[1].toInt();
		} else if (tokens[0] == "mount") {
			if (tokens.size() == 1) {
				for (u32int i = 0; i < VFS::filesystems.size(); i++) {
					*m_vt << VFS::path(VFS::filesystems[i]->getRootNode()) << "\n";
				}
			} else if (tokens.size() == 3) {
				if (tokens[1] == "ramfs") {
					FSNode* n = VFS::find(tokens[2], m_cwd);
					if (n == 0) {
						*m_vt << "No such directory.\n";
					} else if (n->type() != NT_DIRECTORY) {
						*m_vt << "Not a directory.\n";
					} else {
						if (RamFS::mount(100000, (DirectoryNode*)n) != 0) {
							*m_vt << "Ok...\n";
						} else {
							*m_vt << "Error !\n";
						}
					}
				} else {
					*m_vt << "Not supported yet.\n";
				}
			} else {
				*m_vt << "Usage: mount [<device> <mountpoint>\n";
			}
		} else if (tokens[0] == "unmount") {
			if (tokens.size() == 2) {
				FSNode* n = VFS::find(tokens[1], m_cwd);
				bool ok = false;
				if (n == 0) {
					ok = false;
				} else {
					String p = VFS::path(n);
					for (u32int i = 0; i < VFS::filesystems.size(); i++) {
						if (VFS::path(VFS::filesystems[i]->getRootNode()) == p) {
							ok = VFS::unmount(VFS::filesystems[i]);
							break;
						}
					}
				}
				if (ok) *m_vt << "Ok, filesystem unmounted.\n";
				else *m_vt << "Error.\n";
			} else {
				*m_vt << "Usage: unmount <mountpoint>\n";
			}
		} else if (tokens[0] != "" or tokens.size() != 1) {
			u32int i = 0;
			bool found = false;
			while (commands[i].name != 0) {
				if (tokens[0] == (const char*)commands[i].name) {
					found = true;
					if (commands[i].cmd != 0) {
						(this->*(commands[i].cmd))(tokens);	//Call command
					} else {
						*m_vt << "This command isn't enabled... yet !\n";
					}
					break;
				}
				i++;
			}
			if (!found) *m_vt << "Unknown command : " << tokens[0] << "\n";
		}
	}
	return 1337;
}