操作系统文件系统综合设计

来源:互联网 发布:java微信分享接口开发 编辑:程序博客网 时间:2024/06/06 00:07

警告:本计算机程序受著作权法和国际条约保护,如未经授权而擅自复制或传播本程序,,将受到严厉的民事制裁和刑事制裁,并将在法律许可的最大程度内受到起诉。

注:本程序采用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];             //当前的Usernamechar* 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_numint alloc_inode(long* ind_num);                                         //申请inodeint alloc_data(long* dt_num);                                           //申请data号int update_super_blocks();                                              //更新磁盘信息int update_inode_index(long num);                                       //更新索引位图 如果num为 -1 则填充0int update_data_index(long num);                                        //更新索引位图 如果num为 -1 则填充0int 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;}

0 0
原创粉丝点击