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

📄 unixfilesyssim.cpp

📁 在内存中申请1M的空间来模拟存取设备
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "UnixFileSysSim.h"
unsigned FindBlankFileBlockId()
{
	unsigned char c;
	for (unsigned i = 0; i < FS.bm.BitMapLen / 8; i++)
	{
		c = FS.bm.BMStart[i] | 0x7F;
		if (c == 0x7F)
		{
			return i * 8;		//一个字节左边第一位为0,表示该区域未使用
		}

		c = FS.bm.BMStart[i] | 0xBF;
		if (c == 0xBF)
		{
			return i * 8 + 1;		
		}

		c = FS.bm.BMStart[i] | 0xDF;
		if (c == 0xDF)
		{
			return i * 8 + 2;		
		}
		c = FS.bm.BMStart[i] | 0xEF;
		if (c == 0xEF)
		{
			return i * 8 + 3;		
		}
		c = FS.bm.BMStart[i] | 0xF7;
		if (c == 0xF7)
		{
			return i * 8 + 4;		
		}
		c = FS.bm.BMStart[i] | 0xFB;
		if (c == 0xFB)
		{
			return i * 8 + 5;		
		}
		c = FS.bm.BMStart[i] | 0xFD;
		if (c == 0xFD)
		{
			return i * 8 + 6;		
		}
		c = FS.bm.BMStart[i] | 0xFE;
		if (c == 0xFE)
		{
			return i * 8 + 7;		
		}
	}
	return FILEBLOCKCOU + 1;
}

/*
* 函数介绍:寻找第一个文件块地址
* 输入参数:fileblockid 文件块ID
* 输出参数:无
* 返 回 值:返回文件块的地址
*/
char * FindBlankFileBlock(unsigned fileblockid)
{
	FileBlock *fblock = FS.head;
	while (fblock->next != NULL)
	{
		if (fblock->FileBlockId == fileblockid)
		{
			return fblock->FileBlockAddr;
		}
		else
		{
			fblock = fblock->next;
		}
	}
	return NULL;
}

/*
* 函数介绍:得到当前时间的字符串
* 输入参数:时间字符串的指针
* 输出参数:无
* 返 回 值:void
*/
void GetCurrentTime(char *currtime)
{
	char dbuffer [9];
	char tbuffer [9];
	_strdate(dbuffer);
	_strtime(tbuffer);
	strcpy(currtime, dbuffer);
	strcat(currtime, " ");
	strcat(currtime, tbuffer);
}

/*
* 函数介绍:更新文件索引
* 输入参数:fileblockid 文件块ID
* 输出参数:无
* 返 回 值:无
*/
void AddFileIndex(unsigned fileblockid, unsigned filelevel, char *filename, char *parentname)
{
	FS.FI.FIStart[FS.FI.FICount].FileBlockId = fileblockid;
	FS.FI.FIStart[FS.FI.FICount].FileLevel = filelevel;
	strcpy(FS.FI.FIStart[FS.FI.FICount].FileName, filename);
	if (parentname == NULL)
	{
		memset(FS.FI.FIStart[FS.FI.FICount].ParentName, '\0', MAXFILENAMELEN);
	}
	else
	{
		strcpy(FS.FI.FIStart[FS.FI.FICount].ParentName, parentname);
	}
	FS.FI.FIStart[FS.FI.FICount].Index = FS.FI.FICount;
	FS.FI.FIStart[FS.FI.FICount].effect = 1;
	FS.FI.FICount ++;
}

/*
* 函数介绍:更新位示图
* 输入参数:fileblockid 文件块ID
* 输出参数:无
* 返 回 值:无
*/
void UpdateBitMap(unsigned fileblockid)
{
	//计复所在位示图的位置
	int dirInBitmap = ((int)(fileblockid / 8));
	int dirInChar = fileblockid % 8;

	char *c = &(FS.bm.BMStart[dirInBitmap]);
	char xor;
	switch (dirInChar)
	{
	case 0:
		xor = 0x80;
		break;
	case 1:
		xor = 0x40;
		break;
	case 2:
		xor = 0x20;
		break;
	case 3:
		xor = 0x10;
		break;
	case 4:
		xor = 0x08;
		break;
	case 5:
		xor = 0x04;
		break;
	case 6:
		xor = 0x02;
		break;
	case 7:
		xor = 0x01;
		break;
	}
	*c = *c ^ xor;
}

/*
* 函数介绍:创建一个文件元素
* 输入参数:acc 文件元素可操作权限,filename 文件元素名称,type 文件元素类型,filecontent 文件内容
* 输出参数:无
* 返 回 值:返回一个文件元素的指针
*/
FSElement * CreateFileElement(FEAccess acc, char *filename, FEType type, char *filecontent, FSElement *parent)
{
	//查找第一个空白文件块ID
	unsigned blankFileBlockId = FindBlankFileBlockId();
	if (blankFileBlockId >= FILEBLOCKCOU)
	{
		printf("未找到一个文件块的id\n");
		return NULL;
	}

	//查找第一个空白块的地址
	char *blank = FindBlankFileBlock(blankFileBlockId);
	if (blank == NULL)
	{
		printf("未找到一个文件块的地址\n");
		return NULL;
	}

	FSElement *fs = (FSElement *)blank;

	fs->Access = acc;
	fs->Creator = CS.CurrentUser;
	GetCurrentTime(fs->CreateTime);
	fs->FileBlockId = blankFileBlockId;
	fs->FileLevel = CS.FileLevel;
	strcpy(fs->FileName, filename);
	strcpy(fs->LastModTime, fs->CreateTime);
	fs->Type = type;
	fs->parent = parent;	

	if (type == dir)
	{
		fs->FileElemLen = sizeof(FSElement);
		fs->FileData = NULL;
	}
	else
	{		
		fs->FileElemLen = (unsigned)strlen(filename);
		fs->fileStu = closed;
		fs->FileData = (char *)fs + sizeof(FSElement);
		if (filecontent == NULL)
		{
		}
		else
		{
			strcpy(fs->FileData, filecontent);
		}
	}	

	//更新索引	
	if (parent == NULL)
	{
		AddFileIndex(blankFileBlockId, CS.FileLevel, filename, NULL);	
	}
	else
	{
		AddFileIndex(blankFileBlockId, CS.FileLevel, filename, parent->FileName);
	}

	//更新BITMAP
	UpdateBitMap(blankFileBlockId);
	return fs;
}

/*
* 函数介绍:创建文件块链表
* 输入参数:datahead 第一块数据的地址,blockcap 一个文件块的大小,len 链表的长度
* 输出参数:无
* 返 回 值:返回链表的头指针
*/
FileBlock * CreateFileBlockList(char *datahead, unsigned blockcap, unsigned len)
{
	if (datahead == NULL || len == 0)
	{
		return NULL;
	}
	FileBlock *head;
	FileBlock *pnew;
	FileBlock *pold;

	head = pold = pnew = (FileBlock *)malloc(sizeof(FileBlock));
	for ( unsigned i = 0; i < len; i++)
	{
		pold->FileBlockId = i;
		pold->FileBlockCap = FILEBLOCKCAP;
		pold->FileBlockAddr = datahead + i * blockcap;
		memset(pold->FileBlockAddr, '\0', blockcap);
		if (i != len - 1)
		{
			pnew = (FileBlock *)malloc(sizeof(FileBlock));
		}
		else
		{
			pnew = NULL;
		}
		pold->next = pnew;	
		pold = pnew;

	}
	return head;
}

/*
* 函数介绍:初始化模拟文件系统
* 输入参数:无
* 输出参数:无
* 返 回 值:true-初始化成功,false-初始化失败
*/
bool InitFileSys()
{
	//初始化模拟的文件系统
	if ((FS.FSStart = (char *)malloc(FILESYSCAP)) == NULL)
	{
		return false;		
	}

	FS.FileSystemCap = FILESYSCAP;
	FS.bm.BitMapLen = BITMAPLEN;
	FS.bm.BMStart = FS.FSStart;

	//设置位示图为未使用
	memset(FS.bm.BMStart, '\0', FS.bm.BitMapLen);

	//初始化文件系统索引
	FS.FI.FIStart = (FileIndexElement *)(FS.FSStart + BITMAPLEN);
	//因为是模拟系统,暂定一个文件或文件夹最多占用一个文件块,一个文件块只放一个文件元素
	FS.FI.FILen   = sizeof(FileIndexElement) * FILEBLOCKCOU + sizeof(unsigned) * 2;	
	FS.FI.FICount = 0;
	memset(FS.FI.FIStart, '\0', FS.FI.FILen);

	//初始化文件块
	FS.FileBlockCou = FILEBLOCKCOU;
	FS.head = CreateFileBlockList((FS.FSStart + FILESYSCAP - FILEBLOCKCAP * FILEBLOCKCOU), 
		      FILEBLOCKCAP, FS.FileBlockCou);//区域的后FILEBLOCKCAP * FILEBLOCKCOU个单元用来存储数据

	if (FS.head == NULL)
	{
		return false;
	}


	//初始化系统当前状态
	CS.CurrentUser.UserName = (char *)calloc(10,sizeof(char));
	strcpy(CS.CurrentUser.UserName, "man");
	CS.CurrentUser.ut = admin;
	CS.CurrParent = NULL;
	CS.FileLevel = 0;
	CS.CurrentPath = (char *)calloc(1000, sizeof(char));

	//创建一个根目录
	base = CreateFileElement(pub, "root", dir, NULL, NULL);
	if (base == NULL)
	{
		return false;
	}
	else
	{
		return true;
	}
}

/*
* 函数介绍:系统登录模块
* 输入参数:无
* 输出参数:无
* 返 回 值:true 登录成功,false 登录失败
*/
bool Login()
{
	char username[10];
	char password[MAXPASSWORDLEN];
	int c;

	for (c = 0; c < USERTESTLOGINCOU; c++)
	{
		int i = 0;
		memset(password, '\0', MAXPASSWORDLEN);
		memset(username, '\0', 10);
		printf("login:");
		gets(username);

		printf("password:");
		while (i < MAXPASSWORDLEN && (password[i++] = getch()) != 0x0d) {};
		password[strlen(password) - 1] = '\0';

		printf("\nuser name : %s \npassword:%s\n", username, password);

		if ((strcmp(username, "user1") == 0 && strcmp(password, "user1") == 0) ||
			(strcmp(username, "user2") == 0 && strcmp(password, "user2") == 0) ||
			(strcmp(username, "user3") == 0 && strcmp(password, "user3") == 0) ||
			(strcmp(username, "user4") == 0 && strcmp(password, "user4") == 0) ||
			(strcmp(username, "user5") == 0 && strcmp(password, "user5") == 0) ||
			(strcmp(username, "user6") == 0 && strcmp(password, "user6") == 0) ||
			(strcmp(username, "user7") == 0 && strcmp(password, "user7") == 0) ||
			(strcmp(username, "user8") == 0 && strcmp(password, "user8") == 0) ||
			(strcmp(username, "super") == 0 && strcmp(password, "super") == 0))
		{
			if (strcmp(username, "super") == 0)		//	一个管理员
			{
				strcpy(CS.CurrentUser.UserName, username);
				CS.CurrentUser.ut = admin;					
			}
			else
			{
				//memset(CS.CurrentUser.UserName, '\0', 10);	
				strcpy(CS.CurrentUser.UserName, username);
				CS.CurrentUser.ut = comm;
			}
			CS.FileLevel++;
			CS.CurrParent = base;
			strcpy(CS.CurrentPath, "\\");
			printf("\n欢迎使用模拟UNIX文件系统。\n");
			printf("\n%s %s\n$", username, CS.CurrentPath);
			break;
		}
		else
		{
			printf("\n用户名或密码错误,请重新输入。\n");
		}
	}

	if (c >= USERTESTLOGINCOU)		//非法用户
	{
		printf("\n对不起,您不是该系统用户,按任意键退出系统。\n");
		return false;
	}
	else
	{
		return true;
	}
}

/*
* 函数介绍:命令分解
* 输入参数:command 用户输入命令字,key 关键字,path 路径
* 输出参数:无
* 返 回 值:无
*/
void FindCommKey(char *command, char *key, char *path)
{
	for (unsigned i = 0; i < strlen(command); i++)
	{
		if (command[i] == ' ')
		{
			i++;
			if (i < strlen(command))
			{
				strcpy(path, command + i);	
			}
			break;
		}
		if (i <= 9)
		{
			key[i] = command[i];
		}
		else
		{
			for (unsigned j = i; j < strlen(command); j++)
			{
				if (command[j] != ' ')
				{
					strcpy(path, command + j);
					break;

⌨️ 快捷键说明

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