共计 21029 个字符,预计需要花费 53 分钟才能阅读完成。
#include <bits/stdc++.h>
#include <string>
#include <fstream>
using namespace std;
typedef long long ll;
typedef double db;
// 外部系统函数
bool fileExists(const std::string& filename)
{
std::ifstream file(filename);
return file.good();
}
// 保存 vector<vector<ll>> 到二进制文件
void saveVector2DBinary(const std::vector<std::vector<ll>>& data, const std::string& filename) {
std::ofstream file(filename, std::ios::binary);
if (!file.is_open()) {
std::cerr << " 无法打开文件: " << filename << std::endl;
return;
}
// 先写入行数
size_t rows = data.size();
file.write(reinterpret_cast<const char*>(&rows), sizeof(rows));
// 写入每一行
for (const auto& row : data) {
size_t cols = row.size();
file.write(reinterpret_cast<const char*>(&cols), sizeof(cols));
if (cols > 0) {
file.write(reinterpret_cast<const char*>(row.data()), cols * sizeof(ll));
}
}
file.close();
}
// 从二进制文件读取 vector<vector<ll>>
std::vector<std::vector<ll>> loadVector2DBinary(const std::string& filename) {
std::vector<std::vector<ll>> data;
std::ifstream file(filename, std::ios::binary);
if (!file.is_open()) {
std::cerr << " 无法打开文件: " << filename << std::endl;
return data;
}
// 读取行数
size_t rows;
file.read(reinterpret_cast<char*>(&rows), sizeof(rows));
data.resize(rows);
// 读取每一行
for (size_t i = 0; i < rows; ++i) {
size_t cols;
file.read(reinterpret_cast<char*>(&cols), sizeof(cols));
data[i].resize(cols);
if (cols > 0) {
file.read(reinterpret_cast<char*>(data[i].data()), cols * sizeof(ll));
}
}
file.close();
return data;
}
// 文件类
struct fs {
string type; // 类型(文件 or 文件夹)(file or dir)
string name; // 名称
ll id; // 唯一标识符
string content = ""; // 内容
// 序列化函数
void serialize(std::ofstream& file) const {
// 写入 type
size_t type_len = type.size();
file.write(reinterpret_cast<const char*>(&type_len), sizeof(type_len));
file.write(type.c_str(), type_len);
// 写入 name
size_t name_len = name.size();
file.write(reinterpret_cast<const char*>(&name_len), sizeof(name_len));
file.write(name.c_str(), name_len);
// 写入 id
file.write(reinterpret_cast<const char*>(&id), sizeof(id));
// 写入 content
size_t content_len = content.size();
file.write(reinterpret_cast<const char*>(&content_len), sizeof(content_len));
if (content_len > 0) {
file.write(content.c_str(), content_len);
}
}
// 反序列化函数
void deserialize(std::ifstream& file) {
// 读取 type
size_t type_len;
file.read(reinterpret_cast<char*>(&type_len), sizeof(type_len));
type.resize(type_len);
if (type_len > 0) {
file.read(&type[0], type_len);
}
// 读取 name
size_t name_len;
file.read(reinterpret_cast<char*>(&name_len), sizeof(name_len));
name.resize(name_len);
if (name_len > 0) {
file.read(&name[0], name_len);
}
// 读取 id
file.read(reinterpret_cast<char*>(&id), sizeof(id));
// 读取 content
size_t content_len;
file.read(reinterpret_cast<char*>(&content_len), sizeof(content_len));
content.resize(content_len);
if (content_len > 0) {
file.read(&content[0], content_len);
}
}
};
// 保存 vector<fs> 到二进制文件
void saveVectorBinary(const std::vector<fs>& data, const std::string& filename) {
std::ofstream file(filename, std::ios::binary);
if (!file.is_open()) {
std::cerr << " 无法打开文件: " << filename << std::endl;
return;
}
// 先写入元素数量
size_t size = data.size();
file.write(reinterpret_cast<const char*>(&size), sizeof(size));
// 写入所有数据
for (const auto& item : data) {
item.serialize(file);
}
file.close();
}
// 从二进制文件读取 vector<fs>
std::vector<fs> loadVectorBinary(const std::string& filename) {
std::vector<fs> data;
std::ifstream file(filename, std::ios::binary);
if (!file.is_open()) {
std::cerr << " 无法打开文件: " << filename << std::endl;
return data;
}
// 读取元素数量
size_t size;
file.read(reinterpret_cast<char*>(&size), sizeof(size));
data.resize(size);
// 读取所有数据
for (size_t i = 0; i < size; ++i) {
data[i].deserialize(file);
}
file.close();
return data;
}
// 变量定义~
// 主机信息
string host_name = "syh"; // 主机名
string now_ip = "localhost"; // 终端连接的主机 IP
string now_user = "root"; // 登录用户
// 文件系统
fs root = {"dir", "/", 0}; // 根目录
vector<fs> file_system; // file_system[i] 表示 ID 为 i 的文件 / 文件夹
vector<vector<ll>> children; // children[i] 表示 ID 为 i 的文件夹下所有孩子的 id
// 高效获取当前路径
string path_str = "/"; // 存目前路径的字符串
vector<fs> path; // 存目前路径的所有文件夹(有序)
// 获取开始时间
time_t start_time = chrono::system_clock::to_time_t(chrono::system_clock::now()); // 获取当前系统时间
// 终端样式定义
const string BD = "\033[1m";
const string NC = "\033[0m"; // 重置颜色
// 前景色
const string RED = "\033[0;31m";
const string GREEN = "\033[0;32m";
const string YELLOW = "\033[1;33m";
const string BLUE = "\033[0;34m";
const string PURPLE = "\033[0;35m";
const string CYAN = "\033[0;36m";
const string WHITE = "\033[0;37m";
const string GRAY = "\033[0;90m";
// 背景色
const string BG_RED = "\033[41m";
const string BG_GREEN = "\033[42m";
const string BG_YELLOW = "\033[43m";
const string BG_BLUE = "\033[44m";
const string BG_MAGENTA = "\033[45m";
const string BG_CYAN = "\033[46m";
const string BG_WHITE = "\033[47m";
// 主题色
string TC = RED;
// 命令错误的次数
ll wrong_cnt = 0;
// 分割命令列表
vector<string> coms;
time_t get_now_time() { // 获取时间
return chrono::system_clock::to_time_t(chrono::system_clock::now()) - start_time;
}
string add_define(string original) { // 添加引号
char tmp = '"';
return tmp + original + tmp;
}
string get_theme_input_text(signed last_code) { // 获取主题性输入文本
// 直接使用 path_str
string bg = BG_CYAN;
string wr = "";
if (last_code == 1) wr = " " + to_string(wrong_cnt) + "W";
return RED + BD + bg + wr + " " + BD + TC + bg + host_name + NC + WHITE + bg + "@" + now_ip + " " + NC + BG_WHITE + " " + path_str + " " + NC + " ";
}
string get_theme_confirm_text(string command) { // 获取主题固着文本
return BD + ">" + NC + " " + command;
}
string get_theme_command_not_found_text() { // 获取命令未找到文字
return "Command " + add_define(coms[0]) + " Is Undefined!";
}
void output(string output_text = "", string end = "\n") { // 格式化输出
cout << output_text << end;
cout << flush; // 刷新缓冲区,防止内容停在其中
}
string input(string input_text = "") { // 获取输入
output(input_text, "");
string res;
getline(cin, res);
return res;
}
void cls() { // 清屏
output("\033[2J\033[1;1H", "");
}
// 转译符号
map<string, pair<string, string>> translate_log_type = {{"i", {NC, "INFO"}}, {"w", {YELLOW, "WARN"}}, {"e", {RED, "ERROR"}}};
void output_log(string type, string content) { // 输出日志
if (translate_log_type[type].second == "") {
type = add_define(type);
output_log("w", "Unknown log type: " + type + ".");
return;
}
string color;
color = translate_log_type[type].first;
type = translate_log_type[type].second;
output("[ " + color + BD + type + NC + " ]: ", "");
output(content);
// output("[ " + to_string(get_now_time()) + " ]: " + content);
}
void confirm_input(string command) { // 固着输入
string res;
res = get_theme_confirm_text(command);
output("\033[1A\033[2K"); // 回到并清空上一行
output("\033[1A" + res); // 回到上一行输出
}
void init_system() { // 初始化
output_log("i", "Initializing System...");
output_log("i", "Initializing File System...");
output_log("i", "Adding Root Section...");
path.push_back(root);
vector<ll> root_fs;
children.push_back(root_fs);
file_system.push_back(root);
output_log("i", "Root Section Added.");
output_log("i", "File System Initialized.");
output_log("i", "Initialized System.");
}
void load_system() { // 从磁盘上加载文件系统
output_log("i", "Loading System...");
path.push_back(root);
file_system = loadVectorBinary("fs.fs");
children = loadVector2DBinary("fs_children.vll");
output_log("i", "Loaded.");
}
signed save_system() { // 保存系统
output_log("i", "Saving System...");
saveVectorBinary(file_system, "fs.fs");
saveVector2DBinary(children, "fs_children.vll");
output_log("i", "Saved.");
return 0;
}
signed neofetch() { // 系统信息输出
string split_str = "";
string main_str = TC + BD + host_name + NC + "@" + TC + BD + now_ip + NC;
string main_str2 = host_name + "@" + now_ip;
for (ll i=1; i <= (ll)main_str2.length(); i++) split_str += "-";
string colorful_str = "", unit = " ";
colorful_str = BG_RED + unit + BG_GREEN + unit + BG_YELLOW + unit + BG_MAGENTA + unit + BG_CYAN + unit + BG_WHITE + unit + NC;
output(" .-'''-. " + main_str);
output(" .' `. " + split_str);
output(" / \\ " + TC + BD + "OS" + NC + ": Fs Operation System");
output(" " + TC + "_..._" + NC + " | | " + TC + BD + "Kernel" + NC + ": 1.0.0-test");
output(" " + TC + ".' '." + NC + " | | " + TC + ".' '." + NC + " " + TC + BD + "Terminal" + NC + ": Fs Bash (Builtin)");
output(" " + TC + "/ .-''-. \\" + NC + " \\ / " + TC + "/ .-''-. \\" + NC + " " + TC + BD + "CPU" + NC + ": Virtual Core 2");
output(" " + TC + "| / \\ |" + NC + " '-._____.-' " + TC + "| / \\ |" + NC + " " + TC + BD + "GPU" + NC + ": Builtin");
output(" " + TC + "| | | |" + NC + " _.-' `-. " + TC + "| | | |" + NC + " " + TC + BD + "Memory" + NC + ": Unknown / Unknown");
output(" " + TC + "\\ \\ / /" + NC + " / \\ " + TC + "\\ \\ / /" + NC + " ");
output(" " + TC + "'.`-...-' .'" + NC + " | | " + TC + "'.`-...-' .'" + NC + " " + colorful_str);
output(" " + TC + "`.__.'" + NC + " \\ / " + TC + "`.__.'" + NC + " ");
output(" '-...___...-' ");
return 0;
}
void welcome_page() { // 欢迎页
cls();
// 欢迎文字
neofetch();
output("");
output("Welcome to FsOS!");
output("");
output("");
}
void split_command(vector<string> *coms, string command) { // 分割接收到的命令
string now_com = "";
bool in_com = 0;
bool commed = 0;
for (auto i : command) {
if (i == ' ' && !in_com) {
if (now_com != "" || commed)
coms->push_back(now_com);
now_com = "";
commed = 0;
continue;
}
if (i == '"') {
in_com = !in_com;
if (!in_com) commed = 1;
continue;
}
now_com += i;
}
if (now_com != "" || commed) coms->push_back(now_com);
}
void help() { // 帮助页
output(BD + "help" + NC + ": Show this page.");
output(BD + "clear" + NC + ": Clear the Content of the Terminal.");
output(BD + "whoami" + NC + ": Show Your Username.");
output(BD + "whereami" + NC + ": Show Your Working Directory.");
output(BD + "ls" + NC + ": List Files and Folders.");
output(BD + "cd" + NC + ": Change Working Directory.");
output(BD + "touch" + NC + ": Create Files.");
output(BD + "mkdir" + NC + ": Create Folders");
output(BD + "echo" + NC + ": Output the input");
output(BD + "neofetch" + NC + ": Show System Info.");
output(BD + "exit" + NC +": Exit the Shell.");
output("");
output("Tip: You Can Use " + add_define("[content]")+ " to Input a Space-contained Text.");
output("");
}
ll get_now_id() { // 获取工作目录 ID
return path[path.size()-1].id;
}
bool exist_dir(string dirname, ll now_dir_id=get_now_id()) { // 判断文件夹是否存在
for (auto i : children[now_dir_id]) {
if (file_system[i].type == "deleted") continue;
if (file_system[i].name == dirname && file_system[i].type == "dir") {
return 1;
}
}
return 0;
}
bool have_space(string x) { // 判断是否有空格
for (auto i : x) {
if (i == ' ') {
return 1;
}
}
return 0;
}
bool ls_cmp(ll x, ll y) { // 文件列表排序
if (file_system[x].type == file_system[y].type) {
return file_system[x].name < file_system[y].name;
}
else {
if (file_system[x].type == "dir") return 1;
else return 0;
}
}
signed ls() { // 浏览当前目录下的文件
ll now_dir_id = get_now_id();
vector<ll> ls_ids;
for (auto i : children[now_dir_id]) {
if (file_system[i].type == "deleted") continue;
ls_ids.push_back(i);
}
sort(ls_ids.begin(), ls_ids.end(), ls_cmp); // 排序(文件夹在前,文件在后,字典序)
for (auto i : ls_ids) {
fs now_file = file_system[i];
if (have_space(now_file.name)) now_file.name = add_define(now_file.name);
if (now_file.type == "dir") output(CYAN + BD, "");
output(now_file.name, " " + NC);
}
if (ls_ids.size() > 0) output();
return 0;
}
pair<signed, ll> mkdir_re(ll now_dir_id, bool flag, bool loop_make) { // 实际创建目录
if (exist_dir(coms[1], now_dir_id)) {
if (!flag) {
for (auto i : children[now_dir_id]) {
if (file_system[i].type == "deleted") continue;
if (file_system[i].type == "dir" && file_system[i].name == coms[1]) {
return {0, file_system[i].id};
}
}
}
output_log("e", "The dir " + add_define(coms[1]) + " has already existed!");
return {1, -1};
}
if (!loop_make && !flag) { // 中途有一个文件夹不对
output_log("e", "The dir " + add_define(coms[1]) + " does not exist!");
return {1, -1};
}
string new_dir_name = coms[1];
fs new_dir;
new_dir.id = file_system.size();
new_dir.name = new_dir_name;
new_dir.type = "dir";
file_system.push_back(new_dir);
children[now_dir_id].push_back(new_dir.id);
vector<ll> new_children;
children.push_back(new_children);
return {0, new_dir.id};
}
vector<string> split_dirs; // 分割目录
signed split_dir(string dirname) {
split_dirs.clear();
string now_str = "";
for (auto i : dirname) {
if (i == '/' || i == '\\') {
if (now_str != "") {
if (now_str == ".." && split_dirs.size() >= 1) {
split_dirs.pop_back();
}
else {
if (!(now_str == ".")) split_dirs.push_back(now_str);
}
}
now_str = "";
continue;
}
now_str += i;
}
if (now_str != "") {
split_dirs.push_back(now_str);
}
return 0;
}
signed mkdir() { // 创建目录
if (coms.size() <= 1) {
output("MKDIR");
output(" Usage: mkdir [dirname]");
output(" Create a folder.");
output("");
return 0;
}
string new_dir_name = coms[1];
coms[1] = "";
split_dir(new_dir_name);
bool loop_make = 0;
for (ll i=2; i < (ll)coms.size(); i++) {
if (coms[i] == "-p") {
loop_make = 1;
}
}
vector<ll> now_dir_id;
for (auto i : path) {
now_dir_id.push_back(i.id);
}
for (ll j=0; j < (ll)split_dirs.size(); j++) {
auto i = split_dirs[j];
coms[1] = i;
if (coms[1] == "..") {
now_dir_id.pop_back();
if (now_dir_id.size() == 0) {
output_log("e", "The route is out of the root.");
return 1;
}
continue;
}
auto code = mkdir_re(now_dir_id[now_dir_id.size()-1], j == (ll)split_dirs.size()-1, loop_make);
if (code.first == 1) return 1;
now_dir_id.push_back(code.second);
}
now_dir_id.clear();
return 0;
}
signed cd_re() { // 实际切换目录
string cd_name = coms[1];
if (cd_name == "..") { // 返回上一级目录
path_str = path_str.substr(0, path_str.length() - path[path.size()-1].name.length() - 1);
path.pop_back();
if (path.size() == 0) {
output_log("e", "The route is out of the root.");
return 1;
}
return 0;
}
if (!exist_dir(cd_name)) {
output_log("e", "The dir " + add_define(cd_name) + " does not exist!");
return 1;
}
fs cdir;
ll now_dir_id = get_now_id();
for (auto i : children[now_dir_id]) {
if (file_system[i].type == "deleted") continue;
if (file_system[i].type == "dir" && file_system[i].name == cd_name) {
cdir = file_system[i];
break;
}
}
path.push_back(cdir);
path_str += cdir.name + "/";
return 0;
}
signed cd() { // 切换目录
if (coms.size() == 1) {
path.clear();
path.push_back(root);
path_str = "/";
return 0;
}
string cd_dir_name = coms[1];
coms[1] = "";
string bak_path_str = path_str;
vector<fs> bak_path = path;
split_dir(cd_dir_name);
for (auto i : split_dirs) {
coms[1] = i;
auto code = cd_re();
if (code == 1) {
// 出错了,恢复回去
path_str = bak_path_str;
path = bak_path;
return 1;
}
}
return 0;
}
signed touch() { // 创建文件
if (coms.size() <= 1) {
output("TOUCH");
output(" Usage: touch [file_name]");
output(" Create a file.");
output("");
return 0;
}
string file_path = coms[1];
split_dir(file_path);
string file_name = split_dirs[split_dirs.size() - 1];
split_dirs.pop_back();
// 判断文件名中是否只有“.”(不合法)
bool flag = 1;
for (auto i : file_name) {
if (i != '.') {
flag = 0;
break;
}
}
if (flag) {
output_log("e", "The filename " + add_define(file_name) + " is illegal.");
return 1;
}
// 获取文件的路径
vector<ll> file_dir_id;
for (auto i : path) file_dir_id.push_back(i.id);
for (auto i : split_dirs) {
if (i == "..") {
file_dir_id.pop_back();
if (file_dir_id.size() == 0) {
output_log("e", "The route is out of the root.");
return 1;
}
continue;
}
bool flag = 0;
for (auto j : children[file_dir_id[file_dir_id.size()-1]]) {
auto now_f = file_system[j];
if (now_f.type == "deleted") continue;
if (now_f.type == "dir" && now_f.name == i) {
file_dir_id.push_back(now_f.id);
flag = 1;
break;
}
}
if (!flag) {
output_log("e", "The dir " + add_define(i) + " is not exist!");
return 1;
}
}
// 查看是否已经存在
for (auto i : children[file_dir_id[file_dir_id.size()-1]]) {
auto now_f = file_system[i];
if (now_f.type == "deleted") continue;
if (now_f.type == "file" && now_f.name == file_name) {
return 0;
}
}
fs new_file;
new_file.name = file_name;
new_file.type = "file";
new_file.content = "";
new_file.id = file_system.size();
file_system.push_back(new_file);
children[file_dir_id[file_dir_id.size()-1]].push_back(new_file.id);
children.push_back(vector<ll>());
return 0;
}
signed cat() { // 查看文件
if (coms.size() <= 1) {
output("CAT");
output(" Usage: cat [file_name]");
output(" view a file.");
output("");
return 0;
}
string file_path = coms[1];
split_dir(file_path);
string file_name = split_dirs[split_dirs.size() - 1];
split_dirs.pop_back();
// 判断文件名中是否只有“.”(不合法)
bool flag = 1;
for (auto i : file_name) {
if (i != '.') {
flag = 0;
break;
}
}
if (flag) {
output_log("e", "The filename " + add_define(file_name) + " is illegal.");
return 1;
}
// 获取文件的路径
vector<ll> file_dir_id;
for (auto i : path) file_dir_id.push_back(i.id);
for (auto i : split_dirs) {
if (i == "..") {
file_dir_id.pop_back();
if (file_dir_id.size() == 0) {
output_log("e", "The route is out of the root.");
return 1;
}
continue;
}
bool flag = 0;
for (auto j : children[file_dir_id[file_dir_id.size()-1]]) {
auto now_f = file_system[j];
if (now_f.type == "deleted") continue;
if (now_f.type == "dir" && now_f.name == i) {
file_dir_id.push_back(now_f.id);
flag = 1;
break;
}
}
if (!flag) {
output_log("e", "The dir " + add_define(i) + " is not exist!");
return 1;
}
}
// 查看是否已经存在
fs cat_file;
flag = 0;
for (auto i : children[file_dir_id[file_dir_id.size()-1]]) {
auto now_f = file_system[i];
if (now_f.type == "deleted") continue;
if (now_f.type == "file" && now_f.name == file_name) {
flag = 1;
cat_file = now_f;
break;
}
}
if (!flag) { // 找不到
output_log("e", "The file " + add_define(file_name) + " is not exist!");
return 1;
}
output(cat_file.content);
return 0;
}
signed write_file(string filename, string file_content) { // 写入文件
split_dir(filename);
string file_name = split_dirs[split_dirs.size() - 1];
split_dirs.pop_back();
// 判断文件名中是否只有“.”(不合法)
bool flag = 1;
for (auto i : file_name) {
if (i != '.') {
flag = 0;
break;
}
}
if (flag) {
output_log("e", "The filename " + add_define(file_name) + " is illegal.");
return 1;
}
// 获取文件的路径
vector<ll> file_dir_id;
for (auto i : path) file_dir_id.push_back(i.id);
for (auto i : split_dirs) {
if (i == "..") {
file_dir_id.pop_back();
if (file_dir_id.size() == 0) {
output_log("e", "The route is out of the root.");
return 1;
}
continue;
}
bool flag = 0;
for (auto j : children[file_dir_id[file_dir_id.size()-1]]) {
auto now_f = file_system[j];
if (now_f.type == "deleted") continue;
if (now_f.type == "dir" && now_f.name == i) {
file_dir_id.push_back(now_f.id);
flag = 1;
break;
}
}
if (!flag) {
output_log("e", "The dir " + add_define(i) + " is not exist!");
return 1;
}
}
// 查看是否已经存在
ll tmp_file;
flag = 0;
for (auto i : children[file_dir_id[file_dir_id.size()-1]]) {
auto now_f = file_system[i];
if (now_f.type == "deleted") continue;
if (now_f.type == "file" && now_f.name == file_name) {
flag = 1;
tmp_file = now_f.id;
break;
}
}
if (!flag) { // 找不到
output_log("e", "The file " + add_define(file_name) + " is not exist!");
return 1;
}
file_system[tmp_file].content = file_content;
return 0;
}
signed echo() { // 输出内容
if (coms.size() == 1) {
output("ECHO");
output(" Usage1: echo [content]");
output(" Output the Content");
output(" Usage2: echo [content] > [filename]");
output(" Output the Content to a File");
output("");
return 0;
}
if (coms.size() == 2) {
output(coms[1]);
return 0;
}
if (coms[2] == ">") { // 输出内容至文件
if (coms.size() <= 3 || coms[3] == "") {
output_log("e", "The Pipe Cannot Be Found!");
return 0;
}
return write_file(coms[3], coms[1]);
}
else {
for (ll i=1; i < (ll)coms.size(); i++) {
output(coms[i], " ");
}
output("");
}
return 0;
}
ll tree_dir_cnt, tree_file_cnt;
void tree_re(ll now_id, ll tab) { // 实际输出树状目录结构
string tabs = ""; // 缩进
for (ll i=1; i <= tab; i++) {
if (i % 4 == 1) tabs += "|";
tabs += " ";
}
vector<ll> ls_ids;
for (auto i : children[now_id]) {
if (file_system[i].type == "deleted") continue;
ls_ids.push_back(i);
}
sort(ls_ids.begin(), ls_ids.end(), ls_cmp); // 排序(文件夹在前,文件在后,字典序)
ll tmp_cnt = 0;
for (auto i : ls_ids) {
// 格式化输出
output(tabs, "");
if (tmp_cnt == (ll)ls_ids.size() - 1)
output("`", "");
else
output("|", "");
output("-- ", "");
fs now_file = file_system[i];
if (have_space(now_file.name)) now_file.name = add_define(now_file.name);
if (now_file.type == "dir") output(CYAN + BD, "");
output(now_file.name + NC);
if (now_file.type == "dir") {
// 递归输出
tree_re(now_file.id, tab + 4);
}
if (now_file.type == "dir") tree_dir_cnt++;
else tree_file_cnt++;
tmp_cnt++;
}
}
signed tree() { // 输出树状目录结构
tree_dir_cnt = 0;
tree_file_cnt = 0;
ll now_dir_id = get_now_id();
output(CYAN + BD + "." + NC);
tree_re(now_dir_id, 0);
output();
output(to_string(tree_dir_cnt) + " directories, " + to_string(tree_file_cnt) + " files");
return 0;
}
signed rm_file(string filename) {
split_dir(filename);
string file_name = split_dirs[split_dirs.size() - 1];
split_dirs.pop_back();
// 判断文件名中是否只有“.”(不合法)
bool flag = 1;
for (auto i : file_name) {
if (i != '.') {
flag = 0;
break;
}
}
if (flag) {
output_log("e", "The filename " + add_define(file_name) + " is illegal.");
return 1;
}
// 获取文件的路径
vector<ll> file_dir_id;
for (auto i : path) file_dir_id.push_back(i.id);
for (auto i : split_dirs) {
if (i == "..") {
file_dir_id.pop_back();
if (file_dir_id.size() == 0) {
output_log("e", "The route is out of the root.");
return 1;
}
continue;
}
bool flag = 0;
for (auto j : children[file_dir_id[file_dir_id.size()-1]]) {
auto now_f = file_system[j];
if (now_f.type == "deleted") continue;
if (now_f.type == "dir" && now_f.name == i) {
file_dir_id.push_back(now_f.id);
flag = 1;
break;
}
}
if (!flag) {
output_log("e", "The dir " + add_define(i) + " is not exist!");
return 1;
}
}
// 查看是否已经存在
ll tmp_file;
flag = 0;
for (auto i : children[file_dir_id[file_dir_id.size()-1]]) {
auto now_f = file_system[i];
if (now_f.type == "deleted") continue;
if (now_f.type == "file" && now_f.name == file_name) {
flag = 1;
tmp_file = now_f.id;
break;
}
}
if (!flag) { // 找不到
output_log("e", "The file " + add_define(file_name) + " is not exist!");
return 1;
}
file_system[tmp_file].type = "deleted";
return 0;
}
signed rm_dir(string dirname) {
split_dir(dirname);
string dir_name = split_dirs[split_dirs.size() - 1];
split_dirs.pop_back();
// 判断文件夹名中是否只有“.”(不合法)
bool flag = 1;
for (auto i : dir_name) {
if (i != '.') {
flag = 0;
break;
}
}
if (flag) {
output_log("e", "The dirname " + add_define(dir_name) + " is illegal.");
return 1;
}
// 获取文件夹的路径
vector<ll> file_dir_id;
for (auto i : path) file_dir_id.push_back(i.id);
for (auto i : split_dirs) {
if (i == "..") {
file_dir_id.pop_back();
if (file_dir_id.size() == 0) {
output_log("e", "The route is out of the root.");
return 1;
}
continue;
}
bool flag = 0;
for (auto j : children[file_dir_id[file_dir_id.size()-1]]) {
auto now_f = file_system[j];
if (now_f.type == "deleted") continue;
if (now_f.type == "dir" && now_f.name == i) {
file_dir_id.push_back(now_f.id);
flag = 1;
break;
}
}
if (!flag) {
output_log("e", "The dir " + add_define(i) + " is not exist!");
return 1;
}
}
// 查看是否已经存在
ll tmp_file;
flag = 0;
for (auto i : children[file_dir_id[file_dir_id.size()-1]]) {
auto now_f = file_system[i];
if (now_f.type == "deleted") continue;
if (now_f.type == "dir" && now_f.name == dir_name) {
flag = 1;
tmp_file = now_f.id;
break;
}
}
if (!flag) { // 找不到
output_log("e", "The dir " + add_define(dir_name) + " is not exist!");
return 1;
}
file_system[tmp_file].type = "deleted";
return 0;
}
signed rm() { // 删除文件夹 / 文件
if (coms.size() <= 1) {
output("RM");
output(" Usage1: rm [filename]");
output(" Delete a File");
output(" Usage2: rm [dirname] -r");
output(" Delete a Folder.");
output("");
return 0;
}
if (coms.size() == 2) {
return rm_file(coms[1]);
}
if (coms[2] == "-r") {
return rm_dir(coms[1]);
}
return 0;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
if (fileExists("fs.fs")) {
load_system();
}
else init_system();
welcome_page();
signed code = 0;
while (true) {
// 输入
string command;
command = input(get_theme_input_text(code));
confirm_input(command); // 将输出固定
// 执行码初始化
code = 0;
split_command(&coms, command);
if (coms.size() > 0) {
string com_type = coms[0];
if (com_type == "exit") {
save_system();
return 0;
}
else if (com_type == "help") {
help();
}
else if (com_type == "whoami") {
output(now_user);
}
else if (com_type == "whereami") {
output(path_str);
}
else if (com_type == "clear") {
cls();
}
else if (com_type == "neofetch") {
code = neofetch();
}
else if (com_type == "ls") {
code = ls();
}
else if (com_type == "mkdir") {
code = mkdir();
}
else if (com_type == "cd") {
code = cd();
}
else if (com_type == "touch") {
code = touch();
}
else if (com_type == "cat") {
code = cat();
}
else if (com_type == "echo") {
code = echo();
}
else if (com_type == "tree") {
code = tree();
}
else if (com_type == "rm") {
code = rm();
}
else {
output_log("e", get_theme_command_not_found_text());
code = 1;
}
}
if (code) wrong_cnt++;
else wrong_cnt = 0;
coms.clear(); // 释放空间
}
return 0;
}
正文完

