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

📄 main.h

📁 设计一个模拟的多用户多级目录的文件系统
💻 H
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h>
#define getb(type) (type*)malloc(sizeof(type)) 

int usernowpride;//全局变量,当前用户类型
char usernowname[10];//全局变量,当前用户名
int nowlevel; //全局变量,当前目录层次
char usernowpath[200] = "\\\0";

//用户类型定义
struct user
{
	char name[10];//用户名
	int pride;//用户权限,1为管理员,0为普通用户
	char pass[10];//用户密码
};

//定义空白区项
struct freeb
{
	int number;
	struct freeb * next;
};
struct freeb *fblk=NULL;//全局变量,系统空闲区链

//定义文件打开项
struct fileb
{
	int parent;//所在父节点
	char name[15];//文件名
	int pride;//读写权限,0只读,1读写
	int  rex;//读写状态,0为没有,1读2写
	struct fileb * next;
};
struct fileb *flink=NULL;//全局变量,系统打开文件链

//定义文件索引项
struct findex
{
	char name[15];
	int number;
	int parent;
	char kind;
	struct findex * next;
};
struct findex *fidx=NULL;//全局变量,文件索引链

//定义目录表项
struct dreitem
{
	char name[25];//目录或者文件名称
	int share; //共享数
	int parent;//上层目录
	int pride;//文件操作权限,0只读,1读写
	int empty;//是否是空闲块,0为空闲块,1为非空
	char kind;//类型,文件为f,目录为d
};

//新建用户
bool createuser()
{
	struct user newuser;
	char name[10];
	char pass[10];
	int pride;
	if(usernowpride!=1)
	{
		printf("当前用户没有新建用户的权限\n");
		return false;
	}
	FILE *fp;
	if((fp = fopen("user","ab+"))==NULL)
	{
		printf("用户表打开失败\n");
		return false;
	}
	else
	{
		printf("请输入用户名:");
		scanf("%s",&name);
		if(strcmp(name,"root")==0)
		{
			printf("Error:此为超级管理员\n");
			return false;
		}
		rewind(fp);
		while(!feof(fp))
		{
			fread(&newuser,sizeof(struct user),1,fp);
			if(strcmp(newuser.name,name)==0)
			{
				printf("该用户名已经存在\n");
				fclose(fp);
				return false;
			}
		}
		printf("请输入用户密码:");
		scanf("%s",&pass);
		printf("请输入用户权限(0普通用户,1管理员):");
		scanf("%d",&pride);
		strcpy(newuser.name,name);
		strcpy(newuser.pass,pass);
		newuser.pride=pride;
			
//		FILE fpuser;//为新建用户建立用户目录文件
		if(!fopen(newuser.name,"ab+"))
		{
			printf("用户创建失败\n");
			//如创建失败则把已经建立的用户目录删除
			char cmd[20] = "DEL ";
			strcat(cmd,newuser.name);
			system(cmd);
			fclose(fp);
			return false;
		}
		if(!fwrite(&newuser,sizeof(struct user),1,fp))
		{
			printf("创建失败\n");
			fclose(fp);
			return false;
		}
		else
		{
		
			printf("用户创建成功\n");
			fclose(fp);
			return true;
		}
	}
}

//用户登陆
bool login()
{
	char name[10];
	char pass[10];
	printf("\n\t\t\t○用户名:");
	scanf("%s",&name);
	printf("\t\t\t○密  码:");
	scanf("%s",&pass);
	if((strcmp("root",name)==0)&&(strcmp("123456",pass)==0))//管理员
	{
		usernowpride = 1;
		strcpy(usernowname,"root");
		return true;
	}

	FILE *fp=NULL;
	struct user actuser;
	if(!(fp=fopen("user","ab+")))
	{
		printf("Error:用户表错误\n");
		return false;
	}
	rewind(fp);
	while(!feof(fp))
	{
		fread(&actuser,sizeof(struct user),1,fp);
		if((strcmp(actuser.name,name)==0)&&(strcmp(actuser.pass,pass)==0))
		{
			usernowpride = actuser.pride;//记录当前用户的权限
			strcpy(usernowname,actuser.name);//记录当前用户的主路径
			nowlevel=-1;//记录当前目录层次
			fclose(fp);
			//设置路径
			if(strcmp(usernowpath,"\\")!=0)			//不是根目录就添加斜杠
			{
				strcat(usernowpath,"\\");
			}
			strcat(usernowpath,usernowname);
			return true;
		}
	}
	printf("Error:用户名或密码无效,请核对后再输入\n");
	fclose(fp);
	return false;
}

//初始化空闲区链表以及文件索引链
void intlist()
{
	//-----------------------------清空各链表
	fidx=NULL;
	fblk=NULL;	
	//-----------------------------
	int i=0;
	struct dreitem dnow;
	FILE *fp;
	if(!(fp=fopen(usernowname,"rb")))
	{
		printf("Error:打开用户目录失败\n");
		return ;
	}
	else		
	{
		int enp;
		int sp;
		fseek(fp,0,2);
		enp=ftell(fp);
		fseek(fp,0,0);
		sp=ftell(fp);
		if(sp==enp) return;
		
		while(!feof(fp))
		{
			fread(&dnow,sizeof(struct dreitem),1,fp);
			if(dnow.empty==0)
			{	
				//把空闲区连到空闲链表中
				struct freeb *fb =getb(struct freeb);
				fb->number=i;
				fb->next=NULL;
				struct freeb *p=fblk;
				if(p==NULL)
				{
					fblk=getb(struct freeb);
					fblk->next=fb;
				}
				else
				{
					while(p->next!=NULL)
					{
						p=p->next;
					}
					p->next=fb;
				}
			}
			else
			{
				//建立索引表
				struct findex *fi =(struct findex*)malloc(sizeof(struct findex));
				strcpy(fi->name,dnow.name);
				fi->number=i;
				fi->kind=dnow.kind;
				fi->parent=dnow.parent;
				fi->next=NULL;
				struct findex *pi=fidx;
				if(pi==NULL)
				{
					fidx=getb(struct findex);
					fidx->next=fi;
				}
				else
				{
					while(pi->next!=NULL)
					{
						pi=pi->next;
					}
					pi->next=fi;
				}
			}
			i++;
		}
		fclose(fp);
		return ;
	}
}


//新建目录
void newdrec(char ch)//输入参数为要建立的类型,f为文件,d为目录
{
	struct dreitem dnow;
	char name[15];
	char pride;//权限,0只读,1读写
	int i;//记录空闲区区号
	bool cancrd = true;//用于判断是否有重名文件

	printf("请输入名字:");
	fflush(stdin);
	scanf("%s",&name);
	//判断是否已经存在相同名字的文件或者目录
	struct findex *fi=fidx;
	while(fi)
	{
		if((strcmp(fi->name,name)==0)&&(fi->parent==nowlevel)&&(fi->kind==ch))
		{
			printf("Error:此文件或者目录已经存在\n");
			cancrd=false;
			break;
		}
		fi=fi->next;
	}
	if(!cancrd) return;

	printf("请输入权限(0只读,1读写):");
	scanf("%d",&pride);
	dnow.empty=0;
	strcpy(dnow.name,name);
	dnow.parent=nowlevel;
	dnow.pride=pride;
	dnow.share=0;
	dnow.kind=ch;
	dnow.empty=1;
	FILE *fp;
	if(!(fp=fopen(usernowname,"rb+")))
	{
		printf("错误");
		return ;
	}
	else		
	{
		if(fblk==NULL||fblk->next==NULL)		//空闲区没有就直接在文件添加
		{
			fseek(fp,0,2);
			fwrite(&dnow,sizeof(struct dreitem),1,fp);
			printf("创建成功\n");
			fclose(fp);
			return;
		}
		else
		{
			struct freeb *p=fblk->next;//拿第一个空闲区来存放文件
			if(p!=NULL)
			{
			//fblk=p->next;
				i = p->number;
				fblk->next=p->next;
			}
			free(p);
			fseek(fp,i*sizeof(struct dreitem),0);
			fwrite(&dnow,sizeof(struct dreitem),1,fp);
			printf("创建成功\n");
			fclose(fp);
			return;
		}

	}

}

//列表当前路径下的文件
void lsfile()
{
	long ep;
	FILE *fp;
	struct dreitem drenow;
	fp=fopen(usernowname,"rb");
	fseek(fp,0,2);
	ep=ftell(fp);
	fseek(fp,0,0);
	printf("Name\tPride\tKind\tShare\tParent\n");
	while(ep!=ftell(fp))
	{
		fread(&drenow,sizeof(struct dreitem),1,fp);
		if(drenow.parent==nowlevel&&drenow.empty!=0)
		{			
			printf("%s\t%d\t%c\t%d\t%d\n",drenow.name,drenow.pride,drenow.kind,drenow.share,drenow.parent);
		}
	}
	printf("文件列表结束\n");
	fclose(fp);

}

//目录后退
bool back()
{
	if(nowlevel==-1)
	{
		printf("Error:当前已为用户根目录,无法再回退\n");
		return false;
	}
	char name[15];
	int i;
	i=nowlevel;
	struct dreitem drecnow;
	FILE *fp;
	fp=fopen(usernowname,"rb");
	fseek(fp,i*sizeof(struct dreitem),0);
	fread(&drecnow,sizeof(struct dreitem),1,fp);
	fclose(fp);
	strcpy(name,drecnow.name);	
	nowlevel=drecnow.parent;
	char cc;		//检测'\0'位置
	int ccidx=0;		//记录最好一个'\'位置
	int j=0;
	cc=usernowpath[j];
	while(cc!='\0')
	{
		j++;
		cc=usernowpath[j];
		if(cc=='\\')
		{
			ccidx=j;
		}
	}
//	j=ccidx;
//	cc=usernowpath[j];
	if(ccidx!=0)
	{
		usernowpath[ccidx]='\0';
	}
	return true;
//	printf("%s\n",usernowpath);	
}

//进入路径
bool path(char chpath[15])
{	
	struct dreitem drenow;
	char mypath[15];
	int i=0;
//	printf("要进去的路径:");
//  scanf("%s",&mypath);
	strcpy(mypath,chpath);
	if(strcmp(mypath,"..")==0)
	{
		if(back())
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	FILE *fp;
	fp=fopen(usernowname,"rb");
	while(!feof(fp))
	{
		fread(&drenow,sizeof(struct dreitem),1,fp);

⌨️ 快捷键说明

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