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

📄 unix文件模拟系统.cpp

📁 该模拟的UNIX文件系统应该有以下功能: 多级目录的结构
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream.h>
#define BLOCKSIZ		512			/* 磁盘块大小 */
#define MAXBLOCK		2048	    /* 磁盘总块数 */
#define SYSOPENFILE		40			/* 系统打开表最大数 */
#define DIRNUM			128			/* 文件数目 */
#define DIRSIZ			14			/* 文件名长度 */
#define USERNAMESIZ		12			/* 用户名长度 */
#define PWDSIZ			12			/* 密码长度 */
#define PWDNUM			32			/* 允许密码个数 */
#define NOFILE			16			/* 用户打开表最大数 */
#define NADDR			13			/* 物理块号数 */
#define NHINO			64		    /* 查找内存i节点的Hash表桶数 */
#define USERNUM			8			/* 允许的最大用户数 */
#define DINODESIZ		64			/* 磁盘i节点大小 */
#define DINODEBLK		128			/* 磁盘i节点占用盘块数 */
#define FILEBLK			MAXBLOCK - DINODEBLK -2	   /* 文件区占用磁盘块数 */
#define NICFREE			50		                   /* 空闲块堆栈可装入的物理块数 */
#define NICINOD			50                         /* 空闲磁盘i节点堆栈可装入的i节点数 */
#define DINODESTART 2 * BLOCKSIZ		           /* 磁盘i节点开始地址 */
#define DATASTART (2 + DINODEBLK) * BLOCKSIZ	   /* 文件区开始地址 */


#define DIEMPTY			000000			/* 空闲磁盘i节点    */
#define DIREG			001000			/* 普通文件         */
#define DIDIR			002000			/* 子目录文件       */
#define UREAD			000001			/* 文件主"读"权限   */
#define UWRITE			000002			/* 文件主"写"权限   */
#define UEXE			000004			/* 文件主"执行"权限 */
#define GREAD			000010			/* 同组用户"读"权限 */  
#define GWRITE			000020			/* 同组用户"写"权限 */
#define GEXE			000040			/* 同组用户"执行"权限*/
#define OREAD			000100			/* 其它用户"读"权限  */
#define OWRITE			000200			/* 其它用户"写"权限  */
#define OEXE			000400		    /* 其它用户"执行"权限*/

#define READ			000001			/* 文件"读打开"标志  */
#define WRITE			000002			/* 文件"写打开"标志  */
#define EXICUTE			000004			/* 文件"执行"标志    */

/* 超级用户权限,对所有文件可进行所有操作 */
#define SUPERMODE		000777

/* 一般用户"默认"模式,对其它文件可"读",对自己的文件可"写"可"执行" */
#define NORMALMODE		000117	

/* 文件或目录的默认"模式,所有用户均可"读",文件主可"写" */
#define DEFAULTMODE		000113

/* openmode */
#define O_RDONLY		000001			/* 只读 */
#define O_WRONLY		000002			/* 只写 */
#define O_RDWR			000003			/* 读/写 */
#define O_APPEND		010000			/* 读/写指针指到文件尾 */
#define O_TRUNC			020000		/* 如果文件存在,清空文件 */
#define O_CREAT			040000		/* 如果文件不存在,创建文件 */

#define ROOTDIR			2		/* 根目录所在磁盘i节点号 */

#define SEEK_SET		0		/* fseek调用参数,指针指向文件首 */

/* 文件系统(内存i节点)数据结构 */
struct inode
{
	struct inode * i_forw;				/* 前向指针 */
	struct inode * i_back;				/* 后向指针 */
	unsigned int i_ino;				/* 磁盘i节点标志 */
	unsigned int i_count;				/* 引用计数 */
	unsigned short i_number;		/* 关联文件数,当为0时,则删除该文件 */
	unsigned short i_mode;				/* 文件属性与存取权限 */
	unsigned short i_uid;				/* 文件主标识 */
	unsigned short i_gid;				/* 同组用户标识 */
	unsigned short i_size;				/* 文件大小 */
	unsigned int i_addr[NADDR];			/* 物理块号 */
};

/* 磁盘i节点数据结构 */
struct dinode
{
	/* 磁盘i节点的所有变量在内存i节点中都有相应的变量与之相适应 */
	unsigned short di_number;			/* 关联文件数 */
	unsigned short di_mode;				/* 文件属性与存取权限 */
	unsigned short di_uid;				/* 文件主标识 */
	unsigned short di_gid;				/* 同组用户标识 */
	unsigned short di_size;				/* 文件大小 */
	unsigned int di_addr[NADDR];		/* 物理块号 */
};

/* 查找内存i节点的hash表数据结构 */
struct hinode
{
	struct inode * i_forw;				/* hash 表指针 */
};

/* 超级块数据结构 */
struct filsys
{
	unsigned int s_ninode;				/* 空闲磁盘i节点数 */
	unsigned int s_nfree;				/* 空闲盘块数 */
	unsigned short s_pfree;				/* 空闲盘块指针 */
	unsigned short s_pinode;			/* 空闲磁盘i节点栈指针 */
	unsigned int s_rinode;	/* 铭记磁盘i节点,记录下一组要装入的磁盘i节点号 */
	unsigned int s_free[NICFREE];		        /* 空闲盘块堆栈 */
	unsigned int s_inode[NICINOD];		     /* 空闲磁盘i节点堆栈 */

};

/* 目录数据结构 */
struct direct
{
	char d_name[DIRSIZ];				/* 文件名 */
	unsigned short d_ino;				/* 磁盘i节点号 */
};

#define DIRECTSIZ sizeof( struct direct )	        /* 目录结构长度 */

/* 目录数据结构 */
struct dir
{
	struct direct direct[DIRNUM];		        /* 目录项 */
	unsigned short size;				/* 当前目录大小 */
};

/* 系统打开表数据结构 */
struct file
{
	char f_flag;					/* 文件操作标志 */
	unsigned int f_count;				/* 引用计数 */
	struct inode * f_inode;				/* 指向内存i节点 */
	unsigned long f_off;				/* 读/写指针 */
};

/* 用户打开表数据结构 */
struct user
{
	char u_name[USERNAMESIZ];			/* 用户名,登陆时用 */
	char password[PWDSIZ];				/* 用户密码,登陆时用 */
	unsigned short u_default_mode;		        /* 用户默认模式 */
	unsigned short u_uid;				/* 用户标志 */	
	unsigned short u_gid;				/* 用户组标志 */
	unsigned short u_ofile[NOFILE];		        /* 用户打开文件表 */
};

/* 下为全局变量 */
 struct hinode hinode[NHINO];			/* 查找内存i节点的hash表 */
struct dir dir;			/* 当前目录(在内存中全部读入) */
 struct file sys_ofile[SYSOPENFILE];	        /* 系统打开表 */
 struct filsys filsys;			/* 内存中的超级块 */
struct user user[USERNUM];			/* 登陆用户表 */
 FILE *fd;					/* 虚拟磁盘的文件指针 */
 struct inode * cur_path_inode;		        /* 当前目录路径 */
 int user_id;					/* 当前用户的ID */
 struct direct cur_direct[NOFILE];	        /* 路径 */
 unsigned short cur_dir_id;			/* 当前目录指针 */

unsigned short access( struct inode * inode );
unsigned int balloc();
void bfree( unsigned int block_num );
void bread( unsigned int ino, char * buf );
void bwrite( unsigned int ino, char * buf );
int cmdexp();
void chmod( char * pathname, char * modename );
void getcmd();
int clearbuf();
void _dir();
void mkdir( char * dirname );
void chdir( char * dirname );
void rmdir( char * dirname );
struct dir getdir( unsigned int dinodeid, char * dirname );
void putdir( unsigned int dinodeid, struct dir dir);
int format();
void halt();
struct inode * ialloc();
void ifree(unsigned int dinodeid);
struct inode * iget( unsigned int dinodeid );
void iput( struct inode * pinode );
void init();
void edlin( char * filename );
void list( char * filename );
int write( int fh, char * buf, unsigned int nbyte );
int read( int fh, char * buf, unsigned int nbyte );
void close( int cfd );
int login ();
void _delete( char * filename );
int quit();
void reg();
unsigned short iname( struct dir dir, char * name );
int namei( char * name );
void getpath();

unsigned int pre_dinodeid;		// 所搜索路径的父目录i节点 

void message()
{


printf("mkdir命令      功能:创建一个目录        语法:mkdir   dir-name\n");
printf("rmdir命令      功能:删除一个目录        语法:rmdir   dir-name\n");
printf("cd 命令        功能:改变工作目录        语法:cd [directory]\n");
printf("ls 命令        功能: 列出所有目录与文件  语法:ls [目录或是文件]\n");
printf("create命令     功能:创建一个文件        语法:create   file-name\n");  
printf("rm命令         功能:删除不需要的文件    语法:rm    file-name\n");   
printf("cat命令        功能:显示一个文件    语法:cat   file-name\n");   
printf("help命令       功能:帮助信息            语法:help\n"); 
printf("exit 命令      功能:退出程序            语法:exit\n"); 
}



// 用户权限检测函数:access() 
unsigned short access( struct inode * inode )
{	unsigned short can = 0;
	// 该用户可读检测
	if(( inode->i_mode & OREAD ) ||
		(( inode->i_mode & GREAD ) && 
		( user[user_id].u_gid == inode->i_gid )) ||
		((inode->i_mode & UREAD) &&
		( user[user_id].u_uid == inode->i_uid )))
		can = can | READ;

	// 该用户可写检测  
	if(( inode->i_mode & OWRITE ) ||
		(( inode->i_mode & GWRITE ) && 
		(user[user_id].u_gid == inode->i_gid )) ||
		(( inode->i_mode & UWRITE) &&
		( user[user_id].u_uid == inode->i_uid )))
		can = can | WRITE;

	// 该用户可执行检测  
	if(( inode->i_mode & OEXE ) ||
		(( inode->i_mode & GEXE ) && 
		( user[user_id].u_gid == inode->i_gid )) ||
		(( inode->i_mode & UEXE) &&
		( user[user_id].u_uid == inode->i_uid )))

	can = can | EXICUTE;
	return can;
}
//空闲盘块分配函数:balloc()
static unsigned int block_buf0[BLOCKSIZ];
unsigned int balloc()
{	unsigned int free_block, free_block_num;
	unsigned  int i;
	if( filsys.s_nfree == 0 )				// 磁盘已满,无空闲盘块  
	{	printf( "Disk has no space\n" );
		return -1;
	}

	free_block = filsys.s_free[filsys.s_pfree];		// 取得当前空闲盘块  
	if( filsys.s_pfree == 0 )				// 已经是栈底  
	{

	fseek( fd, DATASTART + BLOCKSIZ * filsys.s_free[filsys.s_pfree], SEEK_SET );
	fread(block_buf0, 1, BLOCKSIZ, fd );


		free_block_num = block_buf0[NICFREE];			// 读取该空闲盘块组的盘块数  
		// 把盘块组放到空闲盘块号栈上
		for( i = 0; i < free_block_num; i++ )
			filsys.s_free[i] = block_buf0[i];
		filsys.s_pfree = free_block_num - 1;			// 指针指向栈顶  	
	}
	else
		filsys.s_pfree--;					// 栈指针下移一位  
	filsys.s_nfree--;						// 空闲盘块少1 

	return free_block;					// 返回空闲盘块号数  
}

// 空闲盘块回收函数:bfree
void bfree( unsigned int block_num )
{	int i;
	filsys.s_pfree++;						// 栈指针上移一位  
	if( filsys.s_pfree == NICFREE )					// 空闲盘块堆栈已满  
	{	block_buf0[NICFREE] = NICFREE;	
// 空闲盘块堆栈的盘块数NICFREE记入缓冲区  
		for( i = 0; i < NICFREE; i++ )
			block_buf0[i] = filsys.s_free[i];		
// 把空闲盘块数据写入缓冲区  
		filsys.s_pfree = 0;					// 栈指针指向栈底  
	

	fseek( fd, DATASTART + BLOCKSIZ * block_num, SEEK_SET );
	fwrite(  block_buf0 , 1, BLOCKSIZ, fd );


	}
	filsys.s_free[filsys.s_pfree] = block_num;			// 回收盘块  
	filsys.s_nfree++;					// 空闲盘块多1  
}
// 读相应盘块号的数据函数:bread 
void bread( unsigned int ino, char * buf )
{	fseek( fd, DATASTART + BLOCKSIZ * ino, SEEK_SET );
	fread( buf, 1, BLOCKSIZ, fd );
}
// 写相应盘块号的数据函数:bwrite
void bwrite( unsigned int ino, char * buf )
{
	fseek( fd, DATASTART + BLOCKSIZ * ino, SEEK_SET );
	fwrite( buf, 1, BLOCKSIZ, fd );
}
// 命令解释层函数cmdexp()
char input_buf[20];		//命令行输入缓冲区
int over;			//命令行结束标记
int cmdexp()
{	char buf[5];
	over = 0;
	// 显示命令提示行
	printf("[%s@localroot]#", user[user_id].u_name, cur_direct[cur_dir_id].d_name );
	
	// 读取用户输入  
	getcmd();

	// 显示当前目录  
	if(strcmp( input_buf, "ls" ) == 0 )
	{	_dir();
		clearbuf();
		return 0;
	}

	// 改变当前目录  
	if (strcmp( input_buf, "cd" ) == 0 ) 
	{	getcmd();
		chdir( input_buf );
		clearbuf();
		return 0;
	}

	// 创建目录(建立子目录)  
	if( strcmp( input_buf, "mkdir" ) == 0 ) 
	{
		if( over )
		{	printf( "mkdir: too few arguments\n" );		// mkdir命令参数不足  
			clearbuf();
			return 0;
		}
		getcmd();
		if( input_buf[0] == '\0' )
		{	printf( "mkdir: too few arguments\n" );
			clearbuf();
			return 0;
		}
		mkdir( input_buf );
		while( !over )
		{
			getcmd();
			if( input_buf[0] != '\0' )
				mkdir( input_buf );
		}
		clearbuf();
		return 0;
	}

	// 删除目录
	if( strcmp( input_buf, "rmdir" ) == 0 ) 
	{
		if( over )
		{	printf( "rmdir: too few arguments\n" );
			clearbuf();
			return 0;
		}
		getcmd();
		if( input_buf[0] == '\0' )
		{	printf( "rmdir: too few arguments\n" );
			clearbuf();
			return 0;
		}
		rmdir( input_buf );
		while( !over )
		{	getcmd();
			if( input_buf[0] != '\0' )
				rmdir( input_buf );
		}
		clearbuf();
		return 0;
	}

	// 显示文件
	if(strcmp( input_buf, "cat" ) == 0 )
	{if( over )
		{	printf( "list: too few arguments\n" );
			clearbuf();
			return 0;
		}
		getcmd();
		if( input_buf[0] == '\0' )
		{	printf( "list: too few arguments\n" );
			clearbuf();
			return 0;
		}
		list( input_buf );
		while( !over )
		{	getcmd();
			if( input_buf[0] != '\0' )
				list( input_buf );
		}
		clearbuf();
		return 0;
	}

	// 删除文件  
if( strcmp( input_buf, "rm" ) == 0 )
	{if( over )
		{	printf( "delete: too few arguments\n" );
			clearbuf();
			return 0;
		}
		getcmd();
		if( input_buf[0] == '\0' )
		{	printf( "delete: too few arguments\n" );
			clearbuf();
			return 0;
		}
		_delete( input_buf );
		while( !over )
		{	getcmd();
			if( input_buf[0] != '\0' )
				_delete( input_buf );
		}
		clearbuf();
		return 0;
	}

// 建立新文件并编辑
	if( strcmp( input_buf, "create" ) == 0 ) 
		{	getcmd();
		edlin( input_buf );
		clearbuf();
		return 0;
	}
	// 改变目录或文件属性  
	if( strcmp( input_buf, "chmod" ) == 0 )
	{	getcmd();
		strcpy( buf, input_buf );
		getcmd();
		chmod( input_buf, buf );
		clearbuf();
		return 0;
	}
	if( strcmp( input_buf, "exit" ) == 0 )
		{	quit();
		clearbuf();
		return 1;
	}

   	if( strcmp(input_buf, "help" ) == 0 )
	{
	message();
	clearbuf();
	return 0;
	}
	// 找不到该命令  
	if( input_buf[0] != '\0' )
	{
		printf( "%s: command not found\n", input_buf );
		clearbuf();
			return 0;
	}
return 0;

}
// 取得命令函数:getcmd() 
void getcmd()
{	int i;
	i = 0;
	// 取得命令  
	while( !over )
	{	input_buf[i] = getchar();
		if( input_buf[i] == ' ' )
		{	if( i == 0 )					// 命令行的开始是空格,应舍去  
				i--;
			else
			{
				input_buf[i]='\0';
				break;
			}
		}
		else
			if( input_buf[i] == '\n' )
			{
				over = 1;
				input_buf[i]='\0';
				break;
			}
		i++;
	}
}

// 清空缓冲区  
int clearbuf()
{ while( !over )
	{	if( getchar() =='\n' )
		break;
	}
	return 0;
}

//显示目录函数dir()		
extern char end_path_name[DIRSIZ];					// 最后路径名字  

void _dir()
{
	unsigned int di_mode;
	int i, j, filenum, dirnum;
	struct inode * inode;
	filenum = 0;										// 文件计数  
	dirnum = 0;											// 目录计数  
	printf("CURRENT DIRECTORY :\n" );
    printf("<DIRECTORY||FILE>        access       uid      gid      size    name\n" );

	for( i = 2; i < dir.size; i++ )
	{
		if( dir.direct[i].d_ino != DIEMPTY )
		{	inode = iget( dir.direct[i].d_ino );
			di_mode = inode->i_mode;
			if( di_mode & DIDIR )
			{	printf( "<DIRECTORY>" );						// 目录文件  

⌨️ 快捷键说明

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