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

📄 main.c

📁 UNIX模拟系统模拟得很完善!
💻 C
📖 第 1 页 / 共 4 页
字号:
#include "os.h"
#include "stdio.h"
#include "string.h"
#include "windows.h"
void textcolor(int color);

//设置文本输出颜色
void textcolor (int color)
{
    SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), color );
}

// 用户权限检测函数: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;
	int i;

	textcolor(5);
	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 )					// 已经是栈底  
	{	// 读取栈底盘块号所对应的盘块数据
		bread( filsys.s_free[filsys.s_pfree], block_buf0 );
		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;					// 栈指针指向栈底  
		bwrite( block_num, block_buf0 );			// 缓冲区内容写入新回收的盘块  
	}
	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;
	// 显示命令提示行

	textcolor(12);
	printf("^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
	printf("如需帮助请由终端输入'help'\n");
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n");
	textcolor(7);

	printf( "[%s@localhost]# ", user[user_id].u_name, cur_direct[cur_dir_id].d_name );
	
	// 读取用户输入  
	getcmd();

	//显示帮助文件
	if(strcmp( input_buf, "help" ) == 0 ) 
	{	getcmd();
		help();
		clearbuf();
		return 0;
	}

	// 显示当前目录  
	if(( strcmp( input_buf, "dir" ) == 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 )
		{	textcolor(12);
			printf( "mkdir: 请确认是否输入目录名\n" );		// mkdir命令参数不足
			textcolor(7);
			clearbuf();
			return 0;
		}
		getcmd();
		if( input_buf[0] == '\0' )
		{	textcolor(12);
			printf( "mkdir: 请确认是否输入目录名\n" );
			textcolor(7);
			clearbuf();
			return 0;
		}
		mkdir( input_buf );
		while( !over )
		{
			getcmd();
			if( input_buf[0] != '\0' )
				mkdir( input_buf );
			
		}
		textcolor(14);
		printf("目录创建成功!\n\n");
		textcolor(7);
		clearbuf();
		return 0;
	}

	// 删除目录
	if( strcmp( input_buf, "rmdir" ) == 0 ) 
	{
		if( over )
		{	textcolor(12);
			printf( "rmdir: 请确认是否输入目录名\n" );
			textcolor(7);
			clearbuf();
			return 0;
		}
		getcmd();
		if( input_buf[0] == '\0' )
		{	textcolor(12);
			printf( "rmdir: 请确认是否输入目录名\n" );
			textcolor(7);
			clearbuf();
			return 0;
		}
		rmdir( input_buf );
		while( !over )
		{	getcmd();
			if( input_buf[0] != '\0' )
				rmdir( input_buf );
		}
		textcolor(14);
		textcolor(7);
		clearbuf();
		return 0;
	}

	// 显示文件
	if(strcmp( input_buf, "open" ) == 0 || strcmp( input_buf, "read" ) == 0)
	{if( over )
		{
		textcolor(12);
		printf( "open/read: 请确认是否输入文件名\n" );
		textcolor(7);

			clearbuf();
			return 0;
		}
		getcmd();
		if( input_buf[0] == '\0' )
		{	textcolor(12);
			printf( "open/read: 请确认是否输入文件名\n" );
			textcolor(7);
			clearbuf();
			return 0;
		}
		list( input_buf );
		while( !over )
		{	getcmd();
			if( input_buf[0] != '\0' )
				list( input_buf );
		}
		textcolor(14);
		
		textcolor(7);
		clearbuf();
		return 0;
	}

	// 删除文件  
	if( strcmp( input_buf, "delete" ) == 0 )
	{if( over )
		{
		textcolor(12);
		printf( "delete: 请确认是否输入文件名\n" );
		textcolor(7);
			clearbuf();
			return 0;
		}
		getcmd();
		if( input_buf[0] == '\0' )
		{	textcolor(12);
			printf( "delete: 请确认是否输入文件名\n" );
			textcolor(7);
			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 || strcmp( input_buf, "write" ) == 0) 
		{	
		getcmd();
		textcolor(7);
		edlin( input_buf );
		textcolor(14);
		printf("文件创建成功!\n\n");
		textcolor(7);
		clearbuf();
		return 0;
	}

	if( strcmp (input_buf,"user") == 0)
	{
		getcmd();
		choice();
		clearbuf();
		return 0;
	}


	if( strcmp( input_buf, "quit" ) == 0 )
		{	quit();
		clearbuf();
		return 1;
	}

	// 找不到该命令  
	if( input_buf[0] != '\0' )
	{
		textcolor(12);
		printf( "%s: 找不到此命令,请确认。\n", input_buf );
		textcolor(7);
		clearbuf();
	}
	return 0;

}
// 取得命令函数:getcmd() 
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++;
	}
}

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

//显示目录函数dir()		
extern char end_path_name[DIRSIZ];					// 最后路径名字  
extern int pre_dinodeid;
void _dir()
{
	unsigned int di_mode;
	int i, j, filenum, dirnum;
	struct inode * inode;
	filenum = 0;											// 文件计数  
	dirnum = 0;		// 目录计数  
	textcolor(14);
	printf( "\n□当前目录信息□\n" );
	textcolor(7);	
	printf("===========================================================\n");
	textcolor(9);
	printf("  类型(d/-)  权限(r/w/x)   用户号     组号     大小    名称\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( "   d" );	// 目录文件 
			    printf("\t\t");
				dirnum++;
			}
			else
			{	printf( "   -" );								// 普通文件  
			    printf("\t\t");
				filenum++;
			}
			// 显示读写执行权限  
			for( j = 0; j < 3; j++ )
			{   if( di_mode % 2 )
					printf( "r" );							// 读权限  
				else
					printf( "-" );
				di_mode = di_mode / 2;						
				if( di_mode % 2 )							// 写权限  
					printf( "w" );
				else
					printf( "-" );
				di_mode = di_mode / 2;
				if( di_mode % 2 )							// 执行权限  
					printf( "x" );
				else
					printf( "-" );
				di_mode = di_mode / 2;
			}
			printf( "	%d	%d	%d	%s\n",	// 分别显示文件主uid,gid,文件大小和文件名  
				inode->i_uid, inode->i_gid, inode->i_size, dir.direct[i].d_name );
			iput( inode );
		}
	}
	textcolor(7);
	printf("===========================================================\n");
	printf("\n\t┄┄┄┄┄┄┄┄┄系统信息┄┄┄┄┄┄┄┄┄\n");
	textcolor(11);
	printf( "\n		%d files\n", filenum);				// 显示文件数  
	printf( "		%d directories\n", dirnum);			// 显示目录数  
	textcolor(7);
	printf("\t┄┄┄┄┄┄┄┄┄    END   ┄┄┄┄┄┄┄┄┄\n");
}

//创建目录函数:mkdir
void mkdir( char * dirname )
{	int i, dirid, dirpos;
	struct inode * inode, * pre_inode;
	struct dir tempdir;
	struct direct buf[BLOCKSIZ / DIRECTSIZ];
	unsigned int block;
	dirid = namei( dirname );
	if( dirid == -1 )
	{	textcolor(12);
		printf( "mkdir: cannot make directory '%s': No such file or directory\n", dirname );
		textcolor(7);
		return;
	}
	if( dirid != NULL )
	{	textcolor(12);
		printf( "mkdir: cannot make directory '%s': File exists\n", dirname );
		textcolor(7);
		return;
	}
	inode = ialloc();
	dirid = inode->i_ino;
	if( pre_dinodeid == cur_path_inode->i_ino )	// 如果所要创建的目录的父目录为当前目录  
	{
		dirpos = iname( dir, end_path_name );
		strcpy( dir.direct[dirpos].d_name, end_path_name );
		dir.direct[dirpos].d_ino = dirid;
		dir.size++;
	}
	else	// 所要创建的目录的父目录不是当前目录  
	{	tempdir = getdir( pre_dinodeid, " " );
		dirpos = iname( tempdir, end_path_name );
		strcpy( tempdir.direct[dirpos].d_name, end_path_name );
		tempdir.direct[dirpos].d_ino = dirid;
		tempdir.size++;
		putdir( pre_dinodeid, tempdir );
	}
	for( i = 0; i < BLOCKSIZ / DIRECTSIZ; i++ )// 初始化缓冲区  
	{	buf[i].d_ino = 0;
		strcpy( buf[i].d_name, " " );
	}
	// 把新建的目录内容写入缓冲区  
	strcpy( buf[0].d_name, ".." );
	buf[0].d_ino = pre_dinodeid;
	strcpy( buf[1].d_name, "." );
	buf[1].d_ino = dirid;
	// 写磁盘i节点相关信息  
	inode->i_size = 2 * DIRECTSIZ;
	inode->i_number = 1;
	inode->i_mode = DEFAULTMODE | DIDIR;
	inode->i_uid = user[user_id].u_uid;
	inode->i_gid = user[user_id].u_gid;
	block = balloc();
	inode->i_addr[0] = block;
	bwrite( block, buf );// 把缓冲区内容写入新分配的盘块中  
	iput( inode );
}

// 改变目录函数:chdir() 
void chdir( char * dirname )
{	unsigned int dirid;
	char buf[DIRSIZ];
	int i, len;
	dirid = namei( dirname );					// 获得当前目录的磁盘i节点号  
	if(( dirid == NULL ) || ( dirid == -1 ))				// 没有该目录  
	{	textcolor(12);
		printf( "bash: %s: No such file or directory\n",dirname );
		textcolor(7);
		return;
	}
	len = strlen( dirname );
	while( len )
	{	i = 0;
		while( len ) 
		{
			buf[i] = * dirname;
			if( buf[i] == '/' )
			{
				buf[i] = '\0';
				dirname++;
				len--;
				break;
			}
			i++;
			dirname++;
			len--;
		}
		if( !len )
			buf[i] = '\0';
		if( buf[0] == '\0' )
		{
			buf[0] = '/';
			buf[1] = '\0';
		}

		putdir( cur_path_inode->i_ino, dir );			// 把当前目录写回到磁盘  
		iput( cur_path_inode );
		dir = getdir( dirid, buf );				// 取得所要进入的目录的目录结构  
		cur_path_inode = iget( dirid );
		if( strcmp( buf, "/" ) == 0 )
			cur_dir_id = 0;
		else if( strcmp( buf, ".." ) == 0 )
		{if( cur_dir_id )
				cur_dir_id--;
		}
		else if( strcmp( buf, "." ) != 0 )
		{
			cur_dir_id++;

⌨️ 快捷键说明

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