警告:本计算机程序受著作权法和国际条约保护,如未经授权而擅自复制或传播本程序,,将受到严厉的民事制裁和刑事制裁,并将在法律许可的最大程度内受到起诉。
注:本程序采用C语言设计,用C编译器编译后可直接运行,版权归作者本人所有
#include
#include
#include
#include
#include
#define BLOCK_SIZE 1024
#define INODE_SIZE 256
#define MAX_SIZE 1024*1024
#define DISK_SIZE 1024*1024*10
///inode索引数据结构
typedef struct
{
char file_type; //1个字节
char power[4]; //3个字节
char owner[17]; //16个字节
char group[17]; //16个字节
long lenth; //共几个数据项 8B
long point_number[30]; //指向数据块的节点号,前4个为间接地址块儿号码,每个大小为8B
}INODE;
typedef struct{
long parent_dir_inode_num; //8B
long parent_info_data_num; //8B
char file_name[257]; //文件名为255,最后一个是空格,作为文件名结束
char create_time[17]; //创建时间
long link_num; //连接数 8B
long size; //大小 8B
}FILE_INFO;
///超级块信息结构
typedef struct
{
long total_size; //单位为字节
long inode_space_size; //单位为字节
long inode_used_size;
long data_space_size; //单位为字节
long data_used_size;
long block_size; //单位为字节
}SUPER_BLOCK;
///***********************各个磁盘数据的偏移量(相对于磁盘开始文件)***********************/
long super_block_offset;
long inode_index_offset;
long data_index_offset;
long inode_offset;
long data_offset;
///*****************全局变量区**********************************************************/
FILE *disk; //磁盘设备
long current_pwd; //当前目录的inode号码
char disk_name[20]="disk.dev"; //磁盘的名字
char current_user[200]; //当前的Username
char* users[200]; //用户及密码表
char* pass_words[200];
int user_n=0; //共几个用户
long inode_num; //inode 的个数 文件系统载入的时候需要初始化
long data_block_num; //data 的个数 文件系统载入的时候需要初始化
char inode_index[MAX_SIZE]; //文件系统载入的时候需要初始化
char data_block_index[MAX_SIZE]; //文件系统载入的时候需要初始化
INODE inodes[MAX_SIZE]; //inode 的信息 ,文件系统载入的时候需要初始化
SUPER_BLOCK super_block; //磁盘信息
///*****************函数声明区===开始*******************************/
void display(char* command); //显示信息
char* str_trim(char *str,char *res); //去空格函数
void trim(char* str); //去空格函数
char* converse_power(char* power,char* res); //转换权限形式
int find_data_num(long ind_num,long* dt_num); //根据节点号,来查找该文件的详细信息所在的data_num 号码
int find_prt_ind_num_as_ind_num(long ind_num,long* prt_ind_num); //根据给定的inode号码,查找出父目录的indoe号码
int find_prt_ind_num_as_dt_num(long dt_num,long* prt_ind_num); //根据给定的dt_num号码,查找出父目录的indoe号码
int find_file_ind_num(char* file_name,long pwd_num,long* res_ind_num); //根据给定的文件名,在pwd_num目录查找他的ind_num
int alloc_inode(long* ind_num); //申请inode
int alloc_data(long* dt_num); //申请data号
int update_super_blocks(); //更新磁盘信息
int update_inode_index(long num); //更新索引位图 如果num为 -1 则填充0
int update_data_index(long num); //更新索引位图 如果num为 -1 则填充0
int update_inode(INODE ind,long num); //更新inode信息,及两个位图信息
int update_file_info(long dt_num,FILE_INFO file); //只更新文件名信息
int update_file_all_info(long ind_num,FILE_INFO file,INODE ind); //更新文件的所有详细信息
int get_super_blocks(); //得到磁盘信息
int get_inode_index(); //得到索引节点信息(磁盘放到全局变量里边);
int get_data_index(); //得到索引节点信息(磁盘放到全局变量里边);
int get_inode(long ind_num,INODE* ind); //得到文件的inode信息,如果inode_num=-1 则载入到内存
int get_file_info(long dt_num,FILE_INFO* file); //得到文件的大小及创建时间等信息
int get_file_all_info(long ind_num,FILE_INFO* file,INODE* ind); //得到文件的所有详情信息
int update_dir_data(long ind_num,long new_ind_num,long new_dt_num,int op);//更新ind_num目录的子项目信息
int get_dir_data(long ind_num,long* sub_ind_num,long* sub_dt_num,long* lenth);//得到ind_num目录的子项目信息
int load_disk(int reset); //载入文件系统
int init_file();
int make_file(char file_type,char *file_name,long parent_ind_num); //创建【目录】文件
int rm_file(char file_type,char* file_name,long dir_ind_num); //删除【目录】文件
int ls(long dir_ind_num); //显示指定目录下的文件列表信息 该函数需要打开disk文件
int pwork_dir(char* pwd,long ind_num,int f_print); //得到ind_num文件的路径,并可以控制是否输出
int pre_road(); //显示前缀 如 /root/etc zhangxinming@CentOS>#_
int change_drectory(char* dir_name);
int change_own(char* file_name,char* new_owner);
int change_group(char* file_name,char* new_group);
int change_mod(char* file_name,char* new_power);
int read_file(long ind_num,char* file_name,char* res);
int write_file(long ind_num,char*file_name,char* res);
int vim_file(long ind_num,char*file_name);
int have_power(long ind_num,char* file_name,int op);
int user_login();
int load_file_system();
int user_add(char* user_name);
int user_delete(char* user_name);
int pass_wd(char* user_name);
int switch_user(char* user_name);
///*****************函数声明区===结束**************************************************/
///*******************荣光辉==开始*****************************************************/
int switch_user(char* user_name)
{
char* pass_t=(char*)malloc(256);
char c;
int m=0;
memset(pass_t,0,256);
printf("请输入该用户密码:");
// scanf("%s",pass_t);
while ((c=getch())!='\r')
{
*(pass_t+m)=c;
m++;
if(c!='\b') //输入内容不是退格时就显示 “*”号
printf("*");
else //输入内容是退格时 删除前一个 “*”号
printf("\b \b");
}
/* */
*(pass_t+m)='\0';
// printf("pass_t=%s|\n",pass_t);
int i;
for(i=0;iparent_dir_inode_num=atol(temp);
fgets(temp,9,disk); file->parent_info_data_num=atol(temp);
fgets(temp,257,disk);trim(temp); strcpy(file->file_name,temp);
fgets(temp,17,disk);trim(temp);strcpy(file->create_time,temp);
fgets(temp,9,disk);trim(temp);file->link_num=atol(temp);
fgets(temp,9,disk);file->size=atol(temp);
// printf("get_file_info()dt_num=%ld file->size=%ld\n",dt_num,atol(temp));
// printf("templength=%d\ntemp=%s\n",strlen(temp2),temp2);
return 1;
}
int update_file_info(long dt_num,FILE_INFO file) //只更新文件名信息
{
char* temp=(char*)malloc(BLOCK_SIZE*sizeof(char*));
char* temp2=(char*)malloc(BLOCK_SIZE*sizeof(char*));
memset(temp,0,sizeof(char*)*BLOCK_SIZE);
memset(temp2,0,sizeof(char*)*BLOCK_SIZE);
fseek(disk,data_offset+dt_num*BLOCK_SIZE,SEEK_SET);
// printf("update_file_info() dt_num=%ld offset=%ld\n",dt_num,data_offset+dt_num*BLOCK_SIZE);
sprintf(temp2,"%8ld",file.parent_dir_inode_num);
strcat(temp,temp2);
sprintf(temp2,"%8ld",file.parent_info_data_num);
strcat(temp,temp2);
sprintf(temp2,"%256s",file.file_name);
strcat(temp,temp2);
sprintf(temp2,"%16s",file.create_time);
strcat(temp,temp2);
sprintf(temp2,"%8ld",file.link_num);
strcat(temp,temp2);
sprintf(temp2,"%8ld",file.size);
strcat(temp,temp2);
// printf("update_file_info() file.size=%ld temp.length=%d\ntemp=%s\n",file.size,strlen(temp),temp);
fwrite(temp,strlen(temp),1,disk);
return 1;
}
int update_file_all_info(long ind_num,FILE_INFO file,INODE ind) //更新文件的所有详细信息
{
long dt_num;
update_inode(ind,ind_num);
find_data_num(ind_num,&dt_num);
update_file_info(dt_num,file);
return 1;
}
int get_file_all_info(long ind_num,FILE_INFO* file,INODE* ind) //得到文件的所有详情信息
{
long dt_num;
get_inode(ind_num,ind);
find_data_num(ind_num,&dt_num);
get_file_info(dt_num,file);
///未完成
return 1;
}
char* converse_power(char* power,char* res)
{
int j=0;
if(*(power+0)=='7'){*(res+j)='r';j++;*(res+j)='w';j++;*(res+j)='x';j++;}if(*(power+0)=='6'){*(res+j)='r';j++;*(res+j)='w';j++;*(res+j)='-';j++;}
if(*(power+0)=='5'){*(res+j)='r';j++;*(res+j)='-';j++;*(res+j)='x';j++;}if(*(power+0)=='4'){*(res+j)='r';j++;*(res+j)='-';j++;*(res+j)='-';j++;}
if(*(power+0)=='3'){*(res+j)='-';j++;*(res+j)='w';j++;*(res+j)='x';j++;}if(*(power+0)=='2'){*(res+j)='-';j++;*(res+j)='w';j++;*(res+j)='-';j++;}
if(*(power+0)=='1'){*(res+j)='-';j++;*(res+j)='-';j++;*(res+j)='x';j++;}if(*(power+0)=='0'){*(res+j)='-';j++;*(res+j)='-';j++;*(res+j)='-';j++;}
if(*(power+1)=='7'){*(res+j)='r';j++;*(res+j)='w';j++;*(res+j)='x';j++;}if(*(power+1)=='6'){*(res+j)='r';j++;*(res+j)='w';j++;*(res+j)='-';j++;}
if(*(power+1)=='5'){*(res+j)='r';j++;*(res+j)='-';j++;*(res+j)='x';j++;}if(*(power+1)=='4'){*(res+j)='r';j++;*(res+j)='-';j++;*(res+j)='-';j++;}
if(*(power+1)=='3'){*(res+j)='-';j++;*(res+j)='w';j++;*(res+j)='x';j++;}if(*(power+1)=='2'){*(res+j)='-';j++;*(res+j)='w';j++;*(res+j)='-';j++;}
if(*(power+1)=='1'){*(res+j)='-';j++;*(res+j)='-';j++;*(res+j)='x';j++;}if(*(power+1)=='0'){*(res+j)='-';j++;*(res+j)='-';j++;*(res+j)='-';j++;}
if(*(power+2)=='7'){*(res+j)='r';j++;*(res+j)='w';j++;*(res+j)='x';j++;}if(*(power+2)=='6'){*(res+j)='r';j++;*(res+j)='w';j++;*(res+j)='-';j++;}
if(*(power+2)=='5'){*(res+j)='r';j++;*(res+j)='-';j++;*(res+j)='x';j++;}if(*(power+2)=='4'){*(res+j)='r';j++;*(res+j)='-';j++;*(res+j)='-';j++;}
if(*(power+2)=='3'){*(res+j)='-';j++;*(res+j)='w';j++;*(res+j)='x';j++;}if(*(power+2)=='2'){*(res+j)='-';j++;*(res+j)='w';j++;*(res+j)='-';j++;}
if(*(power+2)=='1'){*(res+j)='-';j++;*(res+j)='-';j++;*(res+j)='x';j++;}if(*(power+2)=='0'){*(res+j)='-';j++;*(res+j)='-';j++;*(res+j)='-';j++;}
return res;
}
int ls(long dir_ind_num)
{
long dt_nums[25],ind_nums[25],length;
int i=0;
INODE inode;
FILE_INFO file_info;
get_dir_data(dir_ind_num,ind_nums,dt_nums,&length);
char * res=(char*)malloc(257);
printf("共%ld项\n",length);
for(i=0;i#_
{
char* res=(char*)malloc(sizeof(char*)*BLOCK_SIZE);
memset(res,0,sizeof(char*)*BLOCK_SIZE);
pwork_dir(res,current_pwd,0);
strcat(res," ");
strcat(res,current_user);
strcat(res,"@Linux>");
printf("%s",res);
return 1;
}
int get_dir_data(long ind_num,long* sub_ind_num,long* sub_dt_num,long* lenth) //得到ind_num目录的子项目信息
{
long num_t;int i=0;
FILE_INFO file_info;
char* temp=(char*)malloc(BLOCK_SIZE*sizeof(char*));
char* data=(char*)malloc(BLOCK_SIZE*sizeof(char*));
memset(data,0,BLOCK_SIZE*sizeof(char*));
memset(temp,0,BLOCK_SIZE*sizeof(char*));
find_data_num(ind_num,&num_t);
get_file_info(num_t,&file_info);
fseek(disk,data_offset+num_t*BLOCK_SIZE+304,SEEK_SET); //定位到该块儿地址
for(i=0;i0)
{
fseek(disk,data_offset+dt_num*BLOCK_SIZE+296,SEEK_SET);
memset(data,0,BLOCK_SIZE*sizeof(char*));
sprintf(data,"%8ld",num_t+1);
fwrite(data,strlen(data),1,disk);
fseek(disk,data_offset+dt_num*BLOCK_SIZE+304+num_t*16,SEEK_SET);
memset(data,0,BLOCK_SIZE*sizeof(char*));
memset(temp,0,BLOCK_SIZE*sizeof(char*));
sprintf(temp,"%8ld",new_ind_num);strcat(data,temp);
sprintf(temp,"%8ld",new_dt_num);strcat(data,temp);
fwrite(data,strlen(data),1,disk);
}
else if(op<0)
{
///更改数据项大小
fseek(disk,data_offset+dt_num*BLOCK_SIZE+296,SEEK_SET);
memset(data,0,BLOCK_SIZE*sizeof(char*));
sprintf(data,"%8ld",num_t-1);
fwrite(data,strlen(data),1,disk);
///查找要删除的节点在第几号数据
long n=0,i=0;
for(i=0;i2){ printf("文件夹非空,不可删除\n");return 1;}
}
if(have_power(current_pwd,file_name,2)==-1)
{
printf("power deniy\n");return 1;
}
find_data_num(dir_ind_num,&dt_num);
update_dir_data(dt_num,new_ind_num,new_dt_num,-1);
return 1;
}
printf("请输入正确的文件名或目录名\n");
return -1;
}
int read_file(long ind_num,char* file_name,char* res) //读取文件
{
long file_ind_num,file_dt_num;
if(find_file_ind_num(file_name,ind_num,&file_ind_num)==1)
{
INODE inode;
get_inode(file_ind_num,&inode);
if(inode.file_type=='1'){printf("%s是目录,不可编辑\n",file_name);return 1;}
find_data_num(file_ind_num,&file_dt_num);
FILE_INFO file_info;
get_file_info(file_dt_num,&file_info);
long file_size=file_info.size;
fseek(disk,data_offset+file_dt_num*BLOCK_SIZE+304,SEEK_SET);
fgets(res,file_size+1,disk);
return 1;
}
printf("请输入正确的文件名\n");
return 1;
}
int write_file(long ind_num,char*file_name,char* res) //写入文件内容
{
long file_ind_num,file_dt_num;
if(find_file_ind_num(file_name,ind_num,&file_ind_num)==1)
{
INODE inode;
get_inode(file_ind_num,&inode);
if(inode.file_type=='1'){printf("%s是目录,不可编辑\n",file_name);return 1;}
find_data_num(file_ind_num,&file_dt_num);
FILE_INFO file_info;
get_file_info(file_dt_num,&file_info);
fseek(disk,data_offset+file_dt_num*BLOCK_SIZE+304,SEEK_SET);
fwrite(res,strlen(res),1,disk);
file_info.size=strlen(res);
update_file_info(file_dt_num,file_info);
return 1;
}
printf("请输入正确的文件名\n");
return 1;
}
int vim_file(long ind_num,char*file_name) //编辑文件
{
long file_ind_num,file_dt_num;
int nLen=0;
if(find_file_ind_num(file_name,ind_num,&file_ind_num)==1)
{
INODE inode;
get_inode(file_ind_num,&inode);
if(inode.file_type=='1'){printf("%s是目录,不可编辑\n",file_name);return 1;}
find_data_num(file_ind_num,&file_dt_num);
FILE_INFO file_info;
get_file_info(file_dt_num,&file_info);
long file_size=file_info.size;
char* content=(char*)malloc(sizeof(char*)*file_size+100);
memset(content,0,sizeof(char*)*file_size+100);
read_file(ind_num,file_name,content);
fseek(disk,data_offset+file_dt_num*BLOCK_SIZE+304,SEEK_SET);
fgets(content,file_size+1,disk);
FILE *temp;
temp=fopen("temp.tmp","w+");
fseek(temp,0,SEEK_SET);
fwrite(content,strlen(content),1,temp);
fclose(temp);
system("notepad.exe temp.tmp");
temp=fopen("temp.tmp","r+");
fseek(temp,0,SEEK_SET);
memset(content,0,sizeof(char*)*file_size+100);
//fgets(content,5,temp);
fseek(temp, 0, SEEK_END);
nLen = ftell(temp);
rewind(temp); // 文件指针恢复到文件头位置~
nLen = fread(content, sizeof(char), nLen, temp);
content[nLen] = '\0';
//printf("%s\n", content);
fclose(temp);
write_file(ind_num,file_name,content);
remove("temp.tmp");
return 1;
}
printf("请输入正确的文件名\n");
return 1;
}
///********************张新明结束**********************************************/
void comand_process() //处理用户命令
{
char* comand=(char*)malloc(sizeof(char*)*200);
char* file_name=(char*)malloc(sizeof(char*)*200);
char* opione=(char*)malloc(sizeof(char*)*200);
pre_rode();
while(scanf("%s",comand))
{
int f=0;
if(!strcmp(comand,"passwd"))
{
scanf("%s",file_name);
pass_wd(file_name);
f=1;
}
if(!strcmp(comand,"su"))
{
scanf("%s",opione);
if(switch_user(opione)==-1)
printf("用户名或密码不正确\n");
else printf("\n");
f=1;
}
if(!strcmp(comand,"vim"))
{
scanf("%s",file_name);
vim_file(current_pwd,file_name);
f=1;
}
if(!strcmp(comand,"rm"))
{
scanf("%s",file_name);
rm_file('0',file_name,current_pwd);
f=1;
}
if(!strcmp(comand,"rmdir"))
{
scanf("%s",file_name);
rm_file('1',file_name,current_pwd);
f=1;
}
if(!strcmp(comand,"ls")) {ls(current_pwd);f=1;}
if(!strcmp(comand,"mkdir"))
{
scanf("%s",file_name);
if(!strcmp(file_name,"")) printf("input dir name:");
make_file('1',file_name,current_pwd);
f=1;
}
if(!strcmp(comand,"touch"))
{
scanf("%s",file_name);
make_file('0',file_name,current_pwd);
f=1;
}
if(!strcmp(comand,"pwd"))
{
f=1;
char* pwd=(char*)malloc(1024);
pwork_dir(pwd,current_pwd,1);
}
if(!strcmp(comand,"super")) {display("super");f=1;}
if(!strcmp(comand,"inode_index")){display("inode_index");f=1;}
if(!strcmp(comand,"data_index")) { display("data_index");f=1;}
if(!strcmp(comand,"reset"))
{
if(strcmp(current_user,"root"))
{
printf("您没有权限格式化磁盘!\n");
}
else
{
load_disk(1);
}
f=1;
}
if(!strcmp(comand,"exit")) {f=1;return;}
if(!strcmp(comand,"cd")){
scanf("%s",file_name);
change_drectory(file_name);
f=1;
}
if(!strcmp(comand,"chmod")){
scanf("%s",file_name);
scanf("%s",opione);
change_mod(file_name,opione);
f=1;
}
if(!strcmp(comand,"chown")){
scanf("%s",file_name);
scanf("%s",opione);
change_own(file_name,opione);
f=1;
}
if(!strcmp(comand,"chgroup")){
scanf("%s",file_name);
scanf("%s",opione);
change_group(file_name,opione);
f=1;
}
if(!strcmp(comand,"logut")){
f=1;
}
if(!strcmp(comand,"useradd")){
scanf("%s",opione);
if(strcmp(current_user,"root"))
{
printf("您没有权限创建用户!\n");
}
else user_add(opione);
f=1;
}
if(f==0) printf("找不到该命令!\n");
pre_rode();
}
}
char* str_trim(char *str,char *res) //去空格函数
{
int i=0,j=0;
for(i=0;i