📄 command.c~
字号:
/* command.c */
#include "command.h"
struct sh_command entry[] = {
{ "exit", 1, "", "exit this program"},
{ "echo", 2, "word", "echo words"},
{ "help", 3, "", "print this message"},
{ "mkdir", 4, "dir", "make dir"},
{ "mkfile", 5, "file (size)", "make file, init size"},
{ "ls", 6, "", "list files and dirs"},
{ "date", 7, "", "print date and time"},
{ "cd", 8, "(path)", "change dir"},
{ "status", 9, "", "show filesystem status"},
{ "rm", 10, "file", "remove file"},
{ "rn", 11, "file1 file2", "rename file1 to file2"},
{ "pwd", 12, "", "print full path"}, {"open", 13,"file", "open file"},
{ "ZZZZ", 0, "", ""}};//0项是标志结束的
/* split the given argv, then return the certain one. */
//argc==1 表示在输入命令行中以空格隔开的第一个字符串
char* pick_arg( int argc, char *argv)
{
int i, catch_len, step;
char work_path[MAX_COMMAND_LEN], token[]=" ", *file, *ptr;//命令同空格符隔开
strcpy( work_path, argv);
for( step = 1, catch_len=0, ptr=work_path;
catch_len<strlen(work_path);
ptr++, step++)
{
strcpy( argv, ptr);//更新argv的值,把读过的命令过滤
file = strtok( argv, token);//提取下一个命令
if(step == argc)
return file;
for( i=0; i<strlen(file); i++)//字符串指针的位置要跳过该命令的长度
ptr++;
catch_len = catch_len + strlen(file) +1;
}
return NULL;
}
/* parser the command to relative programs. */
//第二第三个参数表示是在创建的文件系统中,指明在哪个目录下执行的
void processor( const char *command, FILE *fp, int *pd_ind_no, char *path)
{
char argv1[MAX_COMMAND_LEN], argv2[MAX_COMMAND_LEN];
strcpy( argv1, command);
strcpy( argv2, command);
int i;
for( i=0; entry[i].no != 0; i++){
//查找command与命令行的第一个字符串相同的项,即判断是何种命令
if(!strcmp( entry[i].com, pick_arg( 1, argv1))){
strcpy( argv1, command);
strcpy( argv2, command);
switch(entry[i].no){
case 1: printf("Goodbye user. Logout in " __DATE__ " " __TIME__".\n");exit(1);break;
case 2: printf("%s\n", pick_arg( 2, argv1)); break;
case 3: help(); break;
case 4: create_fd( fp, *pd_ind_no, pick_arg(2,argv1), 'd', "0"); break;//创建目录
case 5: create_fd( fp, *pd_ind_no, pick_arg(2,argv1), 'f', pick_arg(3,argv2)); break;//创建文件
case 6: list_dir( fp, *pd_ind_no); break;
case 7: printf(__DATE__ " " __TIME__ "\n"); break;
case 8: if(cd_path( fp, pd_ind_no, pick_arg( 2, argv1)) != -1) list_dir( fp, *pd_ind_no); break;
case 9: status(fp); break;
case 10: remove_fd( fp, *pd_ind_no, pick_arg( 2, argv1)); break;
case 11: re_name( fp, *pd_ind_no, pick_arg(2,argv1), pick_arg(3,argv2)); break;
case 12: printf("%s\n", path); break; case 13: open_file(fp,*pd_ind_no,pick_arg(2,argv1));break;
}
}
} /* end of for */
}
void open_file(FILE*fp,int dir_ind_no,char* file){ int file_ind_no; struct fs_inode file_node; if((file_ind_no=fd_exist(fp, dir_ind_no, file)) == -1) { /* if f1 do not exist */
fprintf( stderr, "%s have not exist!\n", file);
return;
} file_node = find_inode( fp, file_ind_no); fprintf(stdout,"blocks:%d\n",file_node.size);}
/* else read the dir's entries and print it one by one. */
void list_dir( FILE *fp, int dir_ind_no)
{
char *type, *file="file", *dir="dir";
int blk_no;
long offset;
struct fd_entry entry;
struct fs_inode dir_inode, tmp_inode;
dir_inode = find_inode( fp, dir_ind_no);//找到目录的inode
printf("%-5s %-5s %-5s %-5s %-5s %-5s\n",
"type", "user", "size", "name", "inode", "blocks");
for( offset=0; offset<dir_inode.size; offset+=sizeof(entry)){
//读取一条inode表项
blk_no = blk_map( fp, dir_ind_no, offset);
fseek( fp, (SEEK_BLK(blk_no) + (offset%BLOCK_SIZE)), SEEK_SET);
fread( &entry, sizeof(entry), 1, fp);
tmp_inode = find_inode( fp, entry.inode_no);//由该条inode表项的inode号找到该inode
if(tmp_inode.type == 'd')
type = dir;
else
type = file;
/* type, user, size, name, inode, blocks */
printf("%-5s %-5s %-5d %-7s %-7d", type, tmp_inode.user,
tmp_inode.size, entry.name, entry.inode_no,SEEK_BLK(tmp_inode.addr[0]));
int offset;
for( offset=0; offset<=tmp_inode.size; offset+=BLOCK_SIZE){//列出所占的磁盘块
printf("%d ", blk_map( fp, entry.inode_no, offset));
}
printf("\n");
}
return;
}
//打开指定目录
int cd_path( FILE *fp, int *pd_ind_no, char *given_path)
{
char work_path[PATH_LEN];
if(given_path == NULL)
strcpy( work_path, ".");
else
strcpy( work_path, given_path);
int tmp_ind_no = *pd_ind_no;
if(work_path[0] == '/') /* root inode */
*pd_ind_no = STACK_MAX - 1;
int i, catch_len;
char token[]="/", tmp_path[PATH_LEN], *file, *ptr;
struct fs_inode file_inode;
for( catch_len=0, ptr=work_path; catch_len<strlen(work_path); ptr++){
strcpy( tmp_path, ptr); /* copy the rest component to tmp from ptr */
file = strtok( tmp_path, token);
if((*pd_ind_no=fd_exist( fp, *pd_ind_no, file)) == -1){//查找该目录是否存在,记下目录所在的inode号
fprintf( stderr, "%s does not exist!\n", file);
*pd_ind_no = tmp_ind_no;
return -1; /* if no this file */
}
file_inode = find_inode( fp, *pd_ind_no);
if(file_inode.type != 'd'){//如果找到的不是一个目录,则出错
fprintf( stderr, "%s is not a dir!\n", file);
*pd_ind_no = tmp_ind_no;
return -1;
}
for( i=0; i<strlen(file); i++) /* update the ptr and catch_len */
ptr++;//路径名字符串向前移strlen(file)个长度
catch_len = catch_len + strlen(file) + 1;
}//当每一个‘/’都打开后,就到了我们要找开的目录
return *pd_ind_no;
}
void help()
{
printf("All commands list here, some support\n"
"arguments. Arguments which follows ()\n"
"means omitted to the default.\n\n"
"COMMAND PATAMETER DESCRIPTION\n");
int i;
for( i=0 ; entry[i].no > 0; i++)
printf( "%-8s %-12s %-s\n", entry[i].com, entry[i].argv, entry[i].description);
}
/* print the filesystem's status */
void status( FILE *fp)
{
struct fs_super super;
fseek( fp, sizeof(struct fs_boot), SEEK_SET);
fread( &super, sizeof(super), 1, fp);
int i;
printf("filesystem usage : %f%%\n",
(double)(super.total_block_count - super.free_block_count) / (double)super.total_block_count);
printf("total block count: %d\n", super.total_block_count);
printf("free block count : %d\n", super.free_block_count);
printf("free inode count : %d\n", super.free_inode_count);
printf("remembered inode : %d\n", super.remembered_inode);
printf("free block stack : \n");
for( i=1; i<=super.free_block_stack[0]; i++){
printf("%3d ", super.free_block_stack[i]);
if(i % 12 == 0)
printf("\n");
}
printf("\n");
printf("free inode stack : \n");
for( i=1; i<=super.free_inode_stack[0]; i++){
printf("%3d ", super.free_inode_stack[i]);
if(i % 12 == 0)
printf("\n");
}
printf("\n");
}
void re_name( FILE *fp, int dir_ind_no, char *f1, char *f2)
{
int file_ind_no;
if(f1 == NULL || f2 == NULL){
fprintf( stderr, "invalid command, please see help in detail.\n");
return;
}
else if((file_ind_no=fd_exist(fp, dir_ind_no, f1)) == -1){ /* if f1 do not exist */
fprintf( stderr, "%s have not exist!\n", f1);
return;
}
else if(fd_exist(fp, dir_ind_no, f2) != -1){ /* if f2 have exist */
fprintf( stderr, "%s have exist!\n", f2);
return;
}
else if(!strcmp(f1,".") || !strcmp(f1,"..") ||
!strcmp(f2,".") || !strcmp(f2,".."))
{
fprintf( stderr, "invalid command!\n");
return;
}
int blk_no;
long offset;
struct fd_entry file_entry;
struct fs_inode dir_inode = find_inode( fp, dir_ind_no);
for( offset=2*sizeof(file_entry); offset<dir_inode.size; offset+=sizeof(file_entry)){
//开始时offset=2*sizeof(file_entry)是为了跳过"."和".."索引
blk_no = blk_map( fp, dir_ind_no, offset);
fseek( fp, (SEEK_BLK(blk_no) + offset%BLOCK_SIZE), SEEK_SET);//找到该索引所在的具体地址
fread( &file_entry, sizeof(file_entry), 1, fp);//读出该索引
if(!strcmp( f1, file_entry.name)){ /* locate file */
strcpy( file_entry.name, f2);//修改索引中的名字项
fseek( fp, (SEEK_BLK(blk_no) + offset%BLOCK_SIZE), SEEK_SET);
fwrite( &file_entry, sizeof(file_entry), 1, fp);//写回索引
return;
}
}
}
/* recurse to parent dir, until reach the root. */
void pwd( FILE *fp, int *pd_ind_no, char *path)
{
int stack[STACK_MAX], i, current_ind = *pd_ind_no;
stack[0] = *pd_ind_no; /* current ind */
//一直找到根目录
for( i=1; i<STACK_MAX && (fd_exist(fp,*pd_ind_no,".")!=fd_exist(fp,*pd_ind_no,"..")); i++){
*pd_ind_no = fd_exist( fp, *pd_ind_no, "..");
stack[i] = *pd_ind_no;
}
struct fd_entry file_entry;
if(i == 1){//如果是在根目录下
strcpy( path, "/");
*pd_ind_no = current_ind;
return;
}
else{//如果不是在根目录下,记录路径全名
strcpy( path, "");
for( i--; i>0; i--){
file_entry = find_entry( fp, stack[i], stack[i-1]);
strcat( path, "/");
strcat( path, file_entry.name);
}
*pd_ind_no = current_ind;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -