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

📄 filsys.cpp

📁 大型实验:Unix文件管系统模拟。用内存中的一段区域模拟硬盘空间
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		if (pinode->i_forw == NULL){/*该节点为最后一个节点*/
			if(hinode[pinode->i_ino%NHINO].i_forw == pinode)
			{	
				/*该节点也是为第一个节点*/
				hinode[pinode->i_ino%NHINO].i_forw = NULL;
			}
			else{
				pinode->i_back->i_forw = NULL;
			}		
		}
		else{
			if(hinode[pinode->i_ino%NHINO].i_forw == pinode)
			{
				/*该节点是为第一个节点*/
				hinode[pinode->i_ino%NHINO].i_forw = pinode->i_forw;
				pinode->i_back->i_forw = pinode->i_forw;
			}
			else{
				pinode->i_forw->i_back = pinode->i_back;
				pinode->i_back->i_forw = pinode->i_forw;				
			}
		}
		free(pinode);
	}
}


/*--------------------------------
install()
	启动系统
--------------------------------*/
void install()
{
	__int16 i,j;
	/*0.open the file column */
	fd = fopen(fsystemname, "r+b");
	if(fd==NULL)
	{
		printf("\nfilesys can not be loaded\n");
		exit(0);
	}

	/*	1. read the filsys from the superblock */
	fseek(fd, BLOCKSIZ, 0);
	fread(&filsys, sizeof(struct super_block), 1, fd);

	/*	2. initialize the mode hash chain */
	for(i=0; i<NHINO; i++)
	{
		hinode[i].i_forw = NULL;
	}
		
	/*	3. initjalize the sys-ofile */
	for(i=0; i<SYSOPENFILE; i++)
	{
		sys_ofile[i].f_count = 0;
		sys_ofile[i].f_off = 0;
		sys_ofile[i].f_inode = NULL;
	}
	
	/*4. initialize the user */
	for(i=0; i<USERNUM; i++)
	{
		user[i].u_uid = 0;
		user[i].u_gid = 10;
		for(j=0; j<NOFILE; j++)
		{
			user[i].u_ofile[j] = SYSOPENFILE+ 1;
		}
	}

	/* 5. read the main directory to initialize the dir */
	cur_path_inode = iget(1);
	dir.size =(__int16)(cur_path_inode->di_size/(DIRSIZ+2));

	for(i=0; i<DIRNUM; i++)
	{
		strcpy(dir.direct[i].d_name,"  ");
		dir.direct[i].d_ino = -1;
	}

    /*将根目录设置为当前目录*/
	fseek(fd, DATASTART,SEEK_SET);
	fread(&dir.direct[0], BLOCKSIZ, 1, fd);

	/* 6. read the password */
	fseek(fd,DATASTART+2*BLOCKSIZ, SEEK_SET);
	fread(pwd, 1, BLOCKSIZ,fd);
}



/*-----------------------------------------------
__int8 login()
	用户登录文件系统
	入口:用户名 和密码
	出口:返回在当前用户表中的下标
-----------------------------------------------*/
__int8 login(char *username, char	*passwd)
{
	__int8  u_id = -1;
	__int8 i,j;

	/*用户名和密码不能为空*/
	if(strlen(username)==0 || strlen(passwd)==0)
		return -1;

	for(i=0; i<PWDNUM; i++)
	{
		if((strcmp(username,pwd[i].username)==0) &&
			(strcmp(passwd,pwd[i].password)==0))
		{
			for(j = 0; j < USERNUM; j++){
				if(user[j].u_uid <=0 || (user[j].u_uid >= USERNUM -1) )
					break ;
			}
			if(j == USERNUM)
			{
				printf("\nToo much user in the System, waited to login\n");
				return -1;
			}
			else
			{
				u_id = j;
				user[j].u_uid = pwd[i].p_uid;
				user[i].u_gid = pwd[i].p_gid;
			}
			break;
		}
	}

	if(i==PWDNUM)
	{
         printf("\n incorrect password\n");
	     return -1;
	}
	else
		return u_id;
}


__int8 logout(__int8 uid)	
{
	__int16 i,j,sys_no;
	struct inode *inode;
	for(i=0; i<USERNUM; i++){
		if(uid == user[i].u_uid)
			break;
	}
	if (i==USERNUM)
	{
		printf("\nno such a file\n");
		return -1;
	}
	for(j=0;j<NOFILE; j++)
	{
		if (user[i].u_ofile[j] != SYSOPENFILE+1)
		{
			/* iput the mode free the sys_ofile and clear the user-ofile */
			sys_no = user[i].u_ofile[j];
			inode = sys_ofile[sys_no].f_inode;
			iput(inode);
			--sys_ofile[sys_no].f_count;
			user[i].u_ofile[j] = SYSOPENFILE+ 1;
		}
	}
	return 1;
}


/*---------------------------------------------
namei()
	查找是否有与name同名的目录或是文件,
	check :7-12 13:21
---------------------------------------------*/
__int8 namei(char *name) /* namei */
{
	__int8 i, notfound = 1;
	for (i=0; i<dir.size; i++)
	{
		if ((strcmp(dir.direct[i].d_name,name)==0) &&
			(dir.direct[1].d_ino >=0) && 
			(dir.direct[1].d_ino<BLOCKSIZ))
				return i;   /* find */
	}

	/* notfind */
	return -1;
}

/*---------------------------------------------
iname()
	建立目录,返回新目录的下标
	check :7-12 13:21
---------------------------------------------*/
__int8 iname(char* name)	
{
	__int8 i, notfound = 1;

	//modify by wjy on 7-16 19:40
	if(dir.size<DIRNUM)
	{
		strcpy(dir.direct[dir.size].d_name,name);
		return (__int8)dir.size;
	}
	return -1;


	for (i=0; i < DIRNUM; i++)
	{
		if ((dir.direct[i].d_ino < 0) || (dir.direct[i].d_ino >= BLOCKSIZ))
		{
			notfound = 0;
			break;
		}
	}

	if (notfound)
	{
		printf("\nThe current directory is full! !\n");
		return -1;
	}
	else
	{
		strcpy(dir.direct[i].d_name,name);
		return i;
	}
}



/*----------------------------------------
	_fopen()	
	打开文件
	入口:文件名,打开模式:读、写
	出口:用户打开文件表的下标,执行系统打开文件表
----------------------------------------*/
__int8 _fopen(char * filename,unsigned __int8 openmode)
{
        unsigned __int16 dirid;
        struct inode * inode;
        __int16 i;
		__int8  j;

        dirid = namei(filename);
        if(dirid == -1)/* no such file*/
        {
                printf("\nfile does not existed!!!\n");
                return -1;
        }

        inode = iget(dir.direct[dirid].d_ino);
        if(!_faccess(user_id,inode,DIMODE_READ))/* access denied*/
        {
                printf("\nfile open has not access!!!");
                iput(inode);
                return -1;
        }

		/*确定是打开文件*/
		if(inode->di_mode & DIMODE_DIR)
		{
			printf("你想打开的是目录。命令错误!");
			iput(inode);
			return -1;
		}

        /* alloc the sys_ofile item */
        for(i = 0; i<SYSOPENFILE; i++){
                if(sys_ofile[i].f_count<=0)
					break;
		}
        if(i==SYSOPENFILE)
        {
                printf("\nsystem open file too much\n");
                iput(inode);
                return -1;
        }

		/* alloc the user open file item*/
        for (j=0; j<NOFILE; j++){
                if((user[user_id].u_ofile[j]<0) ||
					(user[user_id].u_ofile[j]>=NOFILE-1))
                        break;
		}
        if(j==NOFILE)
        {
                printf("\nuser open file too much!!!\n");
                sys_ofile[i].f_count = 0;
                iput(inode);
                return -1;
        }
		user[user_id].u_ofile[j] = (__int8)i;

        sys_ofile[i].f_inode = inode;
        sys_ofile[i].f_mode = openmode;
        sys_ofile[i].f_count = 1;
		sys_ofile[i].f_off = 0;
        if(openmode & FAPPEND)//追加
                sys_ofile[i].f_off = inode->di_size;
        
        

        /* if APPEND,free the block of the file before */
        if(openmode & FWRITE)//覆盖
        {
			i = (__int16)inode->di_size/BLOCKSIZ;
            for(; i >=0; --i)
				bfree(inode->di_addr[i]);
			inode->di_size=0;
        }

        return j;
}



/*----------------------------------------
	_fclose()
	关闭系统打开文件表中的文件
	入口为:系统文件表中的下标
----------------------------------------*/
void _fclose(unsigned __int8 fid)
{
        struct inode *inode;
		inode = sys_ofile[ user[user_id].u_ofile[fid] ].f_inode;
		user[user_id].u_ofile[fid] = SYSOPENFILE + 1;
        iput(inode);
        sys_ofile[user[user_id].u_ofile[fid]].f_count --;
}



/*------------------------------------------------
_fread()
	读文件
	入口:u_ofid为用户打开表中文件数组的下标
		  buf为读出的内容存放的缓冲区
		  size为读数据的大小
	出口:实际读文件的大小
------------------------------------------------*/
__int32 _fread(__int16 u_ofid,char* buf,unsigned __int32 size)
{
        __int32 off;
        __int16 block,block_off,i,j;
        struct inode *inode;
        char *temp_buf;

        inode = sys_ofile[user[user_id].u_ofile[u_ofid]].f_inode;
        if(!(sys_ofile[user[user_id].u_ofile[u_ofid]].f_mode & FREAD))
        {
                printf("\nthe file is not opened for read\n");
                return 0;
        }

        temp_buf = buf;

        off = sys_ofile[user[user_id].u_ofile[u_ofid]].f_off;
        if((off+size) > inode->di_size)
                size = inode->di_size-off;

        block_off = off%BLOCKSIZ;
        block = off/BLOCKSIZ;

        if(block_off+size<BLOCKSIZ)
        {
            fseek(fd, DATASTART+inode->di_addr[block]*BLOCKSIZ+block_off, SEEK_SET);
            fread(buf,1,size,fd);
            return size;
        }

        fseek(fd,DATASTART+inode->di_addr[block]*BLOCKSIZ+block_off,SEEK_SET);
        fread(temp_buf,1,BLOCKSIZ-block_off,fd);

        temp_buf += BLOCKSIZ-block_off;
        j = block+1;
        for(i=0; i< (__int16)(size-(BLOCKSIZ-block_off))/BLOCKSIZ; ++i)
        {
                fseek(fd,DATASTART+inode->di_addr[j+i]*BLOCKSIZ,SEEK_SET);
                fread(temp_buf,1,BLOCKSIZ,fd);
                temp_buf += BLOCKSIZ;
        }

		
        block_off = (__int16)((size-(BLOCKSIZ-block_off))%BLOCKSIZ);
		if(block_off>0)
		{
			block = inode->di_addr[off+size/BLOCKSIZ+1];
			fseek(fd,DATASTART+block*BLOCKSIZ,SEEK_SET);
			fread(temp_buf,1,block_off,fd);
		}
        

        sys_ofile[user[user_id].u_ofile[u_ofid]].f_off += size;

        return size;
}


/*-------------------------------------------
function write()
	入口:u_id 所属用户的用户id
		  u_ofid-文件在用户表用u_ofile中的下标
		  buf-文件内容
		  size-文件大小
        写文件
		返回是否写入成功
-------------------------------------------*/
__int32 _fwrite(__int16 u_ofid,char* buf,unsigned __int32 size)
{
        unsigned long off,block_off;
		unsigned __int16 block;
        __int16 i;
			
        struct inode *inode;
        char *temp_buf;

		/*先判断是否有这么多空间来存储文件*/
		if(filsys.s_nfree*512 < size)
		{
			printf("没有多余空间来存储文件");
			return 0;
		}

        if(!(sys_ofile[user[user_id].u_ofile[u_ofid]].f_mode & FWRITE))
        {
                printf("\nthe file is not opened for write\n");
                return 0;
        }

		/*获得该文件的i节点*/
        inode = sys_ofile[user[user_id].u_ofile[u_ofid]].f_inode;
		inode->di_number = 1;
		inode->di_size += size;
		inode->i_flag = IUPDATE;

        temp_buf = buf;

        off = sys_ofile[user[user_id].u_ofile[u_ofid]].f_off;
        block_off = off%BLOCKSIZ;
        block = (unsigned __int16)(off/BLOCKSIZ);

		if(off==0)//是新写入文件内容
		{
			inode->di_addr[0] = balloc();
		}

		if(block_off+size<BLOCKSIZ)
		{
            fseek(fd,DATASTART+inode->di_addr[block]*BLOCKSIZ+block_off,SEEK_SET);
            fwrite(buf,1,size,fd);
			iput(inode);
            return size;
		}

		fseek(fd,DATASTART+inode->di_addr[block]*BLOCKSIZ+block_off,SEEK_SET);
		fwrite(temp_buf,1,BLOCKSIZ-block_off,fd);

		temp_buf += BLOCKSIZ-block_off;
        for(i=0; i< (size-(BLOCKSIZ-block_off))/BLOCKSIZ; ++i)
        {
                inode->di_addr[block+1+i] = balloc();
                fseek(fd,DATASTART+inode->di_addr[block+1+i]*BLOCKSIZ,SEEK_SET);
                fwrite(temp_buf,1,BLOCKSIZ,fd);
                temp_buf += BLOCKSIZ;
        }

        block_off = (size-(BLOCKSIZ-block_off))%BLOCKSIZ;
		if(block_off>0){
			block = balloc();
			inode->di_addr[(off+size)/BLOCKSIZ] = block;
			fseek(fd,DATASTART+block*BLOCKSIZ,SEEK_SET);
			fwrite(temp_buf,1,block_off,fd);
		}

        sys_ofile[user[user_id].u_ofile[u_ofid]].f_off += size;

		//add by wjy on 7-16 15:16
		inode->i_flag = IUPDATE;
		inode->i_count++;
		iput(inode);

        return size;
}

⌨️ 快捷键说明

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