#include<iostream>
#include "file.h"
using namespace std;
#define FREE_INODE_NUMBER 0
#define FREE_BLOCK_NUMBER 0
#define ROOT_INODE_NUMBER 1 // 根目录索引节点号
#define PRO_SET_COMM_COU 14
const char *PRO_SET_COMM[] = {"help","ufsman", "Read", "ls", "mkdir", "cpin", "cd", "pwd", "exit","cat","cpout","cp","rm","rmdir"};
typedef struct {
int start_block; // 起始块,每个region从块边界开始
int block_count; // region占用的块个数
int byte_count; // region占用的字节个数
// byte_count <= block_count * BLOCK_SIZE
} region_t;
typedef struct {
int magic;
int total_block_count;
int inode_count;
region_t inode_table_bitmap;
region_t inode_table;
region_t data_area_bitmap;
region_t data_area;
} super_block_t;
//目录项格式
typedef struct {
char name[14]; // 目录项名称
int ino; // 索引节点号
}dir_t;
typedef enum {
INODE_REGULAR, // 普通文件,文本文件或则二进制文件
INODE_DIR, // 目录文件
INODE_LINK, // 本次实验不用,忽略
} type_t;
//索引节点格式
#define MAX_DISK_ADDRESS 6
typedef struct {
type_t type; // 文件类型
int size; // 文件大小
int disk_address[MAX_DISK_ADDRESS]; // 文件占有的磁盘块
} inode_t;
file fl;//磁盘文件
super_block_t block;//超级快
unsigned char inode_bit[2];
unsigned char data_bit[8];
char path[30]="/";//文件路径
int path_num = 1; //索引所在索引快
char name[30];//用于保存文件名称。
//用于分解输入字符串,去掉空格字符。
int clearBlank(char *str,int i)
{
for(;str[i]==' ';)
i++;
return i;
}
//显示帮助
void help()
{
cout<<" help 显示帮助 example: help "<<endl;
cout<<" ufsman --mkfs 格式化磁盘 ufsman --mkfs a.img "<<endl;
cout<<" ufsman 打开已建磁盘 ufsman a.img "<<endl;
cout<<" ls 列出当前目录下的文件: ls or ls a/b "<<endl;
cout<<" cat 打印文件内容 cat a.txt "<<endl;
cout<<" cp 复制文件 cp source.txt ident.txt "<<endl;
cout<<" cpin 将本机文件copy到disk.img中 cpin source.txt ident.txt "<<endl;
cout<<" cpout 将disk.img中文件copy到本机中 cpout source.txt ident.txt "<<endl;
cout<<" cd 改变当前路径 cd a/b "<<endl;
cout<<" pwd 打印当前路径 pwd "<<endl;
cout<<" rm 删除文件 rm a.txt "<<endl;
cout<<" mkdir 删除目录文件 mkdir p "<<endl;
cout<<" exit 退出系统 exit "<<endl;
}
void initDisk(char *str)
{
int i;
super_block_t block;
fl.open_w(str);
block.total_block_count= 71;
block.inode_count = 16;
block.inode_table_bitmap.start_block=1;
block.inode_table_bitmap.block_count=1;
block.inode_table_bitmap.byte_count=2;
block.inode_table.start_block=2;
block.inode_table.block_count=4;
block.inode_table.byte_count=512;
block.data_area_bitmap.start_block=6;
block.data_area_bitmap.block_count=1;
block.data_area_bitmap.byte_count=8;
block.data_area.start_block=7;
block.data_area.block_count=64;
block.data_area.byte_count=8192;
// fl.diskfile.write((char *)a,sizeof(a));
fl.diskfile.write((char *)&block,sizeof(block));
// fl.diskfile.read((char *)a,sizeof(a));
unsigned char b[2];
b[0]=0xC0;
b[1]=0x00;
fl.lseekp(1,0);
fl.diskfile.write((char*)b,sizeof(b));
inode_t inode;
inode.type= INODE_DIR;
inode.size=36;
inode.disk_address[0]=7;
for(i=1;i<6;i++)
{
inode.disk_address[i]=-1;
}
fl.lseekp(2,32);
fl.diskfile.write((char*)&inode,sizeof(inode));
unsigned char c[8];
c[0]=0x80;
c[1]=0x00;
c[2]=0x00;
c[3]=0x00;
c[4]=0x00;
c[5]=0x00;
c[6]=0x00;
c[7]=0x00;
fl.lseekp(6,0);
fl.diskfile.write((char*)c,sizeof(c));
dir_t dir1[6];
strcpy(dir1[0].name,"..");
dir1[0].ino=1;
strcpy(dir1[1].name,".");
dir1[1].ino=1;
for(i=2;i<6;i++)
{
dir1[i].ino=-1;
}
fl.lseekp(7,0);
fl.diskfile.write((char*)dir1,sizeof(dir1));
fl.close();
}
void openDisk(char *str)
{
fl.open_r(str);
fl.diskfile.read((char*)&block,sizeof(block));
fl.lseekg(1,0);
fl.diskfile.read((char*)inode_bit,sizeof(inode_bit));
fl.lseekg(6,0);
fl.diskfile.read((char*)data_bit,sizeof(data_bit));
fl.close();
}
void Read()
{
fl.diskfile.open("a.txt",ios::in|ios::binary);
// super_block_t block;
char a[8];
inode_t type;
fl.lseekg(2,0);
// fl.diskfile.read((char*)&block,sizeof(block));
// cout<<block.inode_count;
fl.diskfile.read((char*)&type,sizeof(type));
cout<<type.size<<" "<<type.disk_address[0];
}
int find_inode(int num,char *str)//给目录索引节点查找相应索引节点号
{
int block_num=-1;
int i=0,j;
dir_t dir[6];
inode_t inode;
fl.open_r(name);
fl.lseekg(block.inode_table.start_block,num*32);//每个索引节点占32B
fl.diskfile.read((char*)&inode,sizeof(inode));
if(inode.type!=INODE_DIR)
{
return 0;
}
while(inode.disk_address[i]!=-1)
{
fl.lseekg(inode.disk_address[i],0);
fl.diskfile.read((char*)dir,sizeof(dir));
j=0;
while(dir[j].ino!=-1)
{
if(strcmp(dir[j].name,str)==0)
block_num=dir[j].ino;
j++;
}
i++;
}
fl.close();
if(block_num==-1)
return 1;
else
return block_num;
}
void ls() //无参数列表
{
int i=0,j=0;
inode_t inode;
inode_t inode_1;
dir_t dir[6];
fl.open_r(name);
fl.lseekg(block.inode_table.start_block,path_num*32);
fl.diskfile.read((char*)&inode,sizeof(inode));
while(inode.disk_address[i]!=-1)
{
fl.lseekg(inode.disk_address[i],0);
fl.diskfile.read((char*)dir,sizeof(dir));
j=0;
while(dir[j].ino!=-1)
{
cout<<dir[j].ino<<" ";
cout<<dir[j].name<<" ";
fl.lseekg(2,dir[j].ino*32);
fl.diskfile.read((char*)&inode_1,sizeof(inode_1));
cout<<inode_1.size<<endl;
j++;
}
i++;
}
fl.close();
}
//根据相应路径找到相应的索引节点
int findPath(char *path)
{
int search_inode=1;
char str[20];
int i=0,j=0;
while(path[i]!='\0')
{
while(path[i]!='/'&&path[i]!='\0')
{
str[j]=path[i];
i++;
j++;
}
str[j]='\0';
if(path[i]=='\0')
break; //代表结束
search_inode=find_inode(search_inode,str);
i++;
j=0;
}
return search_inode;
}
int findPath2(char *path)
{
int search_inode=1;
char str[20];
int i=0,j=0;
while(path[i]!='\0')
{
while(path[i]!='/'&&path[i]!='\0')
{
str[j]=path[i];
i++;
j++;
}
str[j]='\0';
search_inode=find_inode(search_inode,str);
if(path[i]=='\0')
break; //代表结束
i++;
j=0;
}
return search_inode;
}
void lss(char *str)//有参数列表
{
int inode_now;
inode_now=findPath(str) ;
int i=0,j=0;
inode_t inode;
inode_t inode_1;
dir_t dir[6];
fl.open_r(name);
fl.lseekg(block.inode_table.start_block,inode_now*32);
fl.diskfile.read((char*)&inode,sizeof(inode));
while(inode.disk_address[i]!=-1)
{
fl.lseekg(inode.disk_address[i],0);
fl.diskfile.read((char*)dir,sizeof(dir));
j=0;
while(dir[j].ino!=-1)
{
cout<<dir[j].ino<<" ";
cout<<dir[j].name<<" ";
fl.lseekg(2,dir[j].ino*32);
fl.diskfile.read((char*)&inode_1,sizeof(inode_1));
cout<<inode_1.size<<endl;
j++;
}
i++;
}
fl.close();
}
//查找索引节点视图,找到第一个未用的索引空节点
int find_free_inode_bit()
{
unsigned char temp = 0x80; //用于右移,检测第一个未用的索引节点
int i,j,z=0; //z用来测试是否已经找到
int inode_num=0; //用于标识找到的节点号。
for(i=0;i<2;i++)
{
for(j=0