📄 模拟unix文件系统.c
字号:
#include "stdio.h"
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define G_Read 8 //同组用户对文件的读操作权限
#define G_Write 4 //同组用户对文件的写权限
#define G_Delete 2 //同组用户对文件的删除权限
#define G_Execute 1 //对文件有执行的权限,即修改文件权限的权限
#define O_Read 128 //文件主对文件的读权限
#define O_Write 64 //文件主对文件的写权限
#define O_Delete 32 //文件主对文件的删除权限
#define O_Execute 16 //对文件有执行的权限,即修改文件权限的权限
//定义各个用户
#define User1 1
#define User2 2
int currentuser ;//记录当前用户
int address_buffer[100]; /* 文件地址缓冲区 */
int style=1; /* 文件的类型 */
char cur_dir[10]="root"; /* 当前目录 */
char buffer[100];
char user[10]=" " ;
struct command
{
char com[10];
}cmd[17];
struct block
{
int n; /* 空闲的盘块的个数 */
int free[50]; /* 存放空闲盘块的地址 */
int a; /* 模拟盘块是否被占用 */
}memory[512];
//定义存放文件的数据体
struct file_block
{
char p[512] ;
}fileBlock[1536] ;
struct block_super
{
int n; /* 空闲的盘块的个数 */
int free[50]; /* 存放进入栈中的空闲块 */
int stack[50]; /* 存放下一组空闲盘快的地址 */
}super_block;
struct node /* i结点信息 */
{
int file_style; /* i结点 文件类型 */
int file_length; /* i结点 文件长度 */
int file_mode ;
int file_userid ;
int file_groupid ;
int file_address[10]; /* i结点 文件的物理地址 */
} i_node[512];
struct active_node
{
struct node file_node ;
int i_count ;
int i_number ;
}ActiveNode[30] ;
struct user_file_table
{
int location[15] ;
}UserFileTable[2];
struct system_file_table
{
char filename[10] ;
int pointer ;
}SystemFileTable[30] ;
struct dir /* 目录项信息 */
{
char file_name[10]; /* 文件名 */
int i_num; /* 文件的结点号 */
char dir_name[10]; /* 文件所在的目录 */
} root[512];
void InitUserFileTable()
{
int i ;
for( i=0;i<15;i++ )
{
UserFileTable[0].location[i]=-1 ;
UserFileTable[1].location[i]=-1 ;
}
}
void InitSystemFileTable()
{
int i;
for(i=0; i<30; i++)
{
strcpy(SystemFileTable[i].filename,"");
SystemFileTable[i].pointer=-1 ;
}
}
void InitActiveNode()
{
int i;
for(i=0;i<30;i++)
{
ActiveNode[i].i_count=0 ;
ActiveNode[i].i_number=-1 ;
}
}
void InsertAFileIntoSystemFileTable( char *filename, int i_number )
{
int i, j, k ;
int location=-1 , t;
//检查是否当前用户打开文件表有该记录
for( i=0; i<15; i++ )
{
j=UserFileTable[currentuser-1].location[i] ;
k=SystemFileTable[j].pointer ;
t=ActiveNode[k].i_number ;
if( !strcmp(SystemFileTable[j].filename, filename) && i_number==t )
return ;
if( j==-1 )
location=i ;
}
if( location==-1 )
{
printf("用户打开文件表已满!\n") ;
return ;
}
//检查该当前用户打开表中没有该记录,但系统打开表中有
for( i=0 ; i<30 ; i++ )
{
k=SystemFileTable[i].pointer ;
t=ActiveNode[k].i_number ;
if( !strcmp(SystemFileTable[j].filename, filename) && i_number==t )
{
UserFileTable[currentuser-1].location[location]=i ;
ActiveNode[k].i_count+=1 ;
return ;
}
}
//在当前的用户打开文件表中和系统打开文件表中都没有该记录
for( i=0; i<15; i++ )
{
if( UserFileTable[currentuser-1].location[i]==-1 )
break ;
}
if( i==15 )
{
printf("用户文件表已经满了!\n") ;
return ;
}
for( j=0; j<30; j++ )
{
if( strcmp(SystemFileTable[j].filename,"")==0 )
break ;
}
if( j==30 )
{
printf("系统文件表已经满了!\n") ;
return ;
}
for( k=0; k<30; k++ )
{
if( ActiveNode[k].i_count==0 )
{
break;
}
}
if( k==30 )
{
printf("活动i结点已经用完!\n") ;
return ;
}
UserFileTable[currentuser-1].location[i]=j ;
strcpy(SystemFileTable[j].filename,filename);
SystemFileTable[j].pointer=k ;
ActiveNode[k].i_count+=1 ;
ActiveNode[k].file_node=i_node[i_number] ;
ActiveNode[k].i_number=i_number ;
}
int findAFileInFileTable( char *filename , int *active_node_location)
//在当前用户打开文件表中查找是否有该文件,
//若有,返回其i_number ;
//若没,返回-1
{
int i, j, k ,t;
//检查是否当前用户打开文件表有该记录
for( i=0; i<15; i++ )
{
j=UserFileTable[currentuser-1].location[i] ;
k=SystemFileTable[j].pointer ;
t=ActiveNode[k].i_number ;
if( !strcmp(SystemFileTable[j].filename, filename) )
{
*active_node_location=k ;
return t;
}
}
if( i==15 )
{
*active_node_location=-1 ;
return -1 ;
}
}
int isAOperationElgal( int i_number, char operation )
{
int user_id=i_node[i_number].file_userid ;
int group_id=i_node[i_number].file_groupid ;
int mode=i_node[i_number].file_mode ;
if( currentuser==(currentuser&user_id) )
return 1 ;
if( currentuser==(currentuser&group_id) )
{
if( operation=='R' && G_Read==(G_Read&mode) )
return 1 ;
if( operation=='W' && G_Write==(G_Write&mode) )
return 1 ;
if( operation=='D' && G_Delete==(G_Delete&mode) )
return 1 ;
if( operation=='E' && G_Execute==(G_Execute&mode) )
return 1 ;
}
return 0 ;
}
void closeFile(char *filename)
{
int active_node_location ;
int i_number ;
int i, j, k, t ;
i_number=findAFileInFileTable( filename , &active_node_location) ;
if( i_number==-1 )//如果文件打开表没有则返回
return ;
for( i=0; i<15; i++ )
{
j=UserFileTable[currentuser-1].location[i] ;
k=SystemFileTable[j].pointer ;
t=ActiveNode[k].i_number ;
if( !strcmp(SystemFileTable[j].filename, filename)&& active_node_location==k )
{
ActiveNode[k].i_count-- ;
if( ActiveNode[k].i_count==0 )
{
UserFileTable[currentuser-1].location[i]=-1 ;
SystemFileTable[j].pointer=-1 ;
strcpy(SystemFileTable[j].filename, "") ;
ActiveNode[k].i_number=-1 ;
}
return t;
}
}
}
void changeFileMode( char *filename )
{
char p[9] ;
int i=0 ;
int _mode=0 ;
int i_number ;
int j;
int active_node_location ;
i_number=findAFileInFileTable( filename , &active_node_location) ;
if( i_number!=-1 )
{
if( isAOperationElgal(i_number, 'E' )==1 )
{
printf("请输入0、1串(相应的位为一代表有相应的权限,0代表没有)\n") ;
// printf("文件主读、文件主写、文件主删除、文件主执行、同组用户读、同组用户写、同组用户删除、同组用户执行\n");
scanf("%s",p) ;
for( i=0;i<8;i++ )
{
if( p[i]=='1' )
{
if( i==0 )
_mode=_mode|O_Read ;
if( i==1 )
_mode=_mode|O_Write ;
if( i==2 )
_mode=_mode|O_Delete ;
if( i==3 )
_mode=_mode|O_Execute ;
if( i==4 )
_mode=_mode|G_Read ;
if( i==5 )
_mode=_mode|G_Write ;
if( i==6 )
_mode=_mode|G_Delete ;
if( i==7 )
_mode=_mode|G_Execute ;
}
}
i_node[i_number].file_mode=_mode ;
flushall() ;
return ;
}
else
{
printf("权限不对,对不起!\n") ;
return ;
}
}
for(j=0;j<512;j++)
{
if(strcmp(filename,root[j].file_name)==0)
{
i_number=j;
}
}
if( (currentuser!=i_node[i_number].file_userid) && (G_Execute==(G_Execute&i_node[i_number].file_mode))||
currentuser==i_node[i_number].file_userid )
{
printf("请输入0、1串(相应的位为一代表有相应的权限,0代表没有)\n") ;
//printf("文件主读、文件主写、文件主删除、文件主执行、同组用户读、同组用户写、同组用户删除、同组用户执行\n");
scanf("%s",p ) ;
for( ;i<8;i++ )
{
if( p[i]=='1' )
{
if( i==0 )
_mode=_mode|O_Read ;
if( i==1 )
_mode=_mode|O_Write ;
if( i==2 )
_mode=_mode|O_Delete ;
if( i==3 )
_mode=_mode|O_Execute ;
if( i==4 )
_mode=_mode|G_Read ;
if( i==5 )
_mode=_mode|G_Write ;
if( i==6 )
_mode=_mode|G_Delete ;
if( i==7 )
_mode=_mode|G_Execute ;
}
}
i_node[i_number].file_mode=_mode ;
flushall() ;
return ;
}
else
{
printf("对不起,你没有改权限!\n") ;
}
}
int Login()
{
char username[10];
char password[8];
int c;
int i = 0;
for (c = 0; c < 2; c++)
{
printf("login name:");
scanf("%s",username) ;
strcpy(user,username);
printf("password:");
i=0;
while( (password[i]=getch())!='\r')
{
printf("*") ;
i++;
}
password[i]='\0' ;
printf("\n");
if ((strcmp(username, "user1") == 0 && strcmp(password, "user1") == 0) ||
(strcmp(username, "user2") == 0 && strcmp(password, "user2") == 0) )
{ printf("\n*****************登陆成功*******************************\n");
printf("\n*****************如果是第一次操作,请输入help************\n");
if( strcmp(username, "user1") == 0 )
currentuser=User1 ;
if( strcmp(username, "user2") == 0 )
currentuser=User2 ;
return 1;
break;
}
else
{
printf("\n用户名或密码错误,请重新输入。\n");
}
}
if (c >= 2) //非法用户
{
printf("\n对不起,您不是该系统用户,按任意键退出系统。\n");
return 0;
}
else
{
return 1;
}
}
void format() /* 格式化 */
{
int i,j,k;
super_block.n=50;
for(i=0;i<50;i++) /* 超级块初始化 */
{
super_block.free[i]=i; /* 存放进入栈中的空闲块 */
super_block.stack[i]=50+i; /* 存放下一组的盘块 */
}
for(i=0;i<512;i++) /* i结点信息初始化 */
{
for(j=0;j<100;j++)
{
i_node[i].file_address[j]=-1;/* 文件地址 */
}
i_node[i].file_length=-1; /* 文件长度 */
i_node[i].file_style=-1; /* 文件类型 */
}
for(i=0;i<512;i++) /* 根目录区信息初始化 */
{
strcpy(root[i].file_name,"");
root[i].i_num=-1;
strcpy(root[i].dir_name,"");
}
for(i=0;i<512;i++) /* 存储空间初始化 */
{
memory[i].n=0; /* 必须有这个 */
memory[i].a=0;
for(j=0;j<50;j++)
{
memory[i].free[j]=-1;
}
}
for(i=0;i<512;i++) /* 将空闲块的信息用成组链接的方法写进每组的最后一个块中 */
{ /* 存储空间初始化 */
if((i+1)%50==0)
{
k=i+1;
for(j=0;j<50;j++)
{
if(k<513)
{
memory[i].free[j]=k;/* 下一组空闲地址 */
memory[i].n++; /* 下一组空闲个数 注意在memory[i].n++之前要给其赋初值 */
k++;
}
else
{
memory[i].free[j]=-1;
}
}
memory[i].a=0; /* 标记为没有使用 */
continue; /* 处理完用于存储下一组盘块信息的特殊盘块后,跳过本次循环 */
}
for(j=0;j<50;j++)
{
memory[i].free[j]=-1;
}
memory[i].n=0;
}
printf("---------------------------------已经初始化完毕-------------------------\n");
printf("---------------------------------进入UNIX文件模拟-----------------------\n\n");
}
void write_file(FILE *fp) // 将信息读入系统文件中
{
int i;
fp=fopen("system","wb");
for(i=0;i<512;i++)
{
fwrite(&memory[i],sizeof(struct block),1,fp);
}
fwrite(&super_block,sizeof(struct block_super),1,fp);
for(i=0;i<512;i++)
{
fwrite(&i_node[i],sizeof(struct node),1,fp);
}
for(i=0;i<512;i++)
{
fwrite(&root[i],sizeof(struct dir),1,fp);
}
fclose(fp);
system("cls");
Login();
return;
}
void su()
{
char currentcontent[10]="root" ;
char *p=(currentuser==User1)?"user2":"user1" ;
currentuser=(currentuser==User1)?User2:User1 ;
strcpy(cur_dir,currentcontent) ;
strcpy(user,p) ;
}
void writefile(char *filename)
{
int i_number ;
int i;
int j;
int address[10] ;
int active_node_location ;
i_number=findAFileInFileTable( filename , &active_node_location) ;
if( i_number!=-1 )
{
if( isAOperationElgal(i_number, 'W' )==1 )
{
for( i=0 ; i<10; i++ )
address[i]=i_node[i_number].file_address[i] ;
printf("请输入内容:文件以D结束\n") ;
i=0 ;
j=0 ;
flushall();
while( (buffer[i++]=getchar())!='D' )
{
if( i==512 && j<10 )
{
buffer[i]='\0' ;
strcpy( fileBlock[address[j]].p, buffer) ;
i=0 ;
j++ ;
i_node[i_number].file_length+=512 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -