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

📄 filsys.cpp

📁 大型实验:Unix文件管系统模拟。用内存中的一段区域模拟硬盘空间
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include <StdAfx.h>

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
#include "filsys.h"


/*------------------------------------------------
_facess()
	判断是否有操作该i节点的权限
	入口:user_id 用户表中用户的下标,
			inode 要访问的i节点
			mode 要操作的权限
------------------------------------------------*/
__int8 _faccess(__int8 u_id, struct inode *inode, unsigned __int16 mode)
{
	__int8 gid = user[u_id].u_gid;
	unsigned __int16 gmode;
	
	if(gid==GRUP_0)
		return 1;

	switch (mode)
	{
	case DIMODE_READ:
		gmode = MODER_GRUP(gid);
		gmode = gmode & inode->di_mode;
		if(mode & gmode)
			return 1;
		return 0;

	case DIMODE_WRITE:
		gmode = MODEW_GRUP(gid);
		gmode = gmode & inode->di_mode;
		if(mode & gmode)
			return 1;
		return 0;

	case DIMODE_EXICUTE:
		gmode = MODEW_GRUP(gid);
		gmode = gmode & inode->di_mode;
		if(mode & gmode)
			return 1;
		return 0;

	default:
		return 0;
	}
}



/*-------------------------------------------
balloc()
	申请磁盘块,返回可用磁盘块块号
	check : 7-12 19:25
--------------------------------------------*/
__int16 balloc()
{
	unsigned __int16 free_block, free_block_num;
	unsigned __int16	i;
	static unsigned __int16 block_buf[BLOCKSIZ/2];

	if (filsys.s_nfree==0)
	{
		AfxMessageBox("磁盘空间已被使用完!");
		return -1;
	}
	/*先判断是否到达栈底,是栈底则新分配栈*/
	if ((filsys.s_pfree==0) && (filsys.s_nfree>1))
	{
		fseek(fd,DATASTART+filsys.s_free[0]*BLOCKSIZ,SEEK_SET);
		fread(block_buf, 1, BLOCKSIZ, fd);
		free_block_num = block_buf[NICFREE];
		for (i = 0; i<NICFREE+1; ++i)
		{
			filsys.s_free[NICFREE-i] = block_buf[i];
		}	
		filsys.s_pfree = NICFREE;
	}

	free_block  = filsys.s_free[filsys.s_pfree];
	filsys.s_pfree--;

	filsys.s_nfree--;
	filsys.s_fmod = SUPDATE;
	return free_block;
}


/*----------------------------------------
bfree()
	check : 7-12 19:25
----------------------------------------*/
void bfree(unsigned __int16 block_num)
{
	int i;
	unsigned __int16 block_buf[BLOCKSIZ/2];

	if (filsys.s_pfree == NICFREE)	/* if s-free full */
	{
		for (i=0; i < NICFREE+1; i++)
		{
			block_buf[i]=filsys.s_free[NICFREE-i];
		}
		fseek(fd,DATASTART+filsys.s_free[NICFREE]*BLOCKSIZ,SEEK_SET);
		fwrite(block_buf, 1, BLOCKSIZ, fd);

		filsys.s_pfree = 0;
		filsys.s_free[0] = filsys.s_free[NICFREE];
	}
	filsys.s_pfree++;
	filsys.s_free[filsys.s_pfree] = block_num;
	filsys.s_nfree++;
	filsys.s_fmod = SUPDATE;
}


/*------------------------------------------
create()
   创建文件
   入口:filename 文件名
	出口:返回该文件在用户表中该用户的文件表的下标
------------------------------------------*/
__int8 _fcreate(char* filename)
{
	__int8 i,j;
	__int8 r_id = -1;
	__int16 di_ino,di_ith;
    struct inode *inode;

	di_ino = namei(filename);
	if(di_ino != -1)/* already existed*/
	{
		inode = iget( dir.direct[di_ino].d_ino);
        if(_faccess(user_id,inode,DIMODE_WRITE)==0)/*没有权限*/
        {
            iput(inode);
			AfxMessageBox("没有权限创建文件!");
            return -1;
        }

		if(inode->di_mode & DIMODE_DIR)/*filename is a direct*/
		{
			iput(inode);
			AfxMessageBox("已经有一个同名字的目录!");
            return -1;
		}
		else/*filename is a file*/
		{
//			AfxMessageBox("磁盘空间已被使用完!");
			printf("\nAre you sure delete the old file?(y/n):");
			if(getche()=='y')
			{
				_fdelete(filename);
				inode = NULL;
			}
			else{
				return -1;
			}
		}
	}
	
	
	inode = ialloc();
    di_ith = iname(filename);
	if(di_ith>0 && di_ith<DIRNUM)
	{
		dir.size++;
		dir.direct[di_ith].d_ino = inode->i_ino;

		inode->di_mode = MODE_GRUP(user[user_id].u_gid) | DIMODE_FILE;
		inode->di_uid = user[user_id].u_uid;
		inode->di_gid = user[user_id].u_gid;
		inode->di_size = 0;
		inode->di_number = 0;
		for(i=0; i<NADDR; ++i)
		{
			inode->di_addr[i] = 0;
		}

		for(i = 0; i<SYSOPENFILE; ++i)
		{
			if(sys_ofile[i].f_count==0)
			break;
		}
		for(j=0; j<NOFILE; j++)
		{
			if((user[user_id].u_ofile[j] < 0) || 
				(user[user_id].u_ofile[j] >= SYSOPENFILE-1) )
					break;
		}

		user[user_id].u_ofile[j] = i;
		inode->uf_id = j;
		sys_ofile[i].f_mode = FWRITE;
		sys_ofile[i].f_count = 1;
		sys_ofile[i].f_off = 0;
		sys_ofile[i].f_inode = inode;

		return j;
	}
	//on more 目录空间
	return -1;

}

/*------------------------------------------
adelete(char *filename)
        删除文件
------------------------------------------*/
__int8 _fdelete(char *filename)
{
        __int16 dinodeid,i;
        struct inode * inode;
        dinodeid = namei(filename);
        if(dinodeid != -1){
			inode = iget(dir.direct[dinodeid].d_ino);
			if(_faccess(user_id,inode,DIMODE_WRITE)==0)/*没有权限*/
			{
				iput(inode);
				printf("\ncreate access not allowed \n");
				return 0;
			}
			if(inode->di_mode & DIMODE_DIR)
			{
				iput(inode);
				return _rmdir(filename);
			}

			/*删除该节点的内容*/
			i = (__int16)(inode->di_size/BLOCKSIZ);
			for(; i >=0; --i)
			{
				bfree(inode->di_addr[i]);
			
			}
			//将该文件或是目录的后续文件或是目录迁移
			dir.size--;
			for(i = dinodeid; i<dir.size; ++i)
			{
				dir.direct[i].d_ino = dir.direct[i+1].d_ino;
				strcpy(dir.direct[i].d_name,dir.direct[i+1].d_name);
			}
			inode->di_number--;
			
			/*	free the mode in the memory */
			if (inode->i_forw == NULL){/*该节点为最后一个节点*/
				if(hinode[inode->i_ino%NHINO].i_forw == inode)
				{	
					/*该节点也是为第一个节点*/
					hinode[inode->i_ino%NHINO].i_forw = NULL;
				}
				else{
					inode->i_back->i_forw = NULL;
				}		
			}
			else{
				if(hinode[inode->i_ino%NHINO].i_forw == inode)
				{
					/*该节点是为第一个节点*/
					hinode[inode->i_ino%NHINO].i_forw = inode->i_forw;
					inode->i_back->i_forw = inode->i_forw;
				}
				else{
					inode->i_forw->i_back = inode->i_back;
					inode->i_back->i_forw = inode->i_forw;				
				}
			}
			ifree(inode);
			return 1;
		}
		return 0;
}



/*------------------------------------------
function:_dir()
	打印当前目录信息
	check :7-12 12:30
------------------------------------------*/
void _dir()
{
	__int16 di_mode;
	__int16 one;
	unsigned __int16  i,j;
	struct inode *temp_inode;


	printf("\nCURRENT DIRECTORY size:%d\n",dir.size);
	for(i = 0; i < dir.size; i++)
	{

#if W_DEGUB
	printf("d_ino:%d--",dir.direct[i].d_ino);
#endif
		printf("%-16s",dir.direct[i].d_name);
		temp_inode = iget(dir.direct[i].d_ino);
		di_mode = temp_inode->di_mode;
		for(j=0; j<9; j++)
		{
			one = di_mode%2;
			di_mode = di_mode/2;
			if(one)
				printf("x");
			else
				printf("-");
		}
		if(temp_inode->di_mode & DIMODE_FILE)
		{
			printf("%-5ld\n",temp_inode->di_size);
			printf("block chain: ");
			for(j = 0; j < temp_inode->di_size/BLOCKSIZ+1; ++j)
			{
				printf("%-5d",temp_inode->di_addr[j]);
			}
			printf("\n");
		}
		else{
			printf("<dir> inode: %-5d\n",temp_inode->i_ino);
		}
		iput(temp_inode);
	}//end_for
}

/*------------------------------------------
function:mkdir()
	创建目录,目录名:dirname
	check :7-12 13:13
------------------------------------------*/
__int8 _mkdir(char* dirname)
{
	__int8 dirid,//目录的下标,为了查找是否已经有该名字的目录或是文件
		dirpos;
	struct inode *inode;
	struct direct buf[BLOCKSIZ/(DIRSIZ+2)];
	unsigned __int16 block;

	dirid = namei(dirname);
	if(dirid != -1)
	{
		inode = iget(dirid);
		if(inode->di_mode & DIMODE_DIR)
			printf("\n%s directory already existed!! 1\n",dirname);
		else
			printf("\n%s is a file name, &can't creat a dir the same name",dirname);
		iput(inode);
		return -1;
	}

	/*没有同名,可以建立目录*/
	dirpos = iname(dirname);/*获得新目录所在dir.drect[]中的下标*/
	if(dirpos == -1)
	{
		return -1;
	}
	inode = ialloc();	/*申请一个i节点*/
	dir.direct[dirpos].d_ino = inode->i_ino;
	dir.size++;

	/* fill the new dir buf */
	strcpy(buf[0].d_name,"..");
	buf[0].d_ino = cur_path_inode->i_ino;
	strcpy(buf[1].d_name,".");
	buf[1].d_ino = inode->i_ino;

	block = balloc();/*申请一个磁盘块*/
	fseek(fd,DATASTART+block*BLOCKSIZ, SEEK_SET);
	fwrite(buf,1,BLOCKSIZ,fd);

	inode->di_size = 2*(DIRSIZ+2);
	inode->di_number = 1;
	inode->di_mode = MODE_GRUP(user[user_id].u_gid) | DIMODE_DIR;
	inode->di_uid = user[user_id].u_uid;
	inode->di_gid = user[user_id].u_gid;
	inode->di_addr[0] = block;

	cur_path_inode->i_flag = IUPDATE;

	iput(inode);

	//将新节点保存
//	fseek(fd, DINODESTART + inode->i_ino * DINODESIZ, SEEK_SET);
//	fwrite (&inode->di_number, DINODESIZ, 1 ,fd);
	
	return 1;
}

/*------------------------------------------
function:_rename()
	改变当前目录,目录名:dirname
------------------------------------------*/
__int8 _rename(char* oldname,char* newname)
{
	unsigned __int16 dirid;
	struct inode *inode;

	if(strlen(oldname)<=0){
		return -1;
	}
	/*查找是否存在目录dirname*/
	dirid = namei(oldname);
	if(dirid == -1)
	{
		printf("\n没有目录%s\n",oldname);
		return -1;
	}
	if(dirid<2)
	{
		AfxMessageBox("你不能修改此名称!");
		return -1;
	}

	/*获得i节点*/
	inode = iget( dir.direct[dirid].d_ino );
	if(!_faccess(user_id, inode,DIMODE_WRITE))
	{
		AfxMessageBox("你没有重命名此文件的权限!");
		iput(inode);
		return -1;
	}
	
	strcpy(dir.direct[dirid].d_name,newname);
	cur_path_inode->i_flag = IUPDATE;

	return 1;
}


/*------------------------------------------
function:chdir()
	改变当前目录,目录名:dirname
------------------------------------------*/
int _chdir(char *dirname)
{
	unsigned __int16 dirid;
	struct inode *inode;
	unsigned __int16 block;

	/*查找是否存在目录dirname*/
	dirid = namei(dirname);
	if(dirid == -1)
	{
		printf("\n没有目录%s\n",dirname);
		return 0;
	}

	/*获得i节点*/
	inode = iget( dir.direct[dirid].d_ino );
	if(!_faccess(user_id, inode,DIMODE_READ))
	{
		printf("\n没有访问 %s 的权限",dirname);
		iput(inode);
		return 0;
	}
	//-----------------------------
	/*判断是文件还是目录*/
	if(inode->di_mode & DIMODE_FILE)
	{
		printf("\n%s是文件,不是目录",dirname);
		iput(inode);
		return 0;
	}
	/* modify by wjy */
	/*i节点数据写入i节点区*/
	cur_path_inode->di_size = dir.size*16;
	fseek(fd,DINODESTART+cur_path_inode->i_ino*DINODESIZ,0);
	fwrite(&cur_path_inode->di_number,DINODESIZ,1,fd);

	/*将当前目录写入磁盘*/
	cur_path_inode->i_flag = 0;
	block = cur_path_inode->di_addr[0];
	fseek(fd,DATASTART+block*BLOCKSIZ,0);
	fwrite(&dir.direct[0],BLOCKSIZ,1,fd);

	
	iput(cur_path_inode);

	/*改变当前目录i节点*/
	cur_path_inode = inode;
	dir.size = (__int16)cur_path_inode->di_size/(DIRSIZ+2);

⌨️ 快捷键说明

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