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

📄 test2.cpp

📁 在Linux Red Hat下用C++设计并实现一个多用户多级目录结构的文件系统。
💻 CPP
📖 第 1 页 / 共 4 页
字号:

#define IFMT 0070000	//文件类型屏蔽字
#define IFDIR 0010000	//子目录文件
#define IFREG 0020000	//普通文件
#define IREAD 0400		//文件主读权限
#define IWRITE 0200		//文件主写权限
#define IEXEC 0100		//文件主执行权限
#define GREAD 040		//同组用户读权限
#define GWRITE 020		//同组用户写权限
#define GEXEC 010		//同组用户执行权限
#define OREAD 04		//其他用户读权限
#define OWRITE 02		//其他用户写权限
#define OEXEC 01		//其他用户执行权限
#define MODE IFREG|IREAD|IWRITE|IEXEC|GREAD	//组合权限 rwx-r

#define FREAD 01   //文件读打开标志
#define FWRITE 02  //文件写打开标志


openfile::openfile()
{
//初始化ofile系统
	for(int o=0;o<fileno;o++)
	{
		ofilei[o]=NULL;
	}
}
openfile::~openfile()
{
//将未处理的ofile存储
	for(int o=0;o<fileno;o++)
	{
		if(ofilei[o]!=NULL)
		{
			ifcbi.iput(ofilei[o]->o_fcb);
			delete ofilei[o];
			ofilei[o]=NULL;
		}
	}
} 
int openfile::readf(fcb *fp,int offset,int count,char*base)
{
//引用fcb层的readi
	return ifcbi.readi(fp,offset,count,base);
}
int openfile::writef(fcb *fp,int offset,int count,char*base)
{
//引用fcb层的writei
	return ifcbi.writei(fp,offset,count,base);
}
ofile *openfile::openf(fcb *fp,char*filename,int f_mode,int o_mode,int o_mode2)
{
//在ofile系统中寻找
	for(int i=0;i<fileno;i++)
	{
		if(ofilei[i]!=NULL)
		{
			if(strcmp(ofilei[i]->o_fcb->f_name,filename)==0)
			{
				if(fp==NULL&&ofilei[i]->o_fcb->f_blkno==0)
				{                                         
					ofilei[i]->o_count++;
					return ofilei[i];
				}
				int u;
				for(int kk=0;kk<263;kk++)
				{
					u=ifcbi.getblock(fp,kk);
					if(u==0)
						break;
					else
					{
						if(u==ofilei[i]->o_fcb->f_blkno)
						{	if((ofilei[i]->o_fcb->f_mode==IFDIR&&f_mode==IFDIR)||(ofilei[i]->o_fcb->f_mode>=IFREG&&f_mode>=IFREG))
							{
								ofilei[i]->o_count++;
								return ofilei[i];
							}
						}
					}
				}
			}
		}
	}
	if(o_mode2==1)
		return NULL;
//调用fcb层的namei寻找
	fcb *ofcb=ifcbi.namei(fp,filename,f_mode);
//无则创建新的
	if(ofcb==NULL&&o_mode==0)
	{
		ofcb=ifcbi.icreate(fp,filename);
		ofcb->f_mode=f_mode;
	}
	else
	{
		if(ofcb==NULL&&o_mode==1)
			return NULL;
	}
	int o=0;
	for(;o<fileno;o++)
	{
		if(ofilei[o]==NULL)
			break;
	}
	if(o>=fileno)
	{
		cout<<"OPEN FILE ERROR\n";
		return NULL;
	}
	ofilei[o]=new struct ofile;
	ofilei[o]->o_fcb=ofcb;
	ofilei[o]->o_count=1;
	ofilei[o]->o_offset=0;
	return ofilei[o];
}
int openfile::closef(ofile *fileo)
{
//关闭文件,如果ofile没有在被使用,删除ofile
	fileo->o_count--;
	if(fileo->o_count!=0)
	{
		return OK;
	}
	else
	{
		ifcbi.iput(fileo->o_fcb);
		for(int r=0;r<fileno;r++)
		{
			if(ofilei[r]==fileo)
			{
				delete fileo;
				ofilei[r]=NULL;
				return OK;
			}
		}
	}
}
int openfile::deletef(ofile *pfileo,ofile *fileo)
{
//在指定的ofile下删除ofile
	if(fileo->o_count>1)
	{
		cout<<"CANNOT DELETE! THE FILE "<<fileo->o_fcb->f_name<<" IS BEING USED\n";
		return -1;
	}
	else
	{
		for(int ii=0;ii<fileno;ii++)
		{
			if(fileo==ofilei[ii])
			{
//fileo代表的是文件或空文件夹
				if(fileo->o_fcb->f_mode>=IFREG||fileo->o_fcb->f_fsize==0)
				{
					ifcbi.idelete(pfileo->o_fcb,fileo->o_fcb);
					ofilei[ii]=NULL;
					delete fileo;
					return OK;
				}
				else
				{
//fileo代表的是有文件的文件夹
					int revalue;
					char*base=new char[fileo->o_fcb->f_fsize+1];
					int d_mode;
					char d_name[8];
					ifcbi.readi(fileo->o_fcb,0,fileo->o_fcb->f_fsize,base);
					for(int y=0;y<=(fileo->o_fcb->f_fsize-1)/dsize;y++)
					{
						for(int d=0;d<8;d++)
						{
							d_name[d]=base[y*dsize+8+d];
						}
						d_mode=int((unsigned char)base[y*dsize])*256+int((unsigned char)base[y*dsize+1]);
						ofile *curfile=openf(fileo->o_fcb,d_name,d_mode,1);
						revalue=deletef(fileo,curfile);
						if(revalue==-1)
						{
							closef(curfile);
							return -1;
						}
					}
					revalue=deletef(pfileo,fileo);
					if(revalue==-1)
						return -1;
					delete[]base;
					return OK; 
				}
			}
		}
	}
	return -1;
}


#define fileno 16
struct ofile
{
	char o_flag;		//标志字
	char o_count;		//访问计数
	struct fcb *o_fcb;  //打开对应的文件fcb结构指针
	int o_offset;		//文件当前读写指针
};
class openfile
{
public:
	openfile();
	int readf(fcb *fp,int offset,int count,char *base);		//引用FCB层的readi
	int writef(fcb *fp,int offset,int count,char *base);	//引用FCB层的writei
	ofile *openf(fcb *fp,char*filename,int f_mode=IFREG,int o_mode=0,int o_mode2=0);	//打开文件
	int closef(ofile *fileo);								//关闭文件
	int deletef(ofile *pfileo,ofile *fileo);				//删除文件
	~openfile();
private:
	struct ofile *ofilei[fileno];							//打开文件系统
	class ifcb ifcbi;										//嵌套FCB层
};

#define userno 5
#define UCHG 01
#define UINC 02
struct user
{
	char u_name[12];		//用户名
	char u_password[12];	//用户密码
	int u_number;			//用户资料在uwords中的偏移序号
	char u_flag;			//用户密码是否改变的标志
	char u_uid;				//用户id
	char u_gid;				//同组用户id
	int  u_cdir;			//工作目录指针,与u_ofile[]合用,指示当前工作文件目录
	struct ofile *u_ofile[16];	//工作文件目录数组
	char u_error;			//用户错误代码
	char*u_base;			//读/写文件时信息存储区始址
	int u_count;			//读/写文件的信息字节数
	int u_offset;			//读/写文件的相对位移量
	char u_obuf[8];			//文件路径名分量暂存区(查找文件时用)
};
class use
{
public:
	use();
	void entrance();				//命令接受及解释函数
	int login(char*u_name,char*u_password);	//登陆函数
	int logout();					//注销函数
	int createuser(char*name,char*password);//创建用户
	int deleteuser(char*u_name);	//删除用户
	int changepw(char*password);	//更改密码
	int create(char*name);			//创建文件
	int del(char*name);				//删除文件
	int open(char*name);			//打开文件
	int close(char*name);			//关闭文件
	int read(char*name);			//读文件
	int write(char*name);			//写文件
	int dir();						//列目录中的文件
	int makedir(char*name);			//创建目录
	int removedir(char*name);		//删除目录
	int cdir(char*name);			//进入目录
	~use();
private:
	class openfile iopenfile;		//嵌套openfile层
	struct user *iuser[userno];		//用户系统
	int cuser;						//当前用户指针
	int usernum;					//用户数目
	ofile *rdir;					//跟目录
};


//#include<errcode.h>

use::use()
{
   //初始化用户系统,当前用户指针,用户数目,根目录
   for(int yy=0;yy<userno;yy++)
   {
      iuser[yy]=NULL;
   }
   cuser=-1;
   usernum=0;
   rdir=iopenfile.openf(NULL,"#rdir",IFDIR);
}
use::~use()
{
   //关闭根目录
   iopenfile.closef(rdir);
}
int use::login(char*u_name,char*u_password)
{
   //在用户系统中寻找
   for(int xx=0;xx<userno;xx++)
   {
      if(iuser[xx]!=NULL)
      {
         if(strcmp(iuser[xx]->u_name,u_name)==0)
         {
            if(strcmp(iuser[xx]->u_password,u_password)==0)
            {
               cuser=xx;
               return OK;
            }else
            {
               cout<<"PASSWORD INCORRECT\n";
               return ERROR;
            }
         }
      }
   }
   //在uwords中寻找
   ofile *curfile;
   curfile=iopenfile.openf(rdir->o_fcb,"uwords",IFREG|IREAD|GREAD|OREAD);
   if(curfile->o_fcb->f_add[0]==0)
   {
     // cout<<"empty\n";
      char name[]="root\0       1\0          A0"; 
      curfile->o_fcb->f_uid='a';
      curfile->o_fcb->f_gid='0'; 
      iopenfile.writef(curfile->o_fcb,0,26,name);
   }
   char*base=new char[curfile->o_fcb->f_fsize+1];
   //char base[curfile->o_fcb->f_fsize+1];
   iopenfile.readf(curfile->o_fcb,0,curfile->o_fcb->f_fsize,base); 
   char name[12];
   char pw[12];
   char uid;
   char gid;
   for(int c=0;c<=(curfile->o_fcb->f_fsize-1)/26;c++)
   { 
      for(int i=0;i<12;i++)
      {
         name[i]=base[26*c+i];
         pw[i]=base[26*c+i+12];
      } 
      uid=base[26*c+24];
      gid=base[26*c+25]; 
      if(strcmp(name,u_name)==0)
      { 
         if(strcmp(pw,u_password)==0)
         { 
            for(int u=0;u<userno;u++)
            {
               if(iuser[u]==NULL)
               { 
                  iuser[u]=new struct user;
                  strcpy(iuser[u]->u_name,name);
                  strcpy(iuser[u]->u_password,pw);
                  iuser[u]->u_flag=UINC;
                  iuser[u]->u_number=c;
                  iuser[u]->u_uid=uid;
                  iuser[u]->u_gid=gid;
                  iuser[u]->u_cdir=0;
                  for(int kk=0;kk<16;kk++)
                  {
                     iuser[u]->u_ofile[kk]=NULL;
                  } 
                  iuser[u]->u_ofile[0]=iopenfile.openf(NULL,"#rdir",IFDIR); 
                  cuser=u;
                  usernum++; 
                  iopenfile.closef(curfile);
                  delete[]base; 
                  return OK;
               }
            }
            iopenfile.closef(curfile);
            cout<<"USER FULL\n";
            delete[]base;
            return ERROR;
        }else
        {
            iopenfile.closef(curfile);
            cout<<"password incorrect\n";
            delete[]base;
            return ERROR;
        } 
      }
   }
   iopenfile.closef(curfile);
   cout<<"usename incorrect\n";
   delete[]base;
   return ERROR; 
}
int use::logout()
{
   //关闭用户工作文件目录数组
   for(int l=iuser[cuser]->u_cdir;l>=0;l--)
   {
      iopenfile.closef(iuser[cuser]->u_ofile[l]);
   }
   if(iuser[cuser]->u_flag==UCHG)
   {
	  //存储用户信息
      ofile *curfile;
      curfile=iopenfile.openf(rdir->o_fcb,"uwords",MODE);
      char*base=new char[curfile->o_fcb->f_fsize-iuser[cuser]->u_number*26+1];
      //char base[curfile->o_fcb->f_fsize-iuser[cuser]->u_number*26+1]; iopenfile.readf(curfile->o_fcb,iuser[cuser]->u_number*26,curfile->o_fcb->f_fsize-iuser[cuser]->u_number*26,base);
     // base[curfile->o_fcb->f_fsize-iuser[cuser]->u_number*26+1]='\0'; 
      char name[12];
      char pw[12];
      for(int i=0;i<12;i++)
      {
         name[i]=base[i];
         pw[i]=base[i+12];
      }
      if(strcmp(name,iuser[cuser]->u_name)==0)
      {
         for(int dd=0;dd<12;dd++)
         {
             base[dd+12]=iuser[cuser]->u_password[dd];
         }iopenfile.writef(curfile->o_fcb,iuser[cuser]->u_number*26,curfile->o_fcb->f_fsize-iuser[cuser]->u_number*26,base); 
         iopenfile.closef(curfile);
      }else
      {
        delete[]base;
        return ERROR;
      }
      delete[]base;
   }
   //删除用户在用户系统中的用户结构
   delete iuser[cuser];
   iuser[cuser]=NULL;
   usernum--;
   for(int ll=0;ll<userno;ll++)
   {
      if(iuser[ll]!=NULL)
      {
         cuser=ll;
         return OK;
      }
   }
   cuser=-1;
   return OK;
} 
int use::createuser(char*u_name,char*password)
{
   //创建用户,并将新用户信息存储在文件uwords中
   if(strlen(u_name)>=12||strlen(password)>=12)
   {
     cout<<"the length of the username and password must be less than 12bytes\n";
     return OK;
   } 
   if(strcmp(iuser[cuser]->u_name,"root")!=0)
   {
     cout<<"ONLY THE ROOT CAN CREAT USER\n";
     return OK;
   }else
   {
      ofile *curfile;
      curfile=iopenfile.openf(rdir->o_fcb,"uwords",MODE);
      char*base=new char[curfile->o_fcb->f_fsize+1]; 
      iopenfile.readf(curfile->o_fcb,0,curfile->o_fcb->f_fsize,base); 
      char name[12];
      for(int c=0;c<=(curfile->o_fcb->f_fsize-1)/26;c++)
      {
         for(int i=0;i<12;i++)
         {
            name[i]=base[26*c+i];
         }
         if(strcmp(name,u_name)==0)
         {
           cout<<"THERE HAS BEEN A USER "<<u_name<<endl;
           delete[]base;
           iopenfile.closef(curfile);
           return OK;
         }
      }
      delete[]base;
      char buf[26+1];
      char uid=(curfile->o_fcb->f_fsize-1)/26+1+'A';
      for(int rr=0;rr<12;rr++)
      {
         buf[rr]=u_name[rr];
         buf[rr+12]=password[rr];
      }
      buf[24]=uid;
      buf[25]='0';
      buf[26]='\0';
      iopenfile.writef(curfile->o_fcb,curfile->o_fcb->f_fsize,26,buf);
      iopenfile.closef(curfile);
      return OK;
  }
}
int use::deleteuser(char*u_name)
{

⌨️ 快捷键说明

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