⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 模拟unix文件系统.c

📁 模拟unix文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
				}
				else if( j==10 )
				{
					printf("文件已经写满!\n") ;
					return ;
				}
			}
			if( j==10 )
			{
				printf("文件已经写满!\n") ;
				return ;
			}
			buffer[i-1]='\n' ;
			buffer[i]='\0' ;
			strcpy( fileBlock[address[j]].p, buffer) ;
			printf("输入完毕!\n") ;
			i_node[i_number].file_length+=strlen(buffer);
			for( j=i+1;j<10;j++ )
			{
				strcpy(fileBlock[address[j]].p,"\0") ;
			}
			return ;
		}
		else
		{
			printf("权限不对,对不起!\n") ;
			return ;
		}
	}
	for(i=0;i<512;i++) 
	{ 
		if(strcmp(filename,root[i].file_name)==0) 
		{ 
			i_number=i; 
			InsertAFileIntoSystemFileTable( filename,  i_number ) ;
			break ;
		}
	} 
	if(i==512)
	{
		printf("对不起,找不到相应的文件\n");
		return;
	}

	if( (currentuser!=i_node[i_number].file_userid) && (G_Write==(G_Write&i_node[i_number].file_mode))||
		currentuser==i_node[i_number].file_userid )
	{
		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 ;
			}
			else if( j==10 )
			{
				printf("文件已经写满!\n") ;
				return ;
			}
		}
		if( j==10 )
		{
			printf("文件已经写满!\n") ;
			return ;
		}
		buffer[i-1]='\n' ;
		buffer[i]='\0' ;
		strcpy( fileBlock[address[j]].p, buffer) ;
		printf("输入完毕!\n") ;
		i_node[i_number].file_length+=strlen(buffer);
		for( j=i+1;j<10;j++ )
		{
			strcpy(fileBlock[address[j]].p,"\0") ;
		}
		return ;
	}
	printf("对不起,你对该文件无写权限!\n") ;
}

void read_file(FILE *fp)   // 读出系统文件的信息  
{ 
	int i; 
	fp=fopen("system","rb"); 
	for(i=0;i<512;i++) 
	{ 
		fread(&memory[i],sizeof(struct block),1,fp); 
	} 

	fread(&super_block,sizeof(struct block_super),1,fp); 

	for(i=0;i<512;i++) 
	{ 
		fread(&i_node[i],sizeof(struct node),1,fp); 
	} 

	for(i=0;i<512;i++) 
	{ 
		fread(&root[i],sizeof(struct dir),1,fp); 
	} 
	fclose(fp);
	
} 




void readfile( char *filename)
{
	int i_number ;
	int i; 
	int address[10] ;
	int active_node_location ;
	i_number=findAFileInFileTable( filename , &active_node_location) ;
	if( i_number!=-1 )
	{
		if( isAOperationElgal(i_number, 'R' )==1 )
		{
			for( i=0 ; i<10; i++ )
				address[i]=i_node[i_number].file_address[i] ;
			for( i=0; i<10; i++ )
			{
				printf("%s", fileBlock[address[i]].p);
			}
			return ;
		}
		else
		{
			printf("权限不对,对不起!\n") ;
			return ;
		}
	}
	for(i=0;i<512;i++) 
	{ 
		if(strcmp(filename,root[i].file_name)==0) 
		{ 
			i_number=i; 
		}
	} 
	for( i=0; i<10; i++ )
		address[i]=i_node[i_number].file_address[i] ;
	if( (currentuser!=i_node[i_number].file_userid) && (G_Read==(G_Read&i_node[i_number].file_mode))||
		currentuser==i_node[i_number].file_userid )
	{

		for( i=0; i<10; i++ )
		{
			
			printf("%s", fileBlock[address[i]].p);
		}
		return ;
	}
	printf("对不起,你无法读文件!\n") ;

}

void callback(int length)    /* 回收磁盘空间  */
{ 
	int i,j,k,m,q=0; 
	for(i=length-1;i>=0;i--) 
	{ 
		k=address_buffer[i];     /* 需要提供要回收的文件的地址  */
		m=49-super_block.n;    /* 回收到栈中的哪个位置  */
		if(super_block.n==50)   /* 注意 当super_block.n==50时 m=-1;的值  */
		{        /* super_block.n==50的时候栈满了,要将这个栈中的所有地址信息写进下一个地址中  */
			for(j=0;j<50;j++) 
			{ 
				memory[k].free[j]=super_block.free[j]; 
			} 
			super_block.n=0; 
			memory[k].n=50; 
		} 
		memory[k].a=0; 
		if(m==-1) 
		{ 
			m=49;      /* 将下一个文件地址中的盘块号回收到栈底中,这个地址中存放着刚才满栈的地址的信息  */
		} 
		super_block.free[m]=address_buffer[i]; /* 将下一个文件地址中的盘块号回收到栈中  */
		super_block.n++; 
	} 
} 

void allot(int length)     /* 分配空间  */
{ 
	int i,j,k,m,p; 
	for(i=0;i<length;i++) 
	{ 
		k=50-super_block.n;    /* 超级块中表示空闲块的指针  */
		m=super_block.free[k];   /* 栈中的相应盘块的地址  */
		p=super_block.free[49];   /* 栈中的最后一个盘块指向的地址  */
		if(m==-1||memory[p].a==1)  /* 检测是否还有下一组盘块  */
		{ 
			printf("内存不足,不能够分配空间\n"); 
			callback(length); 
			break; 
		} 
		if(super_block.n==1)
		{
			memory[m].a=1;    /* 将最后一个盘块分配掉  */
			address_buffer[i]=m; 
			super_block.n=0;   
			for(j=0;j<memory[m].n;j++) /* 从最后一个盘块中取出下一组盘块号写入栈中  */
			{ 
				super_block.free[j]=memory[m].free[j]; 
				super_block.n++; 
			} 
			 continue;     /* 要跳过这次循环,下面的语句在IF中已经执行过  */
		} 
		address_buffer[i]=m;     /* 栈中的相应盘块的地址写进 文件地址缓冲区  */
		memory[m].a=1;   
		super_block.n--; 
	} 
} 

void create_file(char filename[],int length) /* 创建文件  */
{ 
	int i,j; 
	for(i=0;i<512;i++) 
	{ 
		if(strcmp(filename,root[i].file_name)==0) 
		{ 
			printf("文件已经存在,不允许建立重名的文件\n"); 
			return; 
		} 
	} 
	for(i=0;i<512;i++) 
	{ 
		if(root[i].i_num==-1) 
		{ 
			root[i].i_num=i; 
			strcpy(root[i].file_name,filename); 
			strcpy(root[i].dir_name,cur_dir);  /* 把当前目录名 给新建立的文件  */
			i_node[i].file_style=style; 
			i_node[i].file_length=length; 
			i_node[i].file_userid=currentuser;
			i_node[i].file_groupid=( currentuser==User1)?User2:User1 ;
			//初始文件的权限对文件主都有,对同组用户只有读的权限
			i_node[i].file_mode=O_Read|O_Write|O_Delete|O_Execute|G_Read;
			InsertAFileIntoSystemFileTable(filename, root[i].i_num) ;
			allot(length); 
			for(j=0;j<length;j++) 
			{ 
				i_node[i].file_address[j]=address_buffer[j]; 
			} 
			break; 
		} 
	} 
} 

void create_dir(char filename[])    /* 创建目录  */
{ 
	style=0;         /* 0代表文件类型是目录文件  */
	create_file(filename,4); 
	style=1;         // 用完恢复初值 
} 

void del_file(char filename[])     /* 删除文件  */
{ 
	int i,j;
	
	int i_number ;
	for(i=0;i<512;i++) 
	{ 
		if(strcmp(filename,root[i].file_name)==0) 
		{ 
			i_number=i; 
			break ;
		}
	} 
	if(i==512)
	{
		printf("对不起,找不到相应的文件\n");
		return;
	}
	if( ((currentuser!=i_node[i_number].file_userid) && (G_Delete==G_Delete&i_node[i_number].file_mode))||
		currentuser==i_node[i_number].file_userid )
	{
		
		strcpy(root[i].file_name,"") ;
		strcpy(root[i].dir_name,"") ;
		for(j=0;j<10;j++)     /* 删除文件后要将文件属性和目录项的各个值恢复初值  */
		{ 
			i_node[i_number].file_address[j]=-1; /* 地址恢复初值  */
		} 
		root[i_number].i_num=-1 ;
		return ;
	} 
	else
	{
				printf("对比起,你无权删除此文件\n");
				return ;
	}
} 

void del_dir(char filename[])     /* 删除目录   需要判断目录下时候为空,不为空就不删除  */
{ 
	int i,j,k; 
	for(i=0;i<512;i++)       /* 还要加条件判断要删除的目录是不是当前目录  */
	{ 
		k=root[i].i_num;      /* 找到目录名字  */
		if( strcmp(root[i].file_name,filename)==0 && strcmp(cur_dir,filename)!=0 && (i_node[k].file_style)==0 ) 
		{ 
			for(j=0;j<512;j++) 
			{ 
				if(strcmp(filename,root[j].dir_name)==0) 
				{ 
					
					del_file(root[j].file_name) ;
			
				}
			}
			del_file(filename);
			break; 
		} 
		else if( strcmp(root[i].file_name,filename)==0 && strcmp(cur_dir,filename)==0 && (i_node[k].file_style)==0 )
		{
			printf("对不起,你在当前目录下无法删除该目录,退回到父目录后在执行删除操作!\n") ;
			break;
		}
	} 
	if(i==512) 
	{ 
		printf("这个不是目录文件 或者不存在这个目录,或者你要删除的是当前目录\n"); 
	} 
} 

void display_curdir()         /* 显示当前目录下的文件列表  */
{ 
	int i,k; 
	printf("\t\t文件名字  文件类型  文件长度  所属目录\n"); 
	for(i=0;i<512;i++) 
	{ 
		if(strcmp(cur_dir,root[i].dir_name)==0)   /* 查询文件中 所在目录信息和当前目录信息相同的数据  */
		{ 
			k=root[i].i_num; 
			printf("\t\t  %s\t",root[i].file_name);  /* 文件名  */
			printf("\t%d\t",i_node[k].file_style);  /* 文件的类型  */
			printf("%d\t",i_node[k].file_length);  /* 文件的长度  */
			printf("%s\n",root[i].dir_name);   /* 文件所在的目录  */
		} 
	} 
} 

void display_dir(char filename[])     /* 进入指定的目录    */
{ 
	int i,k;   
	for(i=0;i<512;i++) 
	{ 
		k=root[i].i_num;       /* 判断文件类型是不是目录类型  */
		if((strcmp(filename,root[i].file_name)==0) && (i_node[k].file_style==0))     
		{ 
			strcpy(cur_dir,filename);    /* 将要进入的指定目录设置为当前目录  赋值不要反了strcpy(目的,源)  */
			break; 
		} 
	} 
	if(i==512) 
	{ 
		printf("没有这个目录\n"); 
	} 
} 
void open_file(char filename[])        /* 打开文件  */
{ 
	int i,j,k; 
	printf("\t\t文件名字  文件类型  文件长度  所属目录\n"); 
	for(i=0;i<512;i++) 
	{ 
		k=root[i].i_num; 
		if(strcmp(filename,root[i].file_name)==0 && (i_node[k].file_style==1)) 
		{ 
			printf("\t\t  %s\t",root[i].file_name);   /* 文件名  */
			printf("\t%d\t",i_node[k].file_style);   /* 文件的类型  */
			printf("%d\t",i_node[k].file_length);   /* 文件的长度  */
			printf("%s\n",root[i].dir_name);    /* 文件所在的目录  */
			printf("\n"); 
			InsertAFileIntoSystemFileTable(filename, k) ;
			
			break; 
		} 
	} 
	if(i==512) 
	{ 
		printf("没有这个文件 或者这个文件不是正规文件\n"); 
	} 
} 

void back_dir()         /* 返回上一级目录  */
{ 
	int  i,k; 
	for(i=0;i<512;i++)       /* 查询和当前目录名相同的目录文件名  */
	{ 
		k=root[i].i_num; 
		if(strcmp(cur_dir,root[i].file_name)==0 && (i_node[k].file_style==0))   
		{ 
			strcpy(cur_dir,root[i].dir_name); /* 将查询到的目录文件名  所在的目录赋值给当前目录  */
		} 
	} 

} 
void display_sys()        /* 显示系统信息(磁盘使用情况)  */
{ 
	int i,m,k=0; 
	for(i=0;i<512;i++) 
	{ 
		if(memory[i].a==0) 
		k++; 
	} 
	m=512-k; 
	printf("空闲的盘块数是:\t"); 
	printf("%d\n",k); 
	printf("使用的盘块数是:\t"); 
	printf("%d\n",m); 
} 
void help()          /* 显示帮助信息  */
{  


	printf("1------dir----------------------查看当前目录文件列表(dir)\n");
	printf("2------open---------------------打开文件(open + 空格 + 文件名)\n"); 
	printf("3------ls-----------------------查看系统信息(ls)\n");
	printf("4------mkdir--------------------创建目录(mkdir  + 空格 + 目录名)\n"); 
	printf("5------create-------------------创建文件(create  + 空格 + 文件名)\n"); 
	printf("6------read---------------------文件的的读(read +文件名)\n");
	printf("7------write--------------------文件的写(write + 文件名)\n");
	printf("8------close--------------------文件的的关闭(close + 文件名)\n");	
	printf("9------delete-------------------删除文件(delete + 空格 + 文件名)\n"); 
	printf("10-----deldir-------------------删除目录(del + 空格 + 目录名)\n"); 
	printf("11-----cd-----------------------进入当前目录下的指定目录(cd + 空格 + 目录名)\n"); 
	printf("12-----cd..---------------------返回上一级目录(cd..)\n"); 
	printf("13-----help---------------------显示帮助命令(help)\n");
	printf("14-----logout-------------------退出文件模拟(logout)\n");
	printf("15-----su-----------------------切换用户(su)\n");
	printf("16-----CMode--------------------赋予用户权限(CMode)\n");
} 


