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