0

作者: dz_zw_gxs | 来源:发表于2018-12-24 10:16 被阅读0次

#include "head.h"

//定义全局变量

char    choice;

int        argc;        // 用户命令的参数个数

char    *argv[5];        // 用户命令的参数

int        inum_cur;        // 当前目录

char    temp[2*BLKSIZE];    // 缓冲区

User    user;        // 当前的用户

char    bitmap[BLKNUM];    // 位图数组

Inode    inode_array[INODENUM];    // i节点数组

File_table file_array[FILENUM];    // 打开文件表数组

char    image_name[10] = "data.dat";    // 文件系统名称

FILE        *fp;                    // 打开文件指针

//创建映像hd,并将所有用户和文件清除

void format(void)

{

int  i;

Inode inode;

printf("Will be to format filesystem...\n");

printf("WARNING:ALL DATA ON THIS FILESYSTEM WILL BE LOST!\n");

printf("Proceed with Format(Y/N)?");

scanf("%c", &choice);

getchar();                                                               

if((choice == 'y') || (choice == 'Y'))

{

if((fp=fopen(image_name, "w+b")) == NULL)

{

printf("Can't create file %s\n", image_name);

exit(-1);

}

for(i = 0; i < BLKSIZE; i++)

fputc('0', fp);

inode.inum = 0;

strcpy(inode.file_name, "/");

inode.type = 'd';

strcpy(inode.user_name, "/");

inode.iparent = 0;

inode.length = 0;

inode.address[0] = -1;

inode.address[1] = -1;

fwrite(&inode, sizeof(Inode), 1, fp);

inode.inum = -1;

for(i = 0; i < 31; i++)

fwrite(&inode, sizeof(Inode), 1, fp);

for(i = 0; i < BLKNUM*BLKSIZE; i++)

fputc('\0', fp);

fclose(fp);

// 打开文件user.txt

if((fp=fopen("user.txt", "w+")) == NULL)

{

printf("Can't create file %s\n", "user.txt");

exit(-1);

}

fclose(fp);

printf("Filesystem created successful.Please first login!\n");

}

return ;

}

// 功能: 用户登陆,如果是新用户则创建用户

void login(void)

{

char *p;

int  flag;

char user_name[10];

char password[10];

char file_name[10] = "user.txt";

do

{

printf("login:");

gets(user_name);

printf("password:");

p=password;

while(*p=getch())

{

if(*p == 0x0d)

{

*p='\0'; //将输入的回车键转换成空格

break;

}

printf("*");  //将输入的密码以"*"号显示

p++;

}

flag = 0;

if((fp = fopen(file_name, "r+")) == NULL)

{

printf("\nCan't open file %s.\n", file_name);

printf("This filesystem not exist, it will be create!\n");

format();

login();

}

while(!feof(fp))

{

fread(&user, sizeof(User), 1, fp);

// 已经存在的用户, 且密码正确

if(!strcmp(user.user_name, user_name) &&

!strcmp(user.password, password))

{

fclose(fp);

printf("\n");

return ;

}

// 已经存在的用户, 但密码错误

else if(!strcmp(user.user_name, user_name))

{

printf("\nThis user is exist, but password is incorrect.\n");

flag = 1;

fclose(fp);

break;

}

}

if(flag == 0) break;

}while(flag);

// 创建新用户

if(flag == 0)

{

printf("\nDo you want to creat a new user?(y/n):");

scanf("%c", &choice);

gets(temp);

if((choice == 'y') || (choice == 'Y'))

{

strcpy(user.user_name, user_name);

strcpy(user.password, password);

fwrite(&user, sizeof(User), 1, fp);

fclose(fp);

return ;

}

if((choice == 'n') || (choice == 'N'))

login();

}

}

// 功能: 将所有i节点读入内存

void init(void)

{

int  i;

if((fp = fopen(image_name, "r+b")) == NULL)

{

printf("Can't open file %s.\n", image_name);

exit(-1);

}

// 读入位图

for(i = 0; i < BLKNUM; i++)

bitmap[i] = fgetc(fp);

// 显示位图

// 读入i节点信息

for(i = 0; i < INODENUM; i++)

fread(&inode_array[i], sizeof(Inode), 1, fp);

// 显示i节点

// 当前目录为根目录

inum_cur = 0;

// 初始化打开文件表

for(i = 0; i < FILENUM; i++)

file_array[i].inum = -1;

}

// 功能: 分析用户命令, 将分析结果填充argc和argv

// 结果: 0-13为系统命令, 14为命令错误

int analyse(char *str)

{

int  i;

char temp[20];

char *ptr_char;

char  *syscmd[]={"help", "cd", "dir", "mkdir", "create", "open", "read", "write",

"close", "delet", "logout", "clear","format","quit"};

argc = 0;

for(i = 0, ptr_char = str; *ptr_char != '\0'; ptr_char++)

{

if(*ptr_char != ' ')

{

while(*ptr_char != ' ' && (*ptr_char != '\0'))

temp[i++] = *ptr_char++;

argv[argc] = (char *)malloc(i+1);

strncpy(argv[argc], temp, i);

argv[argc][i] = '\0';

argc++;

i = 0;

if(*ptr_char == '\0') break;

}

}

if(argc != 0)

{

for(i = 0; (i < 14) && strcmp(argv[0], syscmd[i]); i++);

return i;

}

else

return 14;

}

// 功能: 将num号i节点保存到hd.dat

void save_inode(int num)

{

if((fp=fopen(image_name, "r+b")) == NULL)

{

printf("Can't open file %s\n", image_name);

exit(-1);

}

fseek(fp, BLKNUM +num*sizeof(Inode), SEEK_SET);

fwrite(&inode_array[num], sizeof(Inode), 1, fp);

fclose(fp);

}

// 功能: 申请一个数据块

int get_blknum(void)

{

int i;

for(i = 0; i < BLKNUM; i++)

if(bitmap[i] == '0') break;

// 未找到空闲数据块

if(i == BLKNUM)

{

printf("Data area is full.\n");

exit(-1);

}

bitmap[i] = '1';

if((fp=fopen(image_name, "r+b")) == NULL)

{

printf("Can't open file %s\n", image_name);

exit(-1);

}

fseek(fp, i, SEEK_SET);

fputc('1', fp);

fclose(fp);

return i;

}

// 功能: 将i节点号为num的文件读入temp

void read_blk(int num)

{

int  i, len;

char ch;

int  add0, add1;

len = inode_array[num].length;

add0 = inode_array[num].address[0];

if(len > 512)

add1 = inode_array[num].address[1];

if((fp = fopen(image_name, "r+b")) == NULL)

{

printf("Can't open file %s.\n", image_name);

exit(-1);

}

fseek(fp, BLKSIZE+INODESIZE*INODENUM +add0*BLKSIZE, SEEK_SET);

ch = fgetc(fp);

for(i=0; (i < len) && (ch != '\0') && (i < 512); i++)

{

temp[i] = ch;

ch = fgetc(fp);

}

if(i >= 512)

{

fseek(fp,BLKSIZE+INODESIZE*INODENUM+add1*BLKSIZE, SEEK_SET);

ch = fgetc(fp);

for(; (i < len) && (ch != '\0'); i++)

{

temp[i] = ch;

ch = fgetc(fp); 

}

}

temp[i] = '\0';

fclose(fp);

}

// 功能: 将temp的内容输入hd的数据区

void write_blk(int num)

{

int  i, len;

int  add0, add1;

add0 = inode_array[num].address[0];

len  = inode_array[num].length;

if((fp = fopen(image_name, "r+b")) == NULL)

{

printf("Can't open file %s.\n", image_name);

exit(-1);

}

fseek(fp, BLKSIZE+INODESIZE*INODENUM+add0*BLKSIZE, SEEK_SET);

for(i=0; (i<len)&&(temp[i]!='\0')&&(i < 512); i++)

fputc(temp[i], fp);

if(i == 512)

{

add1 = inode_array[num].address[1];

fseek(fp, BLKSIZE+INODESIZE*INODENUM+add1*BLKSIZE, SEEK_SET);

for(; (i < len) && (temp[i] != '\0'); i++)

fputc(temp[i], fp);

}

fputc('\0', fp);

fclose(fp);

}

// 功能: 释放文件块号为num的文件占用的空间

void release_blk(int num)

{

FILE *fp;

if((fp=fopen(image_name, "r+b")) == NULL)

{

printf("Can't open file %s\n", image_name);

exit(-1);

}

bitmap[num] = '0';

fseek(fp, num, SEEK_SET);

fputc('0', fp);

fclose(fp);

}

// 功能: 显示帮助命令

void help(void)

{

printf("command: \n\

help  ---  show help menu \n\

clear  ---  clear the screen \n\

cd    ---  change directory \n\

mkdir  ---  make directory  \n\

create  ---  create a new file \n\

open  ---  open a exist file \n\

read  ---  read a file \n\

write  ---  write something to a file \n\

close  ---  close a file \n\

delet ---  delete a exist file or directory \n\

format ---  format a exist filesystem \n\

logout ---  exit user \n\

quit  ---  exit this system\n");

}

//设置文件路径

void pathset()

{

char path[50];

int m,n;

if(inode_array[inum_cur].inum == 0)

strcpy(path,user.user_name);

else

{

strcpy(path,user.user_name);

m=0;

n=inum_cur;

while(m != inum_cur)

{

while(inode_array[n].iparent != m)

{

n = inode_array[n].iparent;

}

strcat(path,"/");

strcat(path,inode_array[n].file_name);

m = n;

n = inum_cur;

}

}

printf("[%s]$",path);

}

// 功能: 切换目录(cd .. 或者 cd dir1)

void cd(void)

{

int i;

if(argc != 2)

{

printf("Command cd must have two args. \n");

return ;

}

if(!strcmp(argv[1], ".."))

inum_cur = inode_array[inum_cur].iparent;

else

{

for(i = 0; i < INODENUM; i++)

if((inode_array[i].inum>0)&&

(inode_array[i].type=='d')&&

(inode_array[i].iparent==inum_cur)&&           

!strcmp(inode_array[i].file_name,argv[1])&&

!strcmp(inode_array[i].user_name,user.user_name))

break;

if(i == INODENUM)

printf("This directory isn't exsited.\n");

else

inum_cur = i;

}

}

// 功能: 显示当前目录下的子目录和文件(dir)

void dir(void)

{

int i;

int dcount=0,fcount=0;

short bcount=0;

if(argc != 1)

{

printf("Command dir must have one args. \n");

return ;

}

// 遍历i节点数组, 显示当前目录下的子目录和文件名

for(i = 0; i < INODENUM; i++)

if((inode_array[i].inum> 0) &&

(inode_array[i].iparent == inum_cur)&&

!strcmp(inode_array[i].user_name,user.user_name))

{

if(inode_array[i].type == 'd')

{

dcount++;

printf("%-20s<DIR>\n", inode_array[i].file_name);

}

else

{

fcount++;

bcount+=inode_array[i].length;

printf("%-20s%12d bytes\n", inode_array[i].file_name,inode_array[i].length);

}

}

printf("\n                    %d file(s)%11d bytes\n",fcount,bcount);

printf("                    %d dir(s) %11d bytes FreeSpace\n",dcount,1024*1024-bcount); 

}

// 功能: 在当前目录下创建子目录(mkdir dir1)

void mkdir(void)

{

int i;

if(argc != 2)

{

printf("command mkdir must have two args. \n");

return ;

}

// 遍历i节点数组, 查找未用的i节点

for(i = 0; i < INODENUM; i++)

if(inode_array[i].inum < 0) break;

if(i == INODENUM)

{

printf("Inode is full.\n");

exit(-1);

}

inode_array[i].inum = i;

strcpy(inode_array[i].file_name, argv[1]);

inode_array[i].type = 'd';

strcpy(inode_array[i].user_name,user.user_name);

inode_array[i].iparent = inum_cur;

inode_array[i].length = 0;

save_inode(i);

}

// 功能: 在当前目录下创建文件(creat file)

void create(void)

{

int i;

if(argc != 2)

{

printf("command creat must have two args. \n");

return ;

}

for(i = 0; i < INODENUM; i++)

{

if((inode_array[i].inum > 0) &&

(inode_array[i].type == 'f') &&

!strcmp(inode_array[i].file_name, argv[1]))

{

printf("This file is exsit.\n");

return ;

}

}

for(i = 0; i < INODENUM; i++)

if(inode_array[i].inum < 0) break;

if(i == INODENUM)

{

printf("Inode is full.\n");

exit(-1);

}

inode_array[i].inum = i;

strcpy(inode_array[i].file_name, argv[1]);

inode_array[i].type = 'f';

strcpy(inode_array[i].user_name, user.user_name);

inode_array[i].iparent = inum_cur;

inode_array[i].length = 0;

save_inode(i);

}

// 功能: 打开当前目录下的文件(open file1)

void open()

{

int i, inum, mode, filenum;

if(argc != 2)

{

printf("command open must have two args. \n");

return ;

}

for(i = 0; i < INODENUM; i++)

if((inode_array[i].inum > 0) &&

(inode_array[i].type == 'f') &&

!strcmp(inode_array[i].file_name,argv[1])&&

!strcmp(inode_array[i].user_name,user.user_name))

break;

if(i == INODENUM)

{

printf("The file you want to open doesn't exsited.\n");

return ;

}

inum = i;

printf("Please input open mode:(1: read, 2: write, 3: read and write):");

scanf("%d", &mode);

getchar();

if((mode < 1) || (mode > 3))

{

printf("Open mode is wrong.\n");

return;

}

for(i = 0; i < FILENUM; i++)

if(file_array[i].inum < 0) break;

if(i == FILENUM)

{

printf("The file table is full, please close some file.\n");

return ;

}

filenum = i;

file_array[filenum].inum = inum;

strcpy(file_array[filenum].file_name, inode_array[inum].file_name);

file_array[filenum].mode = mode;     

printf("Open file %s by ", file_array[filenum].file_name);

if(mode == 1) printf("read only.\n");

else if(mode == 2) printf("write only.\n");

else printf("read and write.\n");

}

// 功能: 从文件中读出字符(read file1)

void read()

{

int i, inum;

if(argc != 2)

{

printf("command read must have two args. \n");

return;

}

for(i = 0; i < FILENUM; i++)

if((file_array[i].inum > 0) &&

!strcmp(file_array[i].file_name,argv[1]))

break;

if(i == FILENUM)

{

printf("Open %s first.\n", argv[1]);

return ;

}

else if(file_array[i].mode == 2)

{

printf("Can't read %s.\n", argv[1]);

return ;

}

inum = file_array[i].inum;

printf("The length of %s:%d.\n", argv[1], inode_array[inum].length);

if(inode_array[inum].length > 0)

{

read_blk(inum); 

for(i = 0; (i < inode_array[inum].length) && (temp[i] != '\0'); i++)

printf("%c", temp[i]);

}

}

// 功能: 向文件中写入字符(write file1)

void write()

{

int i, inum, length;

if(argc != 2)

{

printf("Command write must have two args. \n");

return ;

}

for(i = 0; i < FILENUM; i++)

if((file_array[i].inum>0)&&

!strcmp(file_array[i].file_name,argv[1])) break;

if(i == FILENUM)

{

printf("Open %s first.\n", argv[1]);

return ;

}

else if(file_array[i].mode == 1)

{

printf("Can't write %s.\n", argv[1]);

return ;

}

inum = file_array[i].inum;

printf("The length of %s:%d\n", inode_array[inum].file_name, inode_array[inum].length);

if(inode_array[inum].length == 0)

{

i=0;

inode_array[inum].address[0] = get_blknum();

printf("Input the data(CTRL+Z to end):\n");

while(i<1023&&(temp[i]=getchar())!=EOF) i++;

temp[i]='\0';

length=strlen(temp)+1;

inode_array[inum].length=length;

if(length > 512)

inode_array[inum].address[1] = get_blknum();

save_inode(inum);

write_blk(inum);

}

else

printf("This file can't be written.\n");

}

// 功能: 关闭已经打开的文件(close file1)

void close(void)

{

int i;

if(argc != 2)

{

printf("Command close must have two args. \n");

return ;

}

for(i = 0; i < FILENUM; i++)

if((file_array[i].inum > 0) &&

!strcmp(file_array[i].file_name, argv[1])) break;

if(i == FILENUM)

{

printf("This file doesn't be opened.\n");

return ;

}

else

{

file_array[i].inum = -1;

printf("Close %s success!\n", argv[1]);

}

}

//回收i节点,有文件则删除文件

void del(int i)

{

inode_array[i].inum = -1;

if(inode_array[i].length > 0)

{

release_blk(inode_array[i].address[0]);

if(inode_array[i].length >= 512)

release_blk(inode_array[i].address[1]);

}

save_inode(i);

}

//删除子目录树和文件

void delet(void)

{

if(argc != 2)

{

printf("Command delete must have two args. \n");

return ;

}

int n,t,i;

stack<int> istk;

for(i = 0; i < INODENUM; i++)//查找待删除子目录

if((inode_array[i].inum >=0) &&

(inode_array[i].iparent == inum_cur)&&

(!strcmp(inode_array[i].file_name,argv[1]))&&

(!strcmp(inode_array[i].user_name,user.user_name)))

n=inode_array[i].inum;

break;

}

if(i==INODENUM) puts("Directory ERROR");

else

{

istk.push(n);

while(!istk.empty())

{

t=istk.top();

istk.pop();

del(t);

for(i = 0; i < INODENUM; i++)

if((inode_array[i].inum >=0) &&(inode_array[i].iparent == t))

istk.push(i);

}

}           

}

