📄 filsys.cpp
字号:
#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 + -