[Add] Implement build system for user scripts.
This commit is contained in:
		
							parent
							
								
									20f2e5a104
								
							
						
					
					
						commit
						9b6106f8aa
					
				
							
								
								
									
										27
									
								
								assets/scripts/bin/build.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								assets/scripts/bin/build.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					-- /bin/build - "Compiles" a .lua file into an executable.
 | 
				
			||||||
 | 
					local source_filename = arg[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if not source_filename then
 | 
				
			||||||
 | 
					  return "build: missing file operand"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Check for .lua extension.
 | 
				
			||||||
 | 
					if not source_filename:match("%.lua$") then
 | 
				
			||||||
 | 
					  return "build: input file must be a .lua file"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local current_dir = bettola.get_current_dir(context)
 | 
				
			||||||
 | 
					local source_node = current_dir.children[source_filename]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if not source_node then
 | 
				
			||||||
 | 
					  return "build: cannot open '" .. source_filename .."': No such file"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if source_node.type ~= 0 then
 | 
				
			||||||
 | 
					  return "build: '" .. source_filename .. "' is not a regular file"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local executable_filename = source_filename:gsub("%.lua$", "")
 | 
				
			||||||
 | 
					local source_content = source_node.content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return bettola.create_executable(context, executable_filename, source_content)
 | 
				
			||||||
@ -78,6 +78,50 @@ std::string write_file(Session& context, const std::string& path,
 | 
				
			|||||||
  return "";
 | 
					  return "";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string create_executable(Session& context, const std::string& path,
 | 
				
			||||||
 | 
					                              const std::string& content) {
 | 
				
			||||||
 | 
					  vfs_node* parent_dir = nullptr;
 | 
				
			||||||
 | 
					  std::string filename;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(path[0] == '/') {
 | 
				
			||||||
 | 
					    Machine* session_machine = context.get_session_machine();
 | 
				
			||||||
 | 
					    vfs_node* root = session_machine->vfs_root;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t last_slash = path.find_last_of('/');
 | 
				
			||||||
 | 
					    if(last_slash == 0) {
 | 
				
			||||||
 | 
					      parent_dir = root;
 | 
				
			||||||
 | 
					      filename = path.substr(1);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      std::string parent_path = path.substr(0, last_slash);
 | 
				
			||||||
 | 
					      parent_dir = find_node_by_path(root, parent_path);
 | 
				
			||||||
 | 
					      filename = path.substr(last_slash+1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    parent_dir = context.get_current_dir();
 | 
				
			||||||
 | 
					    filename = path;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(!parent_dir) {
 | 
				
			||||||
 | 
					    return "create_executable: cannot create file '" + path + "': No such file or directory";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(parent_dir->type != DIR_NODE) {
 | 
				
			||||||
 | 
					    return "create_executable: cannot create file in '" + get_full_path(parent_dir)
 | 
				
			||||||
 | 
					        + "': Not a directory";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Overwrite if exists. */
 | 
				
			||||||
 | 
					  auto it = parent_dir->children.find(filename);
 | 
				
			||||||
 | 
					  if(it != parent_dir->children.end()) {
 | 
				
			||||||
 | 
					    delete it->second;
 | 
				
			||||||
 | 
					    parent_dir->children.erase(it);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  vfs_node* new_exec = new_node(filename, EXEC_NODE, parent_dir);
 | 
				
			||||||
 | 
					  new_exec->content = content;
 | 
				
			||||||
 | 
					  parent_dir->children[filename] = new_exec;
 | 
				
			||||||
 | 
					  return "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string cd(Session& context, const std::string& path) {
 | 
					std::string cd(Session& context, const std::string& path) {
 | 
				
			||||||
  vfs_node* current_dir = context.get_current_dir();
 | 
					  vfs_node* current_dir = context.get_current_dir();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,8 @@ vfs_node* get_current_dir(Session& context);
 | 
				
			|||||||
std::string rm(Session& context, const std::string& filename);
 | 
					std::string rm(Session& context, const std::string& filename);
 | 
				
			||||||
std::string write_file(Session& context, const std::string& path,
 | 
					std::string write_file(Session& context, const std::string& path,
 | 
				
			||||||
                       const std::string& content);
 | 
					                       const std::string& content);
 | 
				
			||||||
 | 
					std::string create_executable(Session& context, const std::string& path,
 | 
				
			||||||
 | 
					                              const std::string& content);
 | 
				
			||||||
std::string ls(Session& context);
 | 
					std::string ls(Session& context);
 | 
				
			||||||
std::string cd(Session& context, const std::string& path);
 | 
					std::string cd(Session& context, const std::string& path);
 | 
				
			||||||
std::string scp(Session& context, const std::string& source,
 | 
					std::string scp(Session& context, const std::string& source,
 | 
				
			||||||
 | 
				
			|||||||
@ -23,16 +23,17 @@ LuaProcessor::LuaProcessor(Session& context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* Create the 'bettola' API table. */
 | 
					  /* Create the 'bettola' API table. */
 | 
				
			||||||
  sol::table bettola_api = _lua.create_named_table("bettola");
 | 
					  sol::table bettola_api = _lua.create_named_table("bettola");
 | 
				
			||||||
  bettola_api.set_function("rm",              &api::rm);
 | 
					  bettola_api.set_function("rm",                &api::rm);
 | 
				
			||||||
  bettola_api.set_function("ls",              &api::ls);
 | 
					  bettola_api.set_function("ls",                &api::ls);
 | 
				
			||||||
  bettola_api.set_function("write_file",      &api::write_file);
 | 
					  bettola_api.set_function("write_file",        &api::write_file);
 | 
				
			||||||
  bettola_api.set_function("get_current_dir", &api::get_current_dir);
 | 
					  bettola_api.set_function("create_executable", &api::create_executable);
 | 
				
			||||||
  bettola_api.set_function("cd",              &api::cd);
 | 
					  bettola_api.set_function("get_current_dir",   &api::get_current_dir);
 | 
				
			||||||
  bettola_api.set_function("scp",             &api::scp);
 | 
					  bettola_api.set_function("cd",                &api::cd);
 | 
				
			||||||
  bettola_api.set_function("close_terminal",  &api::close_terminal);
 | 
					  bettola_api.set_function("scp",               &api::scp);
 | 
				
			||||||
  bettola_api.set_function("ssh",             &api::ssh);
 | 
					  bettola_api.set_function("close_terminal",    &api::close_terminal);
 | 
				
			||||||
  bettola_api.set_function("nmap",            &api::nmap);
 | 
					  bettola_api.set_function("ssh",               &api::ssh);
 | 
				
			||||||
  bettola_api.set_function("disconnect",      &api::disconnect);
 | 
					  bettola_api.set_function("nmap",              &api::nmap);
 | 
				
			||||||
 | 
					  bettola_api.set_function("disconnect",        &api::disconnect);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LuaProcessor::~LuaProcessor(void) {}
 | 
					LuaProcessor::~LuaProcessor(void) {}
 | 
				
			||||||
 | 
				
			|||||||
@ -93,23 +93,36 @@ std::string Session::process_command(const std::string& command) {
 | 
				
			|||||||
    args.push_back(arg);
 | 
					    args.push_back(arg);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Find the /bin directory in the current machine's VFS. */
 | 
					  vfs_node* command_node = nullptr;
 | 
				
			||||||
  vfs_node* bin_dir = find_node_by_path(_session_machine->vfs_root, "/bin");
 | 
					  if(command_name.find('/') != std::string::npos) {
 | 
				
			||||||
  if(bin_dir && bin_dir->type == DIR_NODE) {
 | 
					    /* Path provided, find node directly. */
 | 
				
			||||||
    auto it = bin_dir->children.find(command_name);
 | 
					    command_node = find_node_by_path(_session_machine->vfs_root, command_name);
 | 
				
			||||||
    if(it != bin_dir->children.end()) {
 | 
					  } else {
 | 
				
			||||||
      vfs_node* command_node = it->second;
 | 
					    /* No path, search current dir then /bin. */
 | 
				
			||||||
      if(command_node->type == EXEC_NODE) {
 | 
					    vfs_node* current_dir = get_current_dir();
 | 
				
			||||||
        /* Execute the script. */
 | 
					    if(current_dir->children.count(command_name)) {
 | 
				
			||||||
        bool is_remote = (_session_machine != _home_machine);
 | 
					      command_node = current_dir->children.at(command_name);
 | 
				
			||||||
        sol::object result = lua.execute(command_node->content, *this, args, is_remote);
 | 
					    } else {
 | 
				
			||||||
        return result.is<std::string>() ? result.as<std::string>()
 | 
					      vfs_node* bin_dir = find_node_by_path(_session_machine->vfs_root, "/bin");
 | 
				
			||||||
            : "[Script returned an unexpected type]";
 | 
					      if(bin_dir && bin_dir->children.count(command_name)) {
 | 
				
			||||||
 | 
					        command_node = bin_dir->children.at(command_name);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return "Unknown command: " + command_name + "\n";
 | 
					  if(command_node) {
 | 
				
			||||||
 | 
					    if(command_node->type == EXEC_NODE) {
 | 
				
			||||||
 | 
					      bool is_remote = (_session_machine != _home_machine);
 | 
				
			||||||
 | 
					      sol::object result = lua.execute(command_node->content, *this, args, is_remote);
 | 
				
			||||||
 | 
					      return result.is<std::string>() ? result.as<std::string>()
 | 
				
			||||||
 | 
					                                      : "[Script returned non-string value]";
 | 
				
			||||||
 | 
					    } else if(command_node->type == DIR_NODE) {
 | 
				
			||||||
 | 
					      return "Cannot execute '" + command_name + "' It is a directory.";
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return "Cannot execute '" + command_name + "': Not an executable file.";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return "Unknown command: " + command_name;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string Session::write_file(const std::string& path, const std::string& content) {
 | 
					std::string Session::write_file(const std::string& path, const std::string& content) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user