// 功能: 退出当前用户(logout)

void logout()

{

printf("Do you want to exit this user(y/n)?");

scanf("%c", &choice);

getchar();

if((choice == 'y') || (choice == 'Y'))

{

printf("\nCurrent user has exited!\n");

login();

}

return ;

}

// 功能: 退出文件系统(quit)

void quit()

{

printf("Do you want to exist(y/n):");

scanf("%c", &choice);

getchar();

if((choice == 'y') || (choice == 'Y'))

exit(0);

}

// 功能: 显示错误

void errcmd()

{

printf("Command Error!!!\n");

}

//清空内存中存在的用户名

void free_user()

{

int i;

for(i=0;i<10;i++)

user.user_name[i]='\0';

}

// 功能: 循环执行用户输入的命令, 直到logout

// "help", "cd", "dir", "mkdir", "creat", "open","read", "write", "close", "delete", "logout", "clear", "format","quit"

void command(void)

{

char cmd[100];

system("cls");

do

{

pathset();

gets(cmd);

switch(analyse(cmd))

{

case 0: 

help(); break;

case 1:

cd(); break;

case 2:

dir(); break;

case 3:

mkdir(); break;

case 4:

create(); break;

case 5:

open(); break;

case 6:

read(); break;

case 7:

write(); break;

case 8:

close(); break;

case 9:

delet(); break;

case 10:

logout();break;

case 11:

system("cls");break;

case 12:

format();

init();

free_user();

login();break;

case 13:

quit(); break;

case 14:

errcmd(); break;

default:

break;

}

}while(1);

}

// 主函数

int main(void)

{

login(); 

init();

command();

return 0;

}

相关文章

  • 0!0!0!

    今天是持续第三天零确诊的日子!同时,全市一切车辆停止,超市关门,配合做好第八次核酸检测。并且给每个做核酸的人发放了...

  • 0 0

    为什么console.log(object + "hello")//显示的是[object object] hello

  • 0。0

    12364829593716 确实你哦好辛苦都会死阿伯才能玩

  • 0/0

    不知从哪天起,可能是得知她和狗子好的那天开始,也可能是最后一次喝醉的那天开始,发现了自己过去的一年里什么也没有...

  • 0:0

    世界很大 优秀的人很多 自己真的就是一个渣渣 渣渣 就是一个0 过去所有的经历 事情 造就了现在的我 那么现在我所...

  • 《Over the Air Deep Learning Base

    snr: [26]Y [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0...

  • Test

    [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,...

  • [C语言]&a[0][0] a[0] a

    sizeof(&a[0][0]) 输出的是8,指针类型的大小是 8字节 sizeof(a[0]),每行的字节总数,...

  • LeetCode 289. Game of Life

    Game of Life live: 0 0 0 0 0 0 0 1die: 0 0 0 0 0 0 0 0 既...

  • Python:编写代码生成列表 [[0, 0, 0, 0, 0]

网友评论

      本文标题:0

      本文链接:https://www.haomeiwen.com/subject/eoyakqtx.html