diff --git a/client/src/terminal.cpp b/client/src/terminal.cpp index 1fdff70..d772dbf 100644 --- a/client/src/terminal.cpp +++ b/client/src/terminal.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/common/src/command_processor.cpp b/common/src/command_processor.cpp index 0110856..97e5a10 100644 --- a/common/src/command_processor.cpp +++ b/common/src/command_processor.cpp @@ -1,4 +1,5 @@ #include "command_processor.h" +#include #include "vfs.h" #include "lua_processor.h" @@ -22,7 +23,16 @@ std::string CommandProcessor::process_command(const std::string& command) { cmd = (end == std::string::npos) ? "" : cmd.substr(0, end+1); /* === Generic script executer. === */ - std::string command_name = cmd.substr(0, cmd.find(" ")); + /* Parse the command and it's arguments. */ + std::stringstream ss(cmd); + std::string command_name; + ss >> command_name; + + std::vector args; + std::string arg; + while(ss >> arg) { + args.push_back(arg); + } /* Search for script in the /bin directory. */ std::string script_filename = command_name + ".lua"; @@ -32,8 +42,7 @@ std::string CommandProcessor::process_command(const std::string& command) { } if(root->children.count("bin") && root->children["bin"]->children.count(script_filename)) { vfs_node* script_node = root->children["bin"]->children[script_filename]; - /* TODO: Pass arguments to the Lua script. */ - return _lua->execute(script_node->content, _current_dir); + return _lua->execute(script_node->content, _current_dir, args); } diff --git a/common/src/lua_processor.cpp b/common/src/lua_processor.cpp index 5090f19..109a4f6 100644 --- a/common/src/lua_processor.cpp +++ b/common/src/lua_processor.cpp @@ -8,15 +8,45 @@ LuaProcessor::LuaProcessor(void) { _lua.new_usertype("vfs_node", "name", &vfs_node::name, "type", &vfs_node::type, - "children", &vfs_node::children); + "children", &vfs_node::children, + "read_only", &vfs_node::read_only); + + /* Create the 'vfs' table for our API. */ + sol::table vfs_api = _lua.create_table("vfs"); + vfs_api.set_function("rm", [](std::string path, vfs_node* current_dir) { + /* for now, we'll just support deleting from the current directory. */ + if(current_dir->children.count(path)) { + vfs_node* target_node = current_dir->children[path]; + if(target_node->read_only || current_dir->read_only) { + return std::string("rm: Permission denied. File or directory is read-only."); + } + if(target_node->type == DIR_NODE) { + return std::string("rm: cannot remove '" + path + "': Is a directory."); + } + + current_dir->children.erase(path); + delete target_node; /* Clean up memry. */ + return std::string(""); /* Success. */ + } + return std::string("rm: cannot remove '" + path + "': No such file or directory."); + }); } LuaProcessor::~LuaProcessor(void) {} -std::string LuaProcessor::execute(const std::string& script, vfs_node* current_dir) { +std::string LuaProcessor::execute(const std::string& script, vfs_node* current_dir, + const std::vector& args) { try { - /* Pass the pointer for the current directory into the Lua env. */ + /* Pass C++ objects/points into the Lua env. */ _lua["current_dir"] = current_dir; + + /* Create and populate the 'arg' table for the script. */ + sol::table arg_table = _lua.create_table();;;; + for(size_t i = 0; i < args.size(); ++i) { + arg_table[i+1] = args[i]; /* Lua array are 1-indexed. Not that Skuzzy would know. */ + } + _lua["arg"] = arg_table; + sol::object result = _lua.script(script); if(result.is()) { return result.as(); diff --git a/common/src/lua_processor.h b/common/src/lua_processor.h index 78b89ba..bb88f37 100644 --- a/common/src/lua_processor.h +++ b/common/src/lua_processor.h @@ -1,18 +1,18 @@ #pragma once #include +#include +#include #include -/* Don't want the full header. */ -struct vfs_node; - class LuaProcessor { public: LuaProcessor(void); ~LuaProcessor(void); /* Executes a string of lua code and returns result as a string. */ - std::string execute(const std::string& script, vfs_node* current_dir); + std::string execute(const std::string& script, vfs_node* current_dir, + const std::vector& args); private: sol::state _lua; }; diff --git a/common/src/vfs.h b/common/src/vfs.h index 1f02dc1..4e3d704 100644 --- a/common/src/vfs.h +++ b/common/src/vfs.h @@ -16,6 +16,7 @@ enum vfs_node_type { struct vfs_node { std::string name; vfs_node_type type; + bool read_only; /* Files. */ std::string content; diff --git a/common/src/vfs_manager.cpp b/common/src/vfs_manager.cpp index db431d4..241fc32 100644 --- a/common/src/vfs_manager.cpp +++ b/common/src/vfs_manager.cpp @@ -3,10 +3,11 @@ /* Create a new node. */ vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent) { - vfs_node* node = new vfs_node(); - node->name = name; - node->type = type; - node->parent = parent; + vfs_node* node = new vfs_node(); + node->name = name; + node->type = type; + node->parent = parent; + node->read_only = false; /* Writable by default. */ return node; } @@ -16,6 +17,9 @@ VFSManager::VFSManager(void) { vfs_node* bin = new_node("bin", DIR_NODE, _vfs_root); _vfs_root->children["bin"] = bin; + _vfs_root->read_only = true; + bin->read_only = true; + /* TODO: * Load all scripts from assets/scripts/bin into the bind node. * We'll create ls.lua manually for now. @@ -37,6 +41,14 @@ VFSManager::VFSManager(void) { )lua"; bin->children["ls.lua"] = ls_script; + + vfs_node* rm_script = new_node("rm.lua", FILE_NODE, bin); + rm_script->content = R"lua(-- /bin/rm.lua - Removes a file. + local file_to_remove = arg[1] + if not file_to_remove then return "rm: missing operand" end + return vfs.rm(file_to_remove, current_dir) + )lua"; + bin->children["rm.lua"] = rm_script; } VFSManager::~VFSManager(void) {