Linux 文件系统实现代码

来源:互联网 发布:火牛软件网 编辑:程序博客网 时间:2024/06/07 13:39
/* * main.cpp * *  */#include <iostream>#include <stdlib.h>#include<string.h>#include<curses.h>using namespace std;typedef struct User{string name[30];string passwd[30];int n;} User, u;typedef struct Priv{char read;char write;char execute;} Priv, priv[3];//记录文件信息。name表示第几块,用disk模拟typedef struct DataStock{int name;  //第几盘块号int stock_num;struct DataStock *next;} DataStock, *ds;// 一个节点信息,可能是一个目录或者一个文件。// 如果是一个目录,那么下面会有子目录childnode, inode_num,//记录子目录项的数目typedef struct Inode{int inode_num;int type; //文件类型,文件/目录  0/1float size;Priv *priv;char* owneruser;struct tm *createtime;struct Inode** childnode;struct DataStock *datastock;} Inode;//一个目录项,typedef struct Dentry{string name;struct Inode *inode;} Dentry;int number = 1000;//默认路径是/home, 用户名是" ".string rootDirect = "/home";string currentUser = " ";string currentPath = rootDirect;User user;Dentry dentry[1000];int of_record = 0;int record = -1;//磁盘块int disk_record = 0;//记录使用了多少磁盘块int disk_stock = 3; //三个字节为一个盘块string *disk = new string[number]; //模拟磁盘存储  1000个磁盘块int firstempty = 0;// 命令行int command_number = 10;int command_record = 0;string *commandsave = new string[command_number];int umask_direct = 775;int umask_file = 664;void test(){for (int i = 0; i < disk_record; i++){cout << disk[i];}}void showDisk(){for (int i = 0; i < disk_record; i++){cout << "第" << i << "个磁盘块:" << disk[i] << endl;}}void output(){cout << "[" << currentUser << "@" << "localhost" << currentPath << "]#";}//数据块节点初始化DataStock *initializeStock(){DataStock *head;head = (DataStock*) malloc(sizeof(DataStock));head->name = -1;head->next = NULL;return head;}//inode节点初始化// 跟踪 // initalizeInode(1,"home",-1)Inode *initializeInode(int type, string u, int p){Inode *inode = NULL;inode = (Inode*) malloc(sizeof(Inode));inode->childnode = (Inode**) malloc(100 * sizeof(Inode*));inode->inode_num = 0;inode->type = type;inode->datastock = initializeStock();inode->size = 0;if(p == 0)inode->owneruser = (char*) u.data();elseinode->owneruser = (char*) currentUser.data();time_t ctime;time(&ctime);inode->createtime = localtime(&ctime);//权限初始化Priv *priv = (Priv*) malloc(sizeof(Priv));if(type == 0) //文件{priv[0].read = 'r';priv[0].write = 'w';priv[0].execute = '-';priv[1].read = 'r';priv[1].write = 'w';priv[1].execute = '-';priv[2].read = 'r';priv[2].write = '-';priv[2].execute = '-';}else{ //目录priv[0].read = 'r';priv[0].write = 'w';priv[0].execute = 'x';priv[1].read = 'r';priv[1].write = 'w';priv[1].execute = 'x';priv[2].read = 'r';priv[2].write = '-';priv[2].execute = '-';}inode->priv = priv;return inode;}//根据目录项名字找对应的目录项Dentry findDentry(char *dentryname){Dentry temp;for (int i = 0; i <= record; i++){if(strcmp((char*) dentry[i].name.data(), dentryname) == 0){temp = dentry[i];break;}}return temp;}//根据inode节点找相对应的目录项Dentry searchDentry(Inode *inode){Dentry temp;for (int i = 0; i <= record; i++){if(dentry[i].inode == inode){temp = dentry[i];break;}}return temp;}//得到当前路径,如/home/root/sxw,最终返回结果为sxw// i+1 - endname.size() 为路径名int getEndPath(string endname){std::cout<<"endname = "<<endname<<std::endl;int i = 0;for (i = endname.size(); i >= 0; i--){if(endname[i] != '/'){continue;}break;}return (i + 1);}int judge(string path){int result = 0;int position = getEndPath(currentPath);char* dentryname =(char*) currentPath.substr(position, currentPath.size()).data();Dentry parent_dt = findDentry(dentryname);Inode *parent_inode = parent_dt.inode;Inode *child_inode = NULL;Dentry child_dt;for (int i = 0; i < parent_inode->inode_num; i++){if((child_inode = parent_inode->childnode[i]) != NULL){child_dt = searchDentry(child_inode);if(child_dt.name == path){if(child_dt.inode->type == 0){result = -1;} else{result = 1;break;}}}}return result;}void split(string command, string end[], char flag){int count = 0;int j = 0;for (int i = 0; i <= command.size(); i++){if(command[i] == flag || i == command.size()){end[j] = command.substr(count, i - count);count = i + 1;j++;}}}void chagePriv(Inode *inode, string seond_result[], char f, int flag){if(f == '+'){if(seond_result[1] == "r")inode->priv[flag].read = 'r';else if(seond_result[1] == "w")inode->priv[flag].write = 'w';else if(seond_result[1] == "x")inode->priv[flag].execute = 'x';} else{if(seond_result[1] == "r")inode->priv[flag].read = '-';else if(seond_result[1] == "w")inode->priv[flag].write = '-';else if(seond_result[1] == "x")inode->priv[flag].execute = '-';}}void chomd(string command){string result[3];string seond_result[2];split(command, result, ' ');int results = judge(result[2]);if(results == 0){cout << "your input is not found!!" << endl;return;} else{split(result[1], seond_result, result[1][1]);Dentry parent_dt = findDentry((char*) result[2].data());Inode *inode = parent_dt.inode;if(strcmp((char*) currentUser.data(), inode->owneruser) == 0|| currentUser == "root"){if(seond_result[0] == "u")chagePriv(inode, seond_result, result[1][1], 0);else if(seond_result[0] == "g")chagePriv(inode, seond_result, result[1][1], 1);else if(seond_result[0] == "o")chagePriv(inode, seond_result, result[1][1], 2);} else{cout << "sorry,当前用户不允许授权!" << endl;}}}//权限判断// target -1 为长路径,  其他为段路径。 flag rwx 012bool isLeagl(string filename, int target, int flag){if(currentUser == "root")return true;int user = 0;char* dentryname;if(target == -1){int position = getEndPath(currentPath);dentryname =(char*) currentPath.substr(position, currentPath.size()).data();} elsedentryname = (char*) filename.data();Dentry dt = findDentry(dentryname);Inode *inode = dt.inode;if(strcmp((char*) currentUser.data(), inode->owneruser) != 0){user = 2;}switch (flag){case 0:if(inode->priv[user].read == '-'){cout << "对不起,权限不够!" << endl;return false;}break;case 1:if(inode->priv[user].write == '-'){cout << "对不起,权限不够!" << endl;return false;}break;case 2:if(inode->priv[user].execute == '-'){cout << "对不起,权限不够!" << endl;return false;}break;}return true;}//创建文件,目录/* * 跟踪createDirect("home", 1, -1); 创建/homecreateDirect("root", 1, -1); 创建/home/root type = 0,创建文件,type = 1 创建目录*/void createDirect(string directname, int type,int p){Inode *inode = NULL;if(directname == "home"){inode = initializeInode(type, directname, p);record++;dentry[record].name = directname;dentry[record].inode = inode;}else{if(isLeagl(directname, -1, 1)){//从当前路径得出文件/目录名称int position = getEndPath(currentPath);//homechar* dentryname = (char*) currentPath.substr(position,currentPath.size()).data();Dentry dt = findDentry(dentryname);record++;Inode *temp = NULL;temp = initializeInode(type, directname, p);dt.inode->childnode[dt.inode->inode_num] = temp;dt.inode->inode_num++;dentry[record].name = directname;dentry[record].inode = temp;// test();}elsereturn;}}void readFile(string filename){if(isLeagl(filename, 1, 0)){int result = judge(filename);if(result == 1){cout << "your input is not file!!" << endl;return;} else if(result == 0){cout << "your input is not found!!" << endl;return;} else{Dentry dt = findDentry((char*) filename.data());Inode *inode = dt.inode;DataStock *ds = inode->datastock;while (ds->next != NULL){DataStock *temp = ds->next;ds = temp;int name = temp->name;cout << disk[name];}}cout << endl;} elsereturn;}void writeFile(string filename){if(isLeagl(filename, 1, 1)){int result = judge(filename);if(result == 1){cout << "your input is not file!!" <<endl;return;} else if(result == 0){cout << "your input is not found!!" << endl;return;} else{Dentry dt = findDentry((char*) filename.data());Inode *inode = dt.inode;string content = " ";getline(cin, content);int size = content.size();// 我修改了盘块float stock_num = (size / disk_stock) + (size%disk_stock ? 1: 0);inode->size += size;DataStock *first = inode->datastock;while (first->next != NULL){first = first->next;}DataStock *head = first;//补充要增加的内容int count = 0;for (int i = 0; i < number; i++){if(i >= disk_record)disk_record++;//向文件追加内容和大小if(disk[i] == ""){DataStock *temp = (DataStock*) malloc(sizeof(DataStock));temp->name = i;temp->next = NULL;head->next = temp;head = temp;if(stock_num > 1){disk[i] = content.substr(count, disk_stock);stock_num--;count = disk_stock + count;} else{disk[i] = content.substr(count, content.size());break;}}}//修改文件夹的大小int position = getEndPath(currentPath);char* dentryname = (char*) currentPath.substr(position,currentPath.size()).data();Dentry parent_dt = findDentry(dentryname);Inode *parent_inode = parent_dt.inode;parent_inode->size = 0;for (int i = 0; i < parent_inode->inode_num; i++){parent_inode->size += parent_inode->childnode[i]->size;}}// test();} elsereturn;}//向前pos移动一个节点void moveInode(Inode *inode, int pos){if(pos != inode->inode_num - 1){for (; pos < inode->inode_num - 1; pos++){inode->childnode[pos] = inode->childnode[pos + 1];}inode->inode_num--;} else{inode->inode_num--;return;}return;}//删除文件,目录操作  0/1void deleteDirect(string directname, int type){if(isLeagl(directname, -1, 1)){int result = judge(directname);if(result == 0){cout << "your input is not found!!" << endl;return;} else{int position = getEndPath(currentPath);char* dentryname = (char*) currentPath.substr(position,currentPath.size()).data();Dentry parent_dt = findDentry(dentryname);Dentry current_dt = findDentry((char*) directname.data());Inode *parent_inode = parent_dt.inode;Inode *current_inode = current_dt.inode;for (int i = 0; i < parent_inode->inode_num; i++){if(parent_inode->childnode[i] == current_inode){parent_inode->childnode[i] = NULL;moveInode(parent_inode, i);if(type == 0){DataStock *ds = current_inode->datastock;// free(current_inode);while (ds->next != NULL){DataStock *temp = ds->next;ds = temp;int name = temp->name;disk[name] = "";memset((char*) disk[name].data(), 0, 3);}}}}}// test();} elsereturn;}//实现ls命令操作列举出当前目录下的所有文件,目录的详细信息void dir(){int position = getEndPath(currentPath);char* dentryname =(char*) currentPath.substr(position, currentPath.size()).data();Dentry parent_dt = findDentry(dentryname);Inode *parent_inode = parent_dt.inode;Inode *child_inode = NULL;Dentry child_dt;string file_type;for (int i = 0; i < parent_inode->inode_num; i++){if((child_inode = parent_inode->childnode[i]) != NULL){child_dt = searchDentry(child_inode);if(child_inode->type == 0)file_type = "文件";else if(child_inode->type == 1)file_type = "目录";cout << file_type << '\t';for (int i = 0; i < 3; i++){cout << child_dt.inode->priv[i].read<< child_dt.inode->priv[i].write<< child_dt.inode->priv[i].execute << '\t';}cout << child_dt.inode->owneruser << '\t' << child_dt.inode->size<< "字节" << '\t' << (child_dt.inode->createtime->tm_mon + 1)<< "月" << '\t' << child_dt.inode->createtime->tm_mday<< '\t' << child_dt.inode->createtime->tm_hour << ":"<< child_dt.inode->createtime->tm_min << '\t'<< child_dt.name << '\t' << endl;}}}//string cinPasswd(){// initscr();// char ch;// string str="";// while((ch=getchar())!='\r')// {// cout<<"*";// str+= ch;// }// endwin();// return str;//}//用户登录void login(string username){bool record = false;cout << "input your passwd please!!" << endl;output();string temp;cin >> temp;for (int i = 0; i < user.n; i++){if((user.name[i]) == username){if(user.passwd[i] == temp){currentUser = username;record = true;cout << username << " login successfully!" << endl;cin.ignore();return;}}}if(!record){cout << "sorry!" << " " << username << " " << "not found" << endl;}return;}void logout(string username){currentUser = user.name[0];cout << "current user logout successfully!!" << endl;}//实现在root用户下添加新用户void addUser(string username){if(currentUser != "root"){cout << "sorry!current user is not root!!" << endl;return;} else{string passwd;cout << "input your passwd please!!" << endl;output();cin >> passwd;user.name[user.n] = username;user.passwd[user.n] = passwd;user.n++;cout << "add user successfully!!" << endl;cin.ignore();createDirect(username, 1, 0);return;}}//实现cd操作进入下个目录void intoNext(string path){if(path == ".."){int position = getEndPath(currentPath);currentPath = currentPath.substr(0, position - 1);} else{int result = judge(path);if(result == -1)cout << "sorry!your entry is not direct" << endl;else if(result == 1)currentPath = currentPath + "/" + path;else if(result == 0)cout << "your entry is not found!" << endl;}}void help(){cout << "ls 列举当前目录下所有目录项" << endl;cout << "pwd 显示当前目录结构 " << endl;cout << "adduser uu 添加新用户uu " << endl;cout << "login root root用户登录 " << endl;cout << "logout 当前用户登出 " << endl;cout << "create ss 创建文件ss " << endl;cout << "rm ss 删除文件ss " << endl;cout << "mkdir ss 创建目录ss " << endl;cout << "rmdir ss 删除目录ss " << endl;cout << "read ss 读文件ss " << endl;cout << "write ss 写文件ss " << endl;cout << "chmod o+w ss 给ss的other用户赋予写的权限 " << endl;}void showWindow(){cout << '\t'<< "***************************************************************"<< endl;cout << '\t' << "**" << " " << "**" << endl;cout << '\t' << "**" << " Linux二级文件系统设计 " << "**" << endl;cout << '\t' << "**" << " " << "**" << endl;cout << '\t' << "**" << " 1,实现文件/目录的创建,删除,打开,关闭,读取,授权等操作 " << "**" << endl;cout << '\t' << "**" << " " << "**" << endl;cout << '\t' << "**" << " 2.模拟linux下如cd,ls,pwd,adduser,chmod等基本命令 " << "**"<< endl;cout << '\t' << "**" << " " << "**" << endl;cout << '\t' << "**" << " 3.文件存储使用内存模拟外存实现,具体操作请使用help命令查询 " << "**"<< endl;cout << '\t'<< "***************************************************************"<< endl;}//实现pwd操作,显示当前目录void showPath(){cout << currentPath << endl;}//程序启动时初始化root用户,创建home和root目录void Initialize(){user.name[0] = "root";user.passwd[0] = "linux";user.n++;currentUser = user.name[0];createDirect("home", 1, -1);createDirect("root", 1, -1);}void saveCommand(string command){if(command_record == number){command_record = 0;commandsave[command_record] = command;commandsave[command_record++] = "";}commandsave[command_record] = command;command_record++;}void Up_BackOpreation(string command){if(command == "w"){if(command_record != 0)command_record--;else if(command_record == 0 && commandsave[command_number] != "")command_record = command_number;} else if(command == "s"){if(commandsave[command_record + 1] != "")command_record++;else if(command[command_record + 1] == command_number)command_record = 0;;}cout << command[command_record];}int commandSolve(string input){std::cout<<"input ="<<input<<std::endl;string first = input.substr(0, input.find(" "));string second = input.substr(input.find(" ") + 1, input.size());if(first == "create")   //创建文件createDirect(second, 0, -1);else if(first == "mkdir")//创建目录createDirect(second, 1, -1);else if(first == "read")    //读文件readFile(second);else if(first == "write")    //写文件writeFile(second);else if(first == "rmdir")    //删除目录deleteDirect(second, 1);else if(first == "rm")       //删除文件deleteDirect(second, 0);else if(first == "chmod")    //修改文件权限chomd(input);else if(first == "login")    //登录login(second);else if(first == "logout")   //退出当前用户,变为root用户logout(currentUser);else if(first == "adduser")  //增加用户addUser(second);else if(first == "pwd")     //显示当前路径showPath();else if(first == "cd")      //切换目录intoNext(second);else if(first == "ls")      // list列出当前目录信息dir();else if(first == "help")    //helphelp();else if(input == "showdisk")//查看目前磁盘使用情况showDisk();else if(input == "")return 0;else{cout << "command error!" << endl;}return 0;}int main(){showWindow();Initialize();string input = " ";while (true){output();getline(cin, input);commandSolve(input);}return 0;}

0 0