警告:本计算机程序受著作权法和国际条约保护,如未经授权而擅自复制或传播本程序,,将受到严厉的民事制裁和刑事制裁,并将在法律许可的最大程度内受到起诉。
注:本程序采用C语言设计,用C编译器编译后可直接运行,版权归作者本人所有
#include <io.h> #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> #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;i<user_n;i++) { // printf("user_name:%s|user_pass=%s|\n",users[i],pass_words[i]); if(!strcmp(users[i],user_name)&&!strcmp(pass_words[i],pass_t)) { current_pwd=0; strcpy(current_user,user_name); return 1; } } return -1; } int user_add(char* user_name) { int flag=1,m=0; char pass[32],pass2[32]; long cur_pwd=current_pwd; for(;m<user_n;m++) { if(!strcmp(user_name,users[m])) { printf("用户名已存在\n"); return 0; } } printf("请输入用户密码:\n"); scanf("%s",pass); printf("请在一次输入用户密码:\n"); scanf("%s",pass2); if(!strcmp(pass,pass2)) { //printf("1\n"); current_pwd=0; change_drectory("root"); change_drectory("etc"); long res_ind_num; find_file_ind_num("passwd",current_pwd, &res_ind_num); long dt_num; find_data_num(res_ind_num,&dt_num); FILE_INFO file_info; get_file_info(dt_num,&file_info); file_info.size+=32; update_file_info(dt_num,file_info); //printf("2\n"); //printf("user_n=%d\n",user_n); fseek(disk,data_offset+dt_num*BLOCK_SIZE+304+32*user_n,SEEK_SET); //printf("3\n"); char temp1[32],temp2[32]; sprintf(temp1,"%-16s",user_name); //printf("temp1=%s\n",temp1); fwrite(temp1,16,1,disk); fseek(disk,data_offset+dt_num*BLOCK_SIZE+304+32*user_n+16,SEEK_SET); sprintf(temp2,"%-16s",pass); //printf("temp2=%s\n",temp2); fwrite(temp2,16,1,disk); strcpy(users[user_n],user_name); strcpy(pass_words[user_n],pass); user_n+=1; } else { printf("两次密码不一致,正在退出…………"); flag=0; } current_pwd=cur_pwd; printf("user_n=%d\n",user_n); return flag; } int pass_wd(char* user_name) { char new_pass[20],new_pass2[20],old_pass[20]; long cur_pwd=current_pwd; int m=0,flag=1; for(;m<user_n;m++) { if(!strcmp(user_name,users[m])) { printf("请输入你的旧密码:\n"); scanf("%s",old_pass); if(!strcmp(pass_words[m],old_pass)) { printf("请输入你的新密码:\n"); scanf("%s",new_pass); printf("请再一次输入你的新密码:\n"); scanf("%s",new_pass2); if(strcmp(new_pass,new_pass2)==0) { current_pwd=0; change_drectory("root"); change_drectory("etc"); long res_ind_num; find_file_ind_num("passwd",current_pwd, &res_ind_num); long dt_num; find_data_num(res_ind_num,&dt_num); fseek(disk,data_offset+dt_num*BLOCK_SIZE+304+32*m+16,SEEK_SET); char temp[32]; sprintf(temp,"%16s",new_pass); fwrite(temp,16,1,disk); //printf(""); } } else { printf("你输入的原来密码不正确:\n"); flag=0; break; } } } current_pwd=cur_pwd; return flag; } int user_login() //用户登录验证函数 { char user_name[20],user_pass[20],c; int i=0,right=0,m; printf("输入您的用户名:"); scanf("%s",user_name); printf("输入您的用户密码:"); while ((c=getch())!='\r') { user_pass[i]=c; i++; if(c!='\b') //输入内容不是退格时就显示 “*”号 printf("*"); else //输入内容是退格时 删除前一个 “*”号 printf("\b \b"); } *(user_pass+i)='\0'; printf("\n"); //printf("pass_asd=%s|\n",user_pass); for(m=0;m<user_n;m++) { if(!strcmp(user_name,users[m])) { if(!strcmp(user_pass,pass_words[m])) { right=1; break; } } } if(right==1) {strcpy(current_user,user_name);return 1;} return 0; } int load_file_system() //初始化文件目录 { char* res=(char*)malloc(BLOCK_SIZE*sizeof(char*)+100); char* temp=(char*)malloc(32*sizeof(char*)); memset(res,0,BLOCK_SIZE*sizeof(char*)+100); memset(temp,0,sizeof(char*)*32); int i=0; for(i=0;i<200;i++) { users[i]=(char*)malloc(256); pass_words[i]=(char*)malloc(256); memset(users[i],0,256); memset(pass_words[i],0,256); } current_pwd=0; change_drectory("root"); change_drectory("etc"); read_file(current_pwd,"passwd",res); i=0;user_n=0; while((i*16)<strlen(res)) { strncpy(users[user_n],res+i*16,16); trim(users[user_n]); i++; strncpy(pass_words[user_n],res+i*16,16); trim(pass_words[user_n]); i++; user_n++; } return 1; } int update_inode_index(long num) //更新索引位图 如果num为 -1 则填充0 { //如果是-1,inode全部初始化为0 if(num==-1) { int i; fseek(disk,inode_index_offset,SEEK_SET); for(i=0;i<inode_num;i++) { fwrite("0",1,1,disk); //printf("%c",fgetc(disk)); } } else { inode_index[num]='1'; fseek(disk,inode_index_offset+num,SEEK_SET); fwrite("1",1,1,disk); } return 1; } int update_data_index(long num) //更新索引位图 如果num为 -1 则填充0 { if(num==-1) { int i=0; fseek(disk,data_index_offset,SEEK_SET); for(i=0;i<data_block_num;i++) fwrite("0",1,1,disk); } else { data_block_index[num]='1'; fseek(disk,data_index_offset+num*1,SEEK_SET); fwrite("1",1,1,disk); } return 1; } int get_inode_index() //得到索引节点信息(磁盘放到全局变量里边); { fseek(disk,inode_index_offset,SEEK_SET); int i=0; for(i=0;i<inode_num;i++) { inode_index[i]=fgetc(disk); } return 1; } int get_data_index() //得到索引节点信息(磁盘放到全局变量里边); { int i=0; fseek(disk,data_index_offset,SEEK_SET); for(i=0;i<data_block_num;i++) { data_block_index[i]=fgetc(disk); } return 1; } int update_inode(INODE inode,long num) //更新inode信息,及两个位图信息 { char* temp=(char*)malloc(INODE_SIZE*sizeof(char*)); char* temp2=(char*)malloc(INODE_SIZE*sizeof(char*)); memset(temp,0,INODE_SIZE*sizeof(char*)); memset(temp2,0,INODE_SIZE*sizeof(char*)); int i=0; fseek(disk,inode_offset+num*INODE_SIZE,SEEK_SET); sprintf(temp2,"%c",inode.file_type); strcat(temp,temp2); sprintf(temp2,"%3s",inode.power); strcat(temp,temp2); sprintf(temp2,"%16s",inode.owner); strcat(temp,temp2); sprintf(temp2,"%16s",inode.group); strcat(temp,temp2); sprintf(temp2,"%8ld",inode.lenth); strcat(temp,temp2); for(i=0;i<inode.lenth;i++) { sprintf(temp2,"%8ld",inode.point_number[i]); strcat(temp,temp2); } fwrite(temp,strlen(temp),1,disk); // printf("update_inode()leng=%d\n%s|\n",strlen(temp),temp); return 1; } int get_inode(long ind_num,INODE* inode) //得到文件的inode信息,如果inode_num=-1 则载入到内存 { char* temp=(char*)malloc(INODE_SIZE*sizeof(char*)); char* temp2=(char*)malloc(INODE_SIZE*sizeof(char*)); long num_t; fseek(disk,inode_offset+ind_num*INODE_SIZE,SEEK_SET); str_trim(fgets(temp,2,disk),&(*inode).file_type); str_trim(fgets(temp,4,disk),(*inode).power); str_trim(fgets(temp,17,disk),(*inode).owner); str_trim(fgets(temp,17,disk),(*inode).group); // fgets(&(*inode).file_type,2,disk); // fgets((*inode).power,4,disk); // fgets((*inode).owner,17,disk); //trim((*inode).owner); // fgets((*inode).group,17,disk); //trim((*inode).group); // fgets(temp,9,disk); str_trim(fgets(temp2,9,disk),temp); (*inode).lenth=atol(temp); // printf("get_inode()%ld\n",(*inode).lenth); int i=0; for(i=0;i<(*inode).lenth;i++) { memset(temp,0,INODE_SIZE*sizeof(char*)); num_t=atol(temp); (*inode).point_number[i]=num_t; } return 1; } int find_prt_ind_num_as_ind_num(long ind_num,long* prt_ind_num) //根据给定的inode号码,查找出父目录的indoe号码 { long num_t; char* temp=(char*)malloc(sizeof(char*)*BLOCK_SIZE); memset(temp,0,sizeof(char*)*BLOCK_SIZE); find_data_num(ind_num,&num_t); fseek(disk,data_offset+num_t*BLOCK_SIZE,SEEK_SET); fgets(temp,9,disk); *prt_ind_num=atol(temp); return 1; } int find_prt_ind_num_as_dt_num(long dt_num,long* prt_ind_num) //根据给定的inode号码,查找出父目录的indoe号码 { char* temp=(char*)malloc(sizeof(char*)*BLOCK_SIZE); memset(temp,0,sizeof(char*)*BLOCK_SIZE); fseek(disk,data_offset+dt_num*BLOCK_SIZE,SEEK_SET); fgets(temp,9,disk); *prt_ind_num=atol(temp); return 1; } int find_data_num(long ind_num,long* dt_num) //根据节点号,来查找该文件的详细信息所在的data_num 号码 { if(ind_num==-1) {*dt_num=0;return 1;} char *temp=(char*)malloc(sizeof(char*)*INODE_SIZE); memset(temp,0,sizeof(char*)*INODE_SIZE); fseek(disk,inode_offset+ind_num*INODE_SIZE+44,SEEK_SET); fgets(temp,9,disk); *dt_num=atol(temp); return 1; } int get_file_info(long dt_num,FILE_INFO* file) //得到文件的大小及创建时间等信息 { if(dt_num==-1) return 1; char *temp=(char*)malloc(sizeof(char*)*BLOCK_SIZE); char *temp2=(char*)malloc(sizeof(char*)*BLOCK_SIZE); memset(temp,0,sizeof(char*)*BLOCK_SIZE); memset(temp2,0,sizeof(char*)*BLOCK_SIZE); fseek(disk,data_offset+dt_num*BLOCK_SIZE,SEEK_SET); fgets(temp,9,disk); file->parent_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<length;i++) { get_inode(ind_nums[i],&inode); if(ind_nums[i]<0) continue; printf("%-3ld",ind_nums[i]); printf("%-3ld",dt_nums[i]); if(inode.file_type=='0') printf("-"); if(inode.file_type=='1') printf("d"); printf("%-11s%-s\t%-s\t",converse_power(inode.power,res),inode.owner,inode.group); get_file_info(dt_nums[i],&file_info); printf("%-4ld",file_info.size); printf("%-s\n",file_info.file_name); } return 1; } ///********************荣光辉结束**********************************************/ ///********************张新明开始**********************************************/ int have_power(long ind_num,char* file_name,int op) //检查权限,返回真假值 { if(!strcmp(current_user,"root")) { return 1; } long num_t; INODE inode_t; find_file_ind_num(file_name,ind_num,&num_t); get_inode(num_t,&inode_t); char* power=(char*)malloc(100); memset(power,0,100); converse_power(inode_t.power,power); //读取 R if(op==1) { if(!strcmp(current_user,inode_t.owner)) { if(*(power+0)=='r') return 1; } else if(!strcmp(current_user,inode_t.group)) { if(*(power+3)=='r') return 1; } else { if(*(power+6)=='r') return 1; } return -1; } //删除 if(op==2) { INODE inode_t2; get_inode(ind_num,&inode_t2); char* power2=(char*)malloc(100); memset(power2,0,100); converse_power(inode_t2.power,power2); if(!strcmp(current_user,inode_t2.owner)) { if(*(power2+1)=='w') return 1; } else if(!strcmp(current_user,inode_t2.group)) { if(*(power2+4)=='w') return 1; } else { if(*(power2+7)=='w') return 1; } return -1; } //修改 if(op==4) { if(!strcmp(current_user,inode_t.owner)) { if(*(power+1)=='w') return 1; } else if(!strcmp(current_user,inode_t.group)) { if(*(power+4)=='w') return 1; } else { if(*(power+7)=='w') return 1; } return -1; } //执行X if(op==3) { if(!strcmp(current_user,inode_t.owner)) { if(*(power+2)=='x') return 1; } else if(!strcmp(current_user,inode_t.group)) { if(*(power+5)=='x') return 1; } else { if(*(power+8)=='x') return 1; } return -1; } return -1; } int load_disk(int reset) //初始化文件系统 { inode_num=(DISK_SIZE-5*BLOCK_SIZE)/(2+5*INODE_SIZE); data_block_num=(DISK_SIZE-5*BLOCK_SIZE)/(2+5*INODE_SIZE); //超级块初始化 super_block.total_size=DISK_SIZE; super_block.inode_space_size=inode_num*INODE_SIZE; super_block.inode_used_size=0; super_block.data_space_size=data_block_num*BLOCK_SIZE; super_block.data_used_size=0; super_block.block_size=BLOCK_SIZE; super_block_offset=4*BLOCK_SIZE; inode_index_offset=5*BLOCK_SIZE; data_index_offset=inode_index_offset+inode_num; inode_offset=data_index_offset+data_block_num; data_offset=inode_offset+inode_num*INODE_SIZE; if(access(disk_name,0)==-1||reset==1) ///文件不存在 { printf("第一次使用磁盘,正在格式化"); if(!(disk=fopen(disk_name,"w+"))) { printf("文件打开失败!\n"); return -1; } int j=1,i=0; for(i=0;i<DISK_SIZE;i++) { if((DISK_SIZE/10*j)==i) {printf(".");j++;} fputc(' ',disk); } update_super_blocks(); update_inode_index(-1);//inode位图 初始化 update_data_index(-1);//data 位图 初始化 get_inode_index(); get_data_index(); init_file(); fclose(disk); printf("完成\n"); } printf("正在载入文件系统...."); if(!(disk=fopen(disk_name,"r+"))) { printf("文件打开失败!\n"); return -1; } get_super_blocks(); //初始化超级块儿 get_inode_index(); get_data_index(); strcpy(current_user,"root"); load_file_system(); current_pwd=0; strcpy(current_user,"root"); printf("完成\n"); //此时没有关闭磁盘 return 1; } int alloc_inode(long* ind_num) //申请inode { int i=0; for(i=0;i<inode_num;i++) if(inode_index[i]=='0'){*ind_num=i;return 1;} return -1; } int alloc_data(long* dt_num) //申请data号 { int i=0; for(i=0;i<data_block_num;i++) if(data_block_index[i]=='0'){*dt_num=i;return 1;} return -1; } void display(char* comand) //显示一些基本信息 { if(!strcmp(comand,"super")) { printf("%-16ld\n",super_block.total_size); printf("%-16ld\n",super_block.data_used_size); printf("%-16ld\n",super_block.inode_used_size); printf("%-16ld\n",super_block.block_size); printf("%-16s\n",current_user); printf("%-16ld\n",current_pwd); } int i=0; if(!strcmp(comand,"inode_index")) { fseek(disk,inode_index_offset,SEEK_SET); for(i=0;i<inode_num;i++) { printf("%c",fgetc(disk)); } printf("\n"); // printf("%ld\n",inode_num); } if(!strcmp(comand,"data_index")) { fseek(disk,data_index_offset,SEEK_SET); for(i=0;i<data_block_num;i++) { printf("%c",fgetc(disk)); } printf("\n"); } } int update_super_blocks() //更新磁盘信息 { char* temp=(char*)malloc(BLOCK_SIZE*sizeof(char*)); char* data=(char*)malloc(BLOCK_SIZE*sizeof(char*)); memset(data,0,sizeof(char*)*BLOCK_SIZE); memset(temp,0,sizeof(char*)*BLOCK_SIZE); sprintf(temp,"%-16ld",super_block.total_size); strcat(data,temp); sprintf(temp,"%-16ld%-16ld",super_block.data_space_size,super_block.data_used_size); strcat(data,temp); sprintf(temp,"%-16ld%-16ld%-16ld",super_block.inode_space_size,super_block.inode_used_size,super_block.block_size); strcat(data,temp); //printf("%d %s\n",strlen(data),data); fseek(disk,super_block_offset,SEEK_SET); //从文件的起始位置,偏移super_block_offse fwrite(data,strlen(data),1,disk); return 1; } int get_super_blocks() //得到磁盘信息 { fseek(disk,super_block_offset,SEEK_SET); fscanf(disk,"%ld%ld",&super_block.total_size,&super_block.data_space_size); fscanf(disk,"%ld%ld",&super_block.data_used_size,&super_block.inode_space_size); fscanf(disk,"%ld%ld",&super_block.inode_used_size,&super_block.block_size); return 1; } int pwork_dir(char* pwd,long ind_num,int f_print) //得到当前文件的路径,并可以控制是否输出 { long num_t1,num_t2,cur_pwd=ind_num; char* temp=(char*)malloc(sizeof(char*)*BLOCK_SIZE); char* res=(char*)malloc(sizeof(char*)*BLOCK_SIZE); memset(temp,0,sizeof(char*)*BLOCK_SIZE); memset(res,0,sizeof(char*)*BLOCK_SIZE); FILE_INFO file_info; for(;;) { find_prt_ind_num_as_ind_num(ind_num,&num_t1); //printf("ind_num=%ld\n",ind_num); //printf("num_t1=%ld\n",num_t1); if(num_t1==-1) { strcpy(temp,"/"); strcat(temp,res); strcpy(res,temp); break; } find_data_num(ind_num,&num_t2); //printf("num_t2=%ld\n",num_t2); get_file_info(num_t2,&file_info); strcpy(temp,file_info.file_name); if(ind_num!=cur_pwd) strcat(temp,"/"); // printf("file_name=%s\n",file_info.file_name); strcat(temp,res); strcpy(res,temp); memset(temp,0,sizeof(char*)*BLOCK_SIZE); ind_num=num_t1; } strcpy(pwd,res); // printf("=====%s\n",pwd); if(f_print==1) printf("当前路径;%s\n",pwd); // printf("当前路径搜索已完成!\n"); return 1; } int pre_rode() //显示前缀 如 /root/etc zhangxinming@CentOS>#_ { 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;i<file_info.size;i++) { fgets(temp,9,disk); num_t=atol(temp); *(sub_ind_num+i)=num_t; fgets(temp,9,disk); num_t=atol(temp); *(sub_dt_num+i)=num_t; } *lenth=file_info.size; return 1; } int update_dir_data(long dt_num,long new_ind_num,long new_dt_num,int op) //更新ind_num目录的子项目信息,用来告诉父目录的数据区新增加了一项或减少了一项(OP) { long num_t; 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*)); fseek(disk,data_offset+dt_num*BLOCK_SIZE+296,SEEK_SET); fgets(temp,9,disk); num_t=atol(temp); //读取几个数据项,连续的 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); 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;i<num_t;i++) { fseek(disk,data_offset+dt_num*BLOCK_SIZE+304+i*16,SEEK_SET); memset(temp,0,BLOCK_SIZE*sizeof(char*)); fgets(temp,9,disk); fgets(temp,9,disk); n=atol(temp); if(n==new_dt_num) {n=i;break;} } for(i=n+1;i<num_t;i++) { fseek(disk,data_offset+dt_num*BLOCK_SIZE+304+i*16,SEEK_SET); memset(temp,0,BLOCK_SIZE*sizeof(char*)); fgets(temp,17,disk); fseek(disk,data_offset+dt_num*BLOCK_SIZE+304+(i-1)*16,SEEK_SET); memset(temp,0,BLOCK_SIZE*sizeof(char*)); fwrite(temp,strlen(temp),1,disk); } } return 1; } int make_file(char file_type,char *file_name,long parent_ind_num) //创建【目录】文件 { long ind_num,dt_num; long dt_num_t,new_ind_num,new_dt_num; long old_parent_num=parent_ind_num; alloc_inode(&ind_num); alloc_data(&dt_num); new_ind_num=ind_num; new_dt_num=dt_num; if(dt_num==-1||ind_num==-1) return -1; ///****************更新内存信息**********************************/ super_block.inode_space_size-=INODE_SIZE; super_block.inode_used_size+=INODE_SIZE; super_block.data_space_size-=BLOCK_SIZE; super_block.data_used_size+=BLOCK_SIZE; update_super_blocks(); ///****************更新磁盘文件信息******************************/ ///更改超级块儿及位图信息 update_inode_index(ind_num); update_data_index(dt_num); ///更改新创建子目录的inode信息 INODE new_inode; new_inode.file_type=file_type; strcpy(new_inode.power,"755"); strcpy(new_inode.owner,current_user); strcpy(new_inode.group,current_user); new_inode.lenth=1; new_inode.point_number[0]=dt_num; update_inode(new_inode,ind_num); find_data_num(parent_ind_num,&dt_num_t); FILE_INFO new_file; new_file.parent_dir_inode_num=parent_ind_num; new_file.parent_info_data_num=dt_num_t; strcpy(new_file.file_name,file_name); strcpy(new_file.create_time,"20140709"); new_file.link_num=0; new_file.size=0; // printf("make_file() dt_num=%ld\n",dt_num,dt_num,dt_num); update_file_info(dt_num,new_file);///更新完成新建文件的信息 ///更新父目录数据区信息 if(parent_ind_num!=-1)update_dir_data(dt_num_t,ind_num,dt_num,1); // printf("parent_ind_num=%ld\n",parent_ind_num); if(file_type=='1') { long tttt; alloc_data(&tttt); update_data_index(tttt); super_block.inode_space_size-=INODE_SIZE; super_block.inode_used_size+=INODE_SIZE; super_block.data_space_size-=BLOCK_SIZE; super_block.data_used_size+=BLOCK_SIZE; update_super_blocks(); FILE_INFO fi; fi.parent_dir_inode_num=new_ind_num; fi.parent_info_data_num=new_dt_num; strcpy(fi.file_name,".."); strcpy(fi.create_time,"11111111"); fi.link_num=1; fi.size=0; update_file_info(tttt,fi); update_dir_data(new_dt_num,old_parent_num,tttt,1); alloc_data(&tttt); update_data_index(tttt); super_block.inode_space_size-=INODE_SIZE; super_block.inode_used_size+=INODE_SIZE; super_block.data_space_size-=BLOCK_SIZE; super_block.data_used_size+=BLOCK_SIZE; update_super_blocks(); fi.parent_dir_inode_num=new_ind_num; fi.parent_info_data_num=new_dt_num; strcpy(fi.file_name,"."); strcpy(fi.create_time,"11111111"); fi.link_num=1; fi.size=0; update_file_info(tttt,fi); update_dir_data(new_dt_num,old_parent_num,tttt,1); // printf("new_dt_num=%ld\n",new_dt_num); } return 1; } int init_file() //初始化文件目录及重要文件内容 { current_pwd=0; strcpy(current_user,"root"); make_file('1',"/",-1); make_file('1',"root",current_pwd); make_file('0',"tex",current_pwd); change_drectory("root"); make_file('1',"etc",current_pwd); change_drectory("etc"); make_file('0',"passwd",current_pwd); char* data=(char*)malloc(1024); char* tmp=(char*)malloc(1024); memset(data,0,1024); memset(tmp,0,1024); sprintf(tmp,"%-16s","root");strcat(data,tmp); sprintf(tmp,"%-16s","root");strcat(data,tmp); write_file(current_pwd,"passwd",data); return 1; } int find_file_ind_num(char* dir_name,long pwd_num,long* res_ind_num) //根据给定的文件名,在pwd_num目录查找他的ind_num { long dt_nums[25],ind_nums[25],length; int i=0; INODE inode; FILE_INFO file_info; get_dir_data(pwd_num,ind_nums,dt_nums,&length); char * res=(char*)malloc(257); for(i=0;i<length;i++) { get_inode(ind_nums[i],&inode); get_file_info(dt_nums[i],&file_info); if(!strcmp(str_trim(file_info.file_name,res),dir_name)) { *res_ind_num=ind_nums[i]; return 1; } } return -1; } int change_drectory(char* dir_name) //改变工作目录 { long num_t; if(find_file_ind_num(dir_name,current_pwd,&num_t)==1) { INODE inode_t; get_inode(num_t,&inode_t); if(inode_t.file_type!='1') { printf("%s不是目录!\n",dir_name); return 1; } if(have_power(current_pwd,dir_name,4)==1) { current_pwd=num_t; return 1; } else { printf("power deniy\n"); return 1; } } else printf("没有%s这个文件夹\n",dir_name); return 1; } int change_mod(char* file_name,char* new_power) //修改权限 { long num_t1; find_file_ind_num(file_name,current_pwd,&num_t1); fseek(disk,inode_offset+num_t1*INODE_SIZE+1,SEEK_SET); fwrite(new_power,3,1,disk); return 1; } int change_own(char* file_name,char* new_owner) //修改所有者 { long num_t1; find_file_ind_num(file_name,current_pwd,&num_t1); fseek(disk,inode_offset+num_t1*INODE_SIZE+4,SEEK_SET); fwrite(new_owner,16,1,disk); return 1; } int change_group(char* file_name,char* new_group) //修改用户组 { long num_t1; find_file_ind_num(file_name,current_pwd,&num_t1); fseek(disk,inode_offset+num_t1*INODE_SIZE+20,SEEK_SET); fwrite(new_group,16,1,disk); return 1; } int rm_file(char file_type,char* file_name,long dir_ind_num) //删除【目录】文件 { long dt_num,new_ind_num,new_dt_num; if(find_file_ind_num(file_name,dir_ind_num,&new_ind_num)==1) { INODE inode; get_inode(new_ind_num,&inode); if(file_type=='1'&&inode.file_type=='0'){printf("%s不是目录,不可删除\n",file_name);return 1;} if(file_type=='0'&&inode.file_type=='1'){printf("%s是目录,不可删除\n",file_name);return 1;} find_data_num(new_ind_num,&new_dt_num); if(file_type=='1') { FILE_INFO file; get_file_info(new_dt_num,&file); if(file.size>2){ 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<strlen(str);i++) { char c=*(str+i); if(c!=32){*(res+j)=c;j++;} } *(res+j)='\0'; return res; } void trim(char* str) //去空格函数 { int i=0,j=0; char * res=(char*)malloc(257); memset(res,0,257); strcpy(res,str); for(i=0;i<strlen(str);i++) { char c=*(str+i); if(c!=32){*(res+j)=c;j++;} } *(res+j)='\0'; memset(str,0,257); strcpy(str,res); } int main() { load_disk(0); printf("****************************欢迎使用EXT2文件管理系统****************************\n"); while(!user_login()) printf(" Login Wrong! \n"); printf(" Login Successful! \n"); comand_process(); fclose(disk); return 0; }