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

📄 filesys.c

📁 这是一本操作系统辅导教材的辅助资料
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>


#define FILENAME_LEN 21
#define INPUT_LEN 81
#define COMMAND_LEN 11

//结点结构
struct FileNode 
{
	char filename[FILENAME_LEN];//文件名/目录名
	int isdir;//目录文件识别标志
	int i_nlink;//文件的链接数
	int adr;//文件的地址
	struct FileNode *parent, *child;//指向父亲的指针和指向左孩子的指针
	struct FileNode *sibling_prev, *sibling_next;//指向前一个兄弟的指针和指向
//后一个兄弟的指针.
};


void Init();//初始化文件树
int ParseCommand();//接受输入的命令并把其分解成操作名和路径文件名
void ExecuteCommand();//执行命令

int cdComd();//处理cd命令
int editComd();//处理edit命令
int delComd();//处理del命令
int rdComd();//处理rd命令
int dirComd();//处理dir命令
int mdComd();//处理md命令

int FindPath(char *ph);//寻找参数ph所指向的路径
//从参数Para2中找到要建立或删除的文件、目录名,并把指针指向其父亲结点
int FindFilename(char Para2[]);


struct FileNode* CreateFileNode(char filename[],int isdir,int i_nlink);//创建结点
int GetInput(char* buffer,unsigned int buffer_len);//获取输入
int CheckCommand();//命令检查
int GetDir(int begin,char* path,char* curDir);//获取路径
void Trim(char* str);

struct FileNode * cp, *tp, *root,*upper;
char path[INPUT_LEN-COMMAND_LEN];//记录当前走过的路径
char curpath[INPUT_LEN-COMMAND_LEN],Para1[COMMAND_LEN],
	    Para2[INPUT_LEN-COMMAND_LEN],tmppath[INPUT_LEN-COMMAND_LEN];
char filename[FILENAME_LEN],dirname[FILENAME_LEN],tmp;
int i,j;

//主函数
int main()
{
	Init();//初始化文件树
	while(1)
	{
		if(ParseCommand())//分解命令
			ExecuteCommand();//执行命令
	}
}

//执行命令子函数
void ExecuteCommand()
{
	int sign;
            //根据参数Para1调用相应的功能处理模块
	if(strcmp(Para1,"cd")==0) 
		sign=cdComd();            //cd命令
	else if(strcmp(Para1,"edit")==0) 
		sign=editComd();         //edit命令
	else if(strcmp(Para1,"del")==0) 
		sign=delComd();          //del命令
	else if(strcmp(Para1,"dir")==0) 
		sign=dirComd();          //dir命令
	else if(strcmp(Para1,"md")==0) 
		sign=mdComd();         //md命令
	else if(strcmp(Para1,"rd")==0) 
		sign=rdComd();           //rd命令
	else if(strcmp(Para1,"exit")==0)
		exit(0);                         //exit命令
	else
		printf("命令错误,请重试\n");  //命令输入不正确,报错
}

//创建结点
struct FileNode* CreateFileNode(char filename[],int isdir,int i_nlink)
{
	//申请结点空间
    struct FileNode* node=(struct FileNode*)malloc(sizeof(struct FileNode));
	//相应内容赋初值
    strcpy(node->filename,filename);
	node->isdir=isdir;
	node->i_nlink=i_nlink;
	node->parent=NULL;
	node->child=NULL;
	node->sibling_prev=NULL;
	node->sibling_next=NULL;
    return node;
}

//初始化文件树
void Init()
{
	struct FileNode *binNode,*usrNode,
			*unixNode,*etcNode,*libNode,*userNode,
			*binNode2,*liuNode,*sunNode,*ftiNode;
	strcpy(path,"/"); //根目录写入当前路径
            //创建文件树的结点
	binNode=CreateFileNode("bin",1,0);
	usrNode=CreateFileNode("usr",1,0);
	unixNode=CreateFileNode("unix",0,0);
	etcNode=CreateFileNode("etc",1,0);
	libNode=CreateFileNode("lib",1,0);
	userNode=CreateFileNode("user",1,0);
	binNode2=CreateFileNode("bin",1,0);
	liuNode=CreateFileNode("liu",1,0);
	sunNode=CreateFileNode("sun",1,0);
	ftiNode=CreateFileNode("fti",1,0);
	cp=tp=root=CreateFileNode("/",1,0);
            //结点相应内容赋值
	root->parent=NULL;
	root->child=binNode;
	root->sibling_prev=root->sibling_next=NULL;
 
	binNode->parent=root;
	binNode->child=NULL;
	binNode->sibling_prev=NULL;
	binNode->sibling_next=usrNode;

	usrNode->parent=NULL;
	usrNode->child=libNode;
	usrNode->sibling_prev=binNode;
	usrNode->sibling_next=unixNode;

	unixNode->parent=NULL;
	unixNode->child=NULL;
	unixNode->sibling_prev=usrNode;
	unixNode->sibling_next=etcNode;

	etcNode->parent=NULL;
	etcNode->child=NULL;
	etcNode->sibling_prev=unixNode;
	etcNode->sibling_next=NULL;

	libNode->parent=usrNode;
	libNode->child=liuNode;
	libNode->sibling_prev=NULL;
	libNode->sibling_next=userNode;

	userNode->parent=NULL;
	userNode->child=NULL;
	userNode->sibling_prev=libNode;
	userNode->sibling_next=binNode2;

	binNode2->parent=NULL;
	binNode2->child=NULL;
	binNode2->sibling_prev=userNode;
	binNode2->sibling_next=NULL;

	liuNode->parent=libNode;
	liuNode->child=NULL;
	liuNode->sibling_prev=NULL;
	liuNode->sibling_next=sunNode;

	sunNode->parent=NULL;
	sunNode->child=NULL;
	sunNode->sibling_prev=liuNode;
	sunNode->sibling_next=ftiNode;

	ftiNode->parent=NULL;
	ftiNode->child=NULL;
	ftiNode->sibling_prev=sunNode;
	ftiNode->sibling_next=NULL;

}

//获取文件或目录名,并把指针指向其父亲结点
int FindFilename(char Para2[])
{
	i=strlen(Para2)-1;
	j=0;
	
	while(Para2[i]!='/'&& i>=0)
	{	
		filename[j]=Para2[i];
		i--; j++;
	}
	filename[j]='\0';//获得逆序的文件或目录名,存入filename中
	if(i<0) Para2[i+1]='\0';
	else Para2[i]='\0';
	j--;
            //filename逆转,获得正确的文件或目录名
	for(i=0;i<strlen(filename)/2;i++,j--)
	{
		tmp=filename[i];
		filename[i]=filename[j];
		filename[j]=tmp;
	}

	//查找路径
	if(strlen(Para2)>0)
	{
		int sign=FindPath(Para2);
		if(sign==0) return 0;
	}
	return 1;
}

//缓冲区安全输入子函数
//如果输入超过buffer_len,则截取前buffer_len-1长度的输入,
//buffer_len处字符用'/0'代替
int GetInput(char* buffer,unsigned int buffer_len)
{
	int count=0;
	while(count<buffer_len)
	{
		if((buffer[count]=getchar())==10)
		{
			buffer[count]='\0';
			return count;
		}
		count++;
	}
	while(getchar()!=10);
	buffer[buffer_len-1]='\0';
	return -1;
}	

//分解命令子函数
int ParseCommand()
{
	char Inputs[INPUT_LEN];
	int i=0,j=0,k=0,ch;
	
	printf("%s>",path);
            //获取输入
	if(GetInput(Inputs,INPUT_LEN)==-1)
	{
		printf("输入行太长。\n");
		return 0;
	}
	
	Para1[0]=Para2[0]='\0';
   
	//获取参数Para1,即操作名
while(Inputs[i]!=' '&&Inputs[i]!='\0' && i<COMMAND_LEN-1)
	{   
		Para1[i]=Inputs[i];
		i++;
	}//while
	Para1[i]='\0';
	
	//输入命令太长
	if(i==(COMMAND_LEN-1))return 1;

	//获取参数2,即路径文件名
if(Inputs[i]!='\0')
	{    
		while(Inputs[i]==' ' && i<INPUT_LEN-1) i++;
		j=0;
		while(Inputs[i]!='\0'  && i<INPUT_LEN-1)
		{  
			Para2[j]=Inputs[i];
			i++; j++;
		}
		Para2[j]='\0';
	}
	Trim(Para1);
	Trim(Para2);

	//将操作名全部转换成小写字母
	for(k=0;k<strlen(Para1);k++)
	{
		ch=tolower((int)Para1[k]);
		Para1[k]=ch;
	}
	return 1;
}

//cd功能处理子函数
int cdComd()
{
	if(!CheckCommand())//命令检查
		return 0;
   
	if(strcmp(Para2,"..")==0)
	{          //对cd ..命令的处理
		int i;
	
		while(cp->sibling_prev)
			cp=cp->sibling_prev;//找到这一层最左边的结点
		if(cp->parent)
		{
			cp=cp->parent;//找到父亲结点
		}
		else
		{
		    return 0;
		}
		//对当前路径进行相应处理
i=strlen(path);
		while(path[i]!='/'&& i>0) i--;
		
		if(i!=0)
			path[i]='\0';
		else
			path[i+1]='\0';
	
	}
	else
	{
		FindPath(Para2);//查找路径
	}
	return 1;
}

//命令格式处理子函数
void Trim(char* str)
{
	int begin,end;
	char* tmp;
	begin=0;
	end=strlen(str);

	//找到字符串第一个非空格的位置
	while(str[begin]==' ' && str[begin]!='\0')begin++;
	//去除字符串尾部空格
	while(str[--end]==' ');
	str[end+1]='\0';
	
	//除去空格
	if(begin<end)
	{
		tmp=(char*)malloc((sizeof(char))*(end-begin+2));
		strcpy(tmp,&str[begin]);
		strcpy(str,tmp);
		free(tmp);
	}
	
}

//获取当前目录名子函数
int GetDir(int begin,char* path,char* curDir)
{
	int i=0;
	int len=strlen(path);
	while(!((path[begin]=='\\' )|| (path[begin]=='/'))&&begin<len)
	{
		curDir[i++]=path[begin++];
	}
	curDir[i]='\0';
	Trim(curDir);
	return begin+1;
}

//查找路径子函数
int FindPath(char *ph) 
{
	struct FileNode *tp,*temp;
	char oldpath[INPUT_LEN-COMMAND_LEN];
	int i=0;
	int sign=1;
	if(strcmp(ph,"/")==0)
	{          //ph是根目录
		cp=root;
		strcpy(path,"/");
		return 1;
	}

	temp=cp;
	strcpy(oldpath,path);//保存原路径和指针
	if(ph[0]=='/')
	{          //指针指向根目录的左孩子
		cp=root->child;
		i++;//滤过'/'
		strcpy(path,"/");
	}
	else 
	{
		if(cp!=NULL && cp!=root )
			strcat(path,"/");

		if(cp && cp->child)
		{
			if(cp->isdir)
				cp=cp->child; //指针指向当前目录的左孩子

⌨️ 快捷键说明

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