📄 main.c
字号:
#include "os.h"
#include "stdio.h"
#include "string.h"
#include "windows.h"
void textcolor(int color);
//设置文本输出颜色
void textcolor (int color)
{
SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), color );
}
// 用户权限检测函数:access()
unsigned short access( struct inode * inode )
{ unsigned short can = 0;
// 该用户可读检测
if(( inode->i_mode & OREAD ) || (( inode->i_mode & GREAD ) && ( user[user_id].u_gid == inode->i_gid )) || ((inode->i_mode & UREAD) && ( user[user_id].u_uid == inode->i_uid )))
can = can | READ;
// 该用户可写检测
if(( inode->i_mode & OWRITE ) || (( inode->i_mode & GWRITE ) && (user[user_id].u_gid == inode->i_gid )) || (( inode->i_mode & UWRITE) && ( user[user_id].u_uid == inode->i_uid )))
can = can | WRITE;
// 该用户可执行检测
if(( inode->i_mode & OEXE ) || (( inode->i_mode & GEXE ) && ( user[user_id].u_gid == inode->i_gid )) || (( inode->i_mode & UEXE) && ( user[user_id].u_uid == inode->i_uid )))
can = can | EXICUTE;
return can;
}
//空闲盘块分配函数:balloc()
static unsigned int block_buf0[BLOCKSIZ];
unsigned int balloc()
{ unsigned int free_block, free_block_num;
int i;
textcolor(5);
if( filsys.s_nfree == 0 ) // 磁盘已满,无空闲盘块
{ printf( "Disk has no space\n" );
return -1;
}
free_block = filsys.s_free[filsys.s_pfree]; // 取得当前空闲盘块
if( filsys.s_pfree == 0 ) // 已经是栈底
{ // 读取栈底盘块号所对应的盘块数据
bread( filsys.s_free[filsys.s_pfree], block_buf0 );
free_block_num = block_buf0[NICFREE]; // 读取该空闲盘块组的盘块数
// 把盘块组放到空闲盘块号栈上
for( i = 0; i < free_block_num; i++ )
filsys.s_free[i] = block_buf0[i];
filsys.s_pfree = free_block_num - 1; // 指针指向栈顶
}
else
filsys.s_pfree--; // 栈指针下移一位
filsys.s_nfree--; // 空闲盘块少1
return free_block; // 返回空闲盘块号数
}
// 空闲盘块回收函数:bfree
void bfree( unsigned int block_num )
{ int i;
filsys.s_pfree++; // 栈指针上移一位
if( filsys.s_pfree == NICFREE ) // 空闲盘块堆栈已满
{ block_buf0[NICFREE] = NICFREE; // 空闲盘块堆栈的盘块数NICFREE记入缓冲区
for( i = 0; i < NICFREE; i++ )
block_buf0[i] = filsys.s_free[i]; // 把空闲盘块数据写入缓冲区
filsys.s_pfree = 0; // 栈指针指向栈底
bwrite( block_num, block_buf0 ); // 缓冲区内容写入新回收的盘块
}
filsys.s_free[filsys.s_pfree] = block_num; // 回收盘块
filsys.s_nfree++; // 空闲盘块多1
}
// 读相应盘块号的数据函数:bread
void bread( unsigned int ino, char * buf )
{ fseek( fd, DATASTART + BLOCKSIZ * ino, SEEK_SET );
fread( buf, 1, BLOCKSIZ, fd );
}
// 写相应盘块号的数据函数:bwrite
void bwrite( unsigned int ino, char * buf )
{
fseek( fd, DATASTART + BLOCKSIZ * ino, SEEK_SET );
fwrite( buf, 1, BLOCKSIZ, fd );
}
// 命令解释层函数cmdexp()
char input_buf[20]; //命令行输入缓冲区
int over; //命令行结束标记
int cmdexp()
{ char buf[5];
over = 0;
// 显示命令提示行
textcolor(12);
printf("^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
printf("如需帮助请由终端输入'help'\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n");
textcolor(7);
printf( "[%s@localhost]# ", user[user_id].u_name, cur_direct[cur_dir_id].d_name );
// 读取用户输入
getcmd();
//显示帮助文件
if(strcmp( input_buf, "help" ) == 0 )
{ getcmd();
help();
clearbuf();
return 0;
}
// 显示当前目录
if(( strcmp( input_buf, "dir" ) == 0 ))
{ _dir();
clearbuf();
return 0;
}
// 改变当前目录
if (strcmp( input_buf, "cd" ) == 0 )
{ getcmd();
chdir( input_buf );
clearbuf();
return 0;
}
// 创建目录(建立子目录)
if( strcmp( input_buf, "mkdir" ) == 0 )
{
if( over )
{ textcolor(12);
printf( "mkdir: 请确认是否输入目录名\n" ); // mkdir命令参数不足
textcolor(7);
clearbuf();
return 0;
}
getcmd();
if( input_buf[0] == '\0' )
{ textcolor(12);
printf( "mkdir: 请确认是否输入目录名\n" );
textcolor(7);
clearbuf();
return 0;
}
mkdir( input_buf );
while( !over )
{
getcmd();
if( input_buf[0] != '\0' )
mkdir( input_buf );
}
textcolor(14);
printf("目录创建成功!\n\n");
textcolor(7);
clearbuf();
return 0;
}
// 删除目录
if( strcmp( input_buf, "rmdir" ) == 0 )
{
if( over )
{ textcolor(12);
printf( "rmdir: 请确认是否输入目录名\n" );
textcolor(7);
clearbuf();
return 0;
}
getcmd();
if( input_buf[0] == '\0' )
{ textcolor(12);
printf( "rmdir: 请确认是否输入目录名\n" );
textcolor(7);
clearbuf();
return 0;
}
rmdir( input_buf );
while( !over )
{ getcmd();
if( input_buf[0] != '\0' )
rmdir( input_buf );
}
textcolor(14);
textcolor(7);
clearbuf();
return 0;
}
// 显示文件
if(strcmp( input_buf, "open" ) == 0 || strcmp( input_buf, "read" ) == 0)
{if( over )
{
textcolor(12);
printf( "open/read: 请确认是否输入文件名\n" );
textcolor(7);
clearbuf();
return 0;
}
getcmd();
if( input_buf[0] == '\0' )
{ textcolor(12);
printf( "open/read: 请确认是否输入文件名\n" );
textcolor(7);
clearbuf();
return 0;
}
list( input_buf );
while( !over )
{ getcmd();
if( input_buf[0] != '\0' )
list( input_buf );
}
textcolor(14);
textcolor(7);
clearbuf();
return 0;
}
// 删除文件
if( strcmp( input_buf, "delete" ) == 0 )
{if( over )
{
textcolor(12);
printf( "delete: 请确认是否输入文件名\n" );
textcolor(7);
clearbuf();
return 0;
}
getcmd();
if( input_buf[0] == '\0' )
{ textcolor(12);
printf( "delete: 请确认是否输入文件名\n" );
textcolor(7);
clearbuf();
return 0;
}
_delete( input_buf );
while( !over )
{ getcmd();
if( input_buf[0] != '\0' )
_delete( input_buf );
}
clearbuf();
return 0;
}
// 建立新文件并编辑
if( strcmp( input_buf, "create" ) == 0 || strcmp( input_buf, "write" ) == 0)
{
getcmd();
textcolor(7);
edlin( input_buf );
textcolor(14);
printf("文件创建成功!\n\n");
textcolor(7);
clearbuf();
return 0;
}
if( strcmp (input_buf,"user") == 0)
{
getcmd();
choice();
clearbuf();
return 0;
}
if( strcmp( input_buf, "quit" ) == 0 )
{ quit();
clearbuf();
return 1;
}
// 找不到该命令
if( input_buf[0] != '\0' )
{
textcolor(12);
printf( "%s: 找不到此命令,请确认。\n", input_buf );
textcolor(7);
clearbuf();
}
return 0;
}
// 取得命令函数:getcmd()
getcmd()
{ int i;
i = 0;
// 取得命令
while( !over )
{ input_buf[i] = getchar();
if( input_buf[i] == ' ' )
{ if( i == 0 ) // 命令行的开始是空格,应舍去
i--;
else
{
input_buf[i]='\0';
break;
}
}
else
if( input_buf[i] == '\n' )
{
over = 1;
input_buf[i]='\0';
break;
}
i++;
}
}
// 清空缓冲区
clearbuf()
{ while( !over )
{ if( getchar() =='\n' )
break;
}
return 0;
}
//显示目录函数dir()
extern char end_path_name[DIRSIZ]; // 最后路径名字
extern int pre_dinodeid;
void _dir()
{
unsigned int di_mode;
int i, j, filenum, dirnum;
struct inode * inode;
filenum = 0; // 文件计数
dirnum = 0; // 目录计数
textcolor(14);
printf( "\n□当前目录信息□\n" );
textcolor(7);
printf("===========================================================\n");
textcolor(9);
printf(" 类型(d/-) 权限(r/w/x) 用户号 组号 大小 名称\n");
for( i = 2; i < dir.size; i++ )
{
if( dir.direct[i].d_ino != DIEMPTY )
{ inode = iget( dir.direct[i].d_ino );
di_mode = inode->i_mode;
if( di_mode & DIDIR )
{ printf( " d" ); // 目录文件
printf("\t\t");
dirnum++;
}
else
{ printf( " -" ); // 普通文件
printf("\t\t");
filenum++;
}
// 显示读写执行权限
for( j = 0; j < 3; j++ )
{ if( di_mode % 2 )
printf( "r" ); // 读权限
else
printf( "-" );
di_mode = di_mode / 2;
if( di_mode % 2 ) // 写权限
printf( "w" );
else
printf( "-" );
di_mode = di_mode / 2;
if( di_mode % 2 ) // 执行权限
printf( "x" );
else
printf( "-" );
di_mode = di_mode / 2;
}
printf( " %d %d %d %s\n", // 分别显示文件主uid,gid,文件大小和文件名
inode->i_uid, inode->i_gid, inode->i_size, dir.direct[i].d_name );
iput( inode );
}
}
textcolor(7);
printf("===========================================================\n");
printf("\n\t┄┄┄┄┄┄┄┄┄系统信息┄┄┄┄┄┄┄┄┄\n");
textcolor(11);
printf( "\n %d files\n", filenum); // 显示文件数
printf( " %d directories\n", dirnum); // 显示目录数
textcolor(7);
printf("\t┄┄┄┄┄┄┄┄┄ END ┄┄┄┄┄┄┄┄┄\n");
}
//创建目录函数:mkdir
void mkdir( char * dirname )
{ int i, dirid, dirpos;
struct inode * inode, * pre_inode;
struct dir tempdir;
struct direct buf[BLOCKSIZ / DIRECTSIZ];
unsigned int block;
dirid = namei( dirname );
if( dirid == -1 )
{ textcolor(12);
printf( "mkdir: cannot make directory '%s': No such file or directory\n", dirname );
textcolor(7);
return;
}
if( dirid != NULL )
{ textcolor(12);
printf( "mkdir: cannot make directory '%s': File exists\n", dirname );
textcolor(7);
return;
}
inode = ialloc();
dirid = inode->i_ino;
if( pre_dinodeid == cur_path_inode->i_ino ) // 如果所要创建的目录的父目录为当前目录
{
dirpos = iname( dir, end_path_name );
strcpy( dir.direct[dirpos].d_name, end_path_name );
dir.direct[dirpos].d_ino = dirid;
dir.size++;
}
else // 所要创建的目录的父目录不是当前目录
{ tempdir = getdir( pre_dinodeid, " " );
dirpos = iname( tempdir, end_path_name );
strcpy( tempdir.direct[dirpos].d_name, end_path_name );
tempdir.direct[dirpos].d_ino = dirid;
tempdir.size++;
putdir( pre_dinodeid, tempdir );
}
for( i = 0; i < BLOCKSIZ / DIRECTSIZ; i++ )// 初始化缓冲区
{ buf[i].d_ino = 0;
strcpy( buf[i].d_name, " " );
}
// 把新建的目录内容写入缓冲区
strcpy( buf[0].d_name, ".." );
buf[0].d_ino = pre_dinodeid;
strcpy( buf[1].d_name, "." );
buf[1].d_ino = dirid;
// 写磁盘i节点相关信息
inode->i_size = 2 * DIRECTSIZ;
inode->i_number = 1;
inode->i_mode = DEFAULTMODE | DIDIR;
inode->i_uid = user[user_id].u_uid;
inode->i_gid = user[user_id].u_gid;
block = balloc();
inode->i_addr[0] = block;
bwrite( block, buf );// 把缓冲区内容写入新分配的盘块中
iput( inode );
}
// 改变目录函数:chdir()
void chdir( char * dirname )
{ unsigned int dirid;
char buf[DIRSIZ];
int i, len;
dirid = namei( dirname ); // 获得当前目录的磁盘i节点号
if(( dirid == NULL ) || ( dirid == -1 )) // 没有该目录
{ textcolor(12);
printf( "bash: %s: No such file or directory\n",dirname );
textcolor(7);
return;
}
len = strlen( dirname );
while( len )
{ i = 0;
while( len )
{
buf[i] = * dirname;
if( buf[i] == '/' )
{
buf[i] = '\0';
dirname++;
len--;
break;
}
i++;
dirname++;
len--;
}
if( !len )
buf[i] = '\0';
if( buf[0] == '\0' )
{
buf[0] = '/';
buf[1] = '\0';
}
putdir( cur_path_inode->i_ino, dir ); // 把当前目录写回到磁盘
iput( cur_path_inode );
dir = getdir( dirid, buf ); // 取得所要进入的目录的目录结构
cur_path_inode = iget( dirid );
if( strcmp( buf, "/" ) == 0 )
cur_dir_id = 0;
else if( strcmp( buf, ".." ) == 0 )
{if( cur_dir_id )
cur_dir_id--;
}
else if( strcmp( buf, "." ) != 0 )
{
cur_dir_id++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -