📄 fs.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <string.h>
#include <malloc.h>
#include <iomanip.h>
#include <dos.h>
#define BLOCK_SIZE 8192
#define BLOCK_TOTAL 50
#define BLOCK_OUT -1
#define BLOCK_RTBASE 1
#define MAX_FBLKTOTAL 5
#define MAX_FILENM 32
#define MAX_USERNM 32
#define MAX_KEYLEN 8
#define MAX_USERTOTAL 1
#define MAX_RECTOTAL 20
#define MAX_IOBUF 512
#define UID_SYSM 0
#define UID_USR1 1
#define UID_USR2 2
#define UID_USR3 3
#define UID_USR4 4
#define NULLSUER -1
#define NOF_ERR -1
#define PRI_ERR -2
#define SPANOELV_ERR -3
#define FORMAT_ERR -4
#define LOGIN_ERR -5
#define NOD_ERR -6
#define MAL_ERR -7
#define MOD_ERR (-8)
#define PATH_ERR -9
#define RFULL_ERR -10
#define OPEN_ERR -11
//#define NULL -11
#define OVERW_ERR -12
#define NULLUSER 0
#define OK 1
// unsigned int UID[MAX_USERTOTAL]={UID_USR1,UID_USR2,UID_USR3,UID_USR4};
struct free_block{
unsigned int cur_blknum; //当前空闲块编号
unsigned int next_blknum; //下一空闲块编号
};
struct free_inode{
unsigned int cur_nodnum; //当前空闲块编号
unsigned int next_nodnum; //下一空闲块编号
};
struct user{
char key[MAX_KEYLEN]; // 用户密码
char name[MAX_FILENM]; //用户姓名
unsigned int uid; //用户ID
};
struct table{
unsigned int flag; //是否有文件纪录标志
char rec_name [MAX_FILENM]; //纪录文件和子目录名
unsigned int rec_idnum; //纪录和文件及子目录名对应的inode编号
};
struct dir{
unsigned int inode_num; //保存该目录的块所对应的inode节点索引
unsigned int rec_len; //该目录下的纪录个数
struct table rectables[MAX_RECTOTAL];
};
struct mode{
unsigned int rwx:3; //文件读、写、执行的权限,1有效表示可以
unsigned int pri:1; //文件的级别:超级用户0 ,普通用户1
unsigned int typ:1; //文件的类型:普通文件1,目录文件0
};
struct inode{
unsigned int i_num; //该节点在空闲inode表中的编号
struct mode i_mode; //文件类型和访问权限
unsigned int i_uid;
unsigned int flag; //读写标志
unsigned int f_length;
unsigned int f_blktotal;
unsigned int f_blknums[BLOCK_TOTAL];
unsigned int i_father; //指向父节点
};
struct super_block{
unsigned int blksize;
unsigned int blktotal;
unsigned int fsy_num;
unsigned int freblkstart; //始终指向当前空闲块,空闲块满则置为NULL
char basefilenm [MAX_FILENM]; //纪录虚拟磁盘文件名称
struct free_block free_blks[BLOCK_TOTAL];
struct user users[MAX_USERTOTAL];
unsigned int freenod_start; //始终指向当前空闲块,空闲块满则置为NULL
struct free_inode free_inodes[BLOCK_TOTAL]; //record free i_nodes,0:free,1:used
};
/*************************************************
* now define globl variable
*
*
**************************************************/
struct super_block * psp;
unsigned int maxftotal;
unsigned int UID[MAX_USERTOTAL]={UID_USR1};
char namelist[MAX_USERTOTAL][MAX_USERNM]={"xqc"};
char keylist[MAX_USERTOTAL][MAX_KEYLEN]={"654321"};
unsigned int cur_usernum;
FILE * fd;
/*************************************************
* now define format()
*
*
**************************************************/
unsigned int format(void)
{
struct dir boot; //dir dictionary
struct inode * pnode;
unsigned int i;
unsigned int useblk;
unsigned int inodlen;
char name[MAX_USERNM]="name";
char key[MAX_KEYLEN]="11232435";
// char * name="name";
// char * key="11232435";
psp=(struct super_block *)malloc(sizeof(struct super_block));
if(psp==NULL){
printf("Initiate global variable psp error! \n");
return MAL_ERR;
}
pnode=(struct inode *)malloc(sizeof(struct inode));
if(pnode==NULL){
printf("Malloc inode error! \n");
return MAL_ERR;
}
/************************************
** 1. initiate super blocks
** 2. initiate free inodes
** 3. creat user list
** 4. write super block content to disk
** 5. write root inode to disk
**
**/
/* initiate super block members */
psp->blksize=BLOCK_SIZE;
psp->blktotal=BLOCK_TOTAL;
psp->fsy_num=0x01;
/* now initiate free block line */
for(i=1;i<BLOCK_TOTAL;i++){
psp->free_blks[i].cur_blknum=i;
psp->free_blks[i].next_blknum=i+1;
}
psp->freblkstart=BLOCK_RTBASE; //BLOCK_RTBASE is used to recorded boot dictionary
psp->free_blks[i-1].next_blknum=psp->freblkstart; //构成空闲块循环表
/* now initiate free inode array */
inodlen=sizeof(struct inode);
i=BLOCK_SIZE/inodlen;
maxftotal=BLOCK_TOTAL<i?BLOCK_TOTAL:i;
for(i=0;i<maxftotal;i++){
psp->free_inodes[i].cur_nodnum=i;
psp->free_inodes[i].next_nodnum=i+1;
}
psp->freenod_start=0;
psp->free_blks[i-1].next_blknum=psp->freblkstart; //构成空闲inode循环表
/* initate system mamanger user list */
printf("@ Input system mamanger name : ");
scanf("%s",name);
printf("@ Input system mamanger key : ");
scanf("%s",key);
strcpy(psp->users[0].name,name);
strcpy(psp->users[0].key,key);
psp->users[0].uid=UID_SYSM;
/* initate commer user list */
for(i=1;i<MAX_USERTOTAL;i++){
printf("@ Input common user%d name : ",i);
scanf("%s",(char *)name);
printf("@ Input common user%d key : ",i);
scanf("%s",(char *)key);
strcpy(psp->users[i].name,name);
strcpy(psp->users[i].key,key);
}
for(i=1;i<MAX_USERTOTAL;i++)
psp->users[i].uid=UID[i];
/* write super block content to first block */
fwrite(psp,sizeof(struct super_block),1,fd);
/* creat and write boot dir content to a free block */
boot.inode_num=0;
boot.rec_len=0;
useblk=psp->free_blks[psp->freblkstart].next_blknum;
fseek(fd,useblk*BLOCK_SIZE,SEEK_SET);
fwrite(psp,sizeof(struct super_block),1,fd);
/* update free_blks line in sup_block struct */
psp->free_blks[psp->freblkstart].next_blknum=psp->free_blks[useblk].next_blknum;
/* creat first inode to record boot dirctory */
pnode->i_num=0;
pnode->i_mode.rwx=4;
pnode->i_mode.pri=0;
pnode->i_mode.typ=0;
pnode->i_uid=1;
pnode->flag=0;
pnode->f_length=0;
pnode->f_blktotal=1;
pnode->f_blknums[0]=psp->freblkstart;
pnode->i_father=0;
/* write inode content to its inode area in block 1 */
fseek(fd,BLOCK_SIZE,SEEK_SET);
fwrite(psp,sizeof(struct inode),1,fd);
/* modify free block start index psp->freblkstart */
psp->freblkstart=psp->free_blks[psp->freblkstart].next_blknum;
printf("\n Success!");
fclose(fd);
return OK;
}
/***********************************************
**
**
***********************************************/
unsigned int login(void)
{
unsigned int num;
char name[MAX_USERNM];
char key[MAX_KEYLEN];
struct inode * pusernod;
struct dir * pdboot;
unsigned int nodnum,next,blknum,offset,i;
/** read out super block area at first **/
if(psp==NULL){ //第一次进入则需读出 super block 结构
psp=(struct super_block *)malloc(sizeof(struct super_block));
if(psp==NULL){
printf("Initiate global variable psp error! \n");
return MAL_ERR;
}
/* read out super block */
fread(psp,sizeof(struct super_block),1,fd);
}
//login first
printf("@ user name : ");
scanf("%s",name);
printf("@ user key : ");
scanf("%s",key);
for(i=0;i<MAX_USERTOTAL;i++)
if(strcmp(psp->users[i].name,name)==0)
break;
if(i==MAX_USERTOTAL){
printf("User not exit!\n");
return LOGIN_ERR;
}
if(strcmp(psp->users[i].key,key)!=0){
printf("Secrate key error!\n");
return LOGIN_ERR;
}
cur_usernum=i;
/* 1. malloc a inode for current user
* 2. add a record of dir name of user to boot dir
* 3. malloc a block for boot dir form disk
* 4. write boot dir to disk
*/
/* malloc a free inode in memory*/
pusernod=(struct inode * )malloc(sizeof(struct inode));
if(pusernod==NULL){
printf("malloc new inode error!");
return MAL_ERR;
}
/* malloc a free inode in inode area in disk */
nodnum=psp->freenod_start;
pusernod->i_num=psp->free_inodes[nodnum].next_nodnum;
/* update psp->freenod_start and psp->free_nods[] */
next=psp->free_inodes[nodnum].next_nodnum;
psp->free_inodes[nodnum].next_nodnum=psp->free_inodes[next].next_nodnum;
psp->freenod_start=psp->free_inodes[next].next_nodnum; //freenod_start point to next free inode
pusernod->i_mode.rwx=6;
pusernod->i_mode.pri=(cur_usernum==0)?0:1;
pusernod->i_mode.typ=0;
num=cur_usernum;
pusernod->i_uid=psp->users[num].uid;
pusernod->i_father=BLOCK_RTBASE;
pusernod->flag=0; //no body is reading
pusernod->f_length=0;
pusernod->f_blktotal=0;
pusernod->f_blknums[0]=psp->freblkstart;
/* rewrite new inode to disk */
offset=BLOCK_SIZE+sizeof(struct inode)*nodnum;
fseek(fd,offset,SEEK_SET);
fwrite((char *)pusernod,sizeof(struct inode),1,fd);
/* add a record of dir name of user to boot dir
* . read out boot dir struct from disk
* . update boot dir struct
* . save boot dir file to disk
****/
pdboot=(struct dir *)malloc(sizeof(struct dir));
if(pdboot==NULL){
printf("malloc new dir error!");
return MAL_ERR;
}
/* read out boot dir from disk according pusernod */
blknum=pusernod->i_father;
fseek(fd,blknum*BLOCK_SIZE,SEEK_SET);
fread((char *)pdboot,sizeof(struct dir),1,fd);
/* update and write boot dir content to a free block */
pdboot->inode_num=BLOCK_RTBASE;
pdboot->rec_len++;
/* seach for free recordtables for user dir */
for(i=0;i<MAX_RECTOTAL;i++){
if(pdboot->rectables[i].flag==1)
continue;
else break;
}
strcpy(pdboot->rectables[i].rec_name,name); // record current user name
pdboot->rectables[i].rec_idnum=nodnum; // record current user inode number
/* malloc a free block area in disk for boor dir */
blknum=psp->free_blks[psp->freblkstart].next_blknum;
/* rewrite boot dir to free block */
offset=BLOCK_SIZE*blknum;
fseek(fd,offset,SEEK_SET);
fwrite((char *)pdboot,sizeof(struct dir),1,fd);
/* update free_blks line in sup_block struct */
psp->free_blks[psp->freblkstart].next_blknum=psp->free_blks[blknum].next_blknum;
psp->freblkstart=blknum;
printf("begin login ..........\n");
//sleep(2);
printf("login Done! \n");
printf("\n Success!");
return OK;
}
/***********************************************
**
**
***********************************************/
unsigned int logout(void)
{
char ch;
/** read out super block area at first **/
if(psp==NULL){ //第一次进入则需读出 super block 结构
psp=(struct super_block *)malloc(sizeof(struct super_block));
if(psp==NULL){
printf("Initiate global variable psp error! \n");
return MAL_ERR;
}
/* read out super block */
fread(psp,sizeof(struct super_block),1,fd);
}
printf("Log out?Y/N ");
//ch=getch();
//putch(ch);
//cin>>ch;
scanf("%c",&ch);
if(ch=='Y'||ch=='y')
cur_usernum=NULLUSER;
//sleep(1);
printf("Logout Done! \n");
return OK;
}
/****************************************************
** 函数
** 函数
**
***************************************************/
unsigned int getinode(const char * rname)
{
char * subname="/user";
char buf[MAX_FILENM];
unsigned int leng,nodnum,begnum,offset,blklen,blknum;
unsigned int i,j,k;
struct dir * pdir;
struct inode * pnode;
char ch;
i=0;
ch=*(rname+i);
j=i=k=0;
begnum=0;
nodnum=begnum;
subname="username";
pnode=(struct inode *)malloc(sizeof(struct inode));
if(pnode==NULL){
printf("malloc error \n");
return MAL_ERR;
}
pdir=(struct dir *)malloc(sizeof(struct dir));
if(pdir==NULL){
printf("Malloc dir struct error!\n");
return MAL_ERR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -