您的位置:首页 > 运维架构 > Linux

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: