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

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

注:本程序采用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

你可能感兴趣的:(操作系统文件系统综合设计)