#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];
typedef struct DataStock
{
int name;
int stock_num;
struct DataStock *next;
}DataStock,*ds;
typedef struct Inode
{
int inode_num;
int type;
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;
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]; //模拟磁盘存储
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节点初始化
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
int getEndPath(string endname)
{
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;
}
}
}
//权限判断
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;
}
//创建文件,目录
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);
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)+1;
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;
}
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;
}
//删除文件,目录操作
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‘<<"**"<<" 操作系统文件系统设计 "<<"**"<<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){
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") logout(currentUser);
else if(first=="adduser") addUser(second);
else if(first=="pwd") showPath();
else if(first=="cd") intoNext(second);
else if(first=="ls") dir();
else if(first=="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;
}