Linux 文件系统实现代码
2017-03-05 14:31
501 查看
/* * 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/1 float 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(); else inode->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 012 bool 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(); } else dentryname = (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); 创建/home createDirect("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); //home char* 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(); } else return; } } 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; } else return; } 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(); } else return; } //向前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/1 void 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(); } else return; } //实现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") //help help(); 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; }
相关文章推荐
- Linux实用代码(1)--文件系统操作
- linux系统调用实现代码分析
- (cc)2.6版本Linux上替换系统调用函数实现隐藏文件学习
- Linux 下几个文件操作命令的代码实现
- Linux 下几个文件操作命令的代码实现
- 2.6版本Linux上替换系统调用函数实现隐藏文件学习
- linux 2.6.11内核文件IO的系统调用实现分析(read,write)(转载)
- Linux 下几个文件操作命令的代码实现
- 嵌入式linux下jffs2文件系统的实现
- linux系统调用实现代码分析
- Linux实用代码--文件系统操作
- linux系统调用之文件:递归实现pwd
- [zt] Linux 下几个文件操作命令的代码实现
- YAFFS文件系统在嵌入式Linux上的实现
- Linux系统实现跨平台共享文件
- Linux实用代码--文件系统操作
- Linux下简单配置SAMBA服务,实现与Windows系统文件共享.
- 如何实现虚拟客户机linux系统与主机Windows的文件共享或互访?
- Linux 下几个文件操作命令的代码实现
- Linux 下几个文件操作命令的代码实现(转载)