void main()          /* 主函数  */
{ 
	char tmp[10],com[10],tmp1[10];
	int i, j=0,p,len=0; 
	FILE *fp; 
	printf("**************************欢迎使用模拟unix文件系统*******************\n");
	if((fp=fopen("system","rb"))==NULL)   /* 判断系统文件是否存在  */
	{ 
		format(); 
		InitUserFileTable() ;
		InitSystemFileTable();
		InitActiveNode() ;
	} 
	else 
	{ 
		read_file(fp);       /* 读取系统文件的内容  */
	} 
	strcpy(cmd[1].com,"dir"); 
	strcpy(cmd[2].com,"open"); 
	strcpy(cmd[3].com,"ls"); 
	strcpy(cmd[4].com,"mkdir"); 
	strcpy(cmd[5].com,"create"); 
	strcpy(cmd[6].com,"read"); 
	strcpy(cmd[7].com,"write"); 
	strcpy(cmd[8].com,"close"); 
	strcpy(cmd[9].com,"delete"); 
	strcpy(cmd[10].com,"deldir"); 
	strcpy(cmd[11].com,"cd"); 
	strcpy(cmd[12].com,"cd.."); 
	strcpy(cmd[13].com,"help"); 
	strcpy(cmd[14].com,"logout"); 
	strcpy(cmd[15].com,"su") ;
	strcpy(cmd[16].com,"CMode") ;
	

	while(1) 
	{ 
	
		while(!Login()) ;

		while(1)
		{
			printf("[%s @ %s]#",user,cur_dir); 
			scanf("%s",com);       /* 输入命令并且查找命令的相关操作  */
			for(i=1;i<17;i++)       
			{ 
				if(strcmp(com,cmd[i].com)==0) 
				{ 
					p=i; 
					break; 
				} 
			} 
			if(i==17)         /* 如果没有这个语句以后输入的命令都和第一次输入的效果一样  */
			{ 
				p=17; /* 随便的一个值  */
			} 
			switch(p) 
			{ 
				case 1: display_curdir();     /* 查看当前目录下的文件列表        */
						break; 
				case 2: scanf("%s",tmp);     /* 查看文件  */
						open_file(tmp);   
						break; 
				case 3: display_sys();      /* 查看系统信息  */
						break; 
				case 4: scanf("%s",tmp);      /* 创建目录      */
						create_dir(tmp);   
						break; 
				case 5: scanf("%s",tmp);     /* 创建文件  */
						create_file(tmp,80);   
						break; 

				case 6: scanf("%s",tmp);  
						readfile(tmp);
						break;
				case 7: scanf("%s",tmp);  
						writefile(tmp);
						break;
				case 8: scanf("%s",tmp); 
					  closeFile(tmp);
					  break;
				case 9: scanf("%s",tmp);     /* 删除文件  */
						for(i=0;i<512;i++)     /* 判断文件是不是正规文件  */
						{ 
							j=root[i].i_num; 
							if(strcmp(tmp,root[i].file_name)==0 && (i_node[j].file_style)==1) 
							{ 
								del_file(tmp); 
								break; 
							} 
						} 
						if(i==512) 
						{ 
							printf("这个不是正规文件文件\n"); 
						}     
						break; 
				case 10: 
						 scanf("%s",tmp);     /* 删除目录  */
						 del_dir(tmp);   
						 break; 
				case 11: scanf("%s",tmp1);     /* 进入当前目录下的指定目录   相当于进入目录  cd  +  目录名  */
						 display_dir(tmp1); 
						 break; 
				case 12: back_dir();       /* 返回上一级目录  */
						 break; 
				case 13: help(); 
						 break; 
				case 14: write_file(fp);      /* 将磁盘利用信息写进系统文件,退出  */
						 break;
				case 15: su() ;
						 break ;
				case 16: scanf("%s",tmp1);   
						 changeFileMode(tmp1) ;
						 break ;
				default: printf("SORRY,没有这个命令\n"); 
						 break; 
			} 
		} 
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -