⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 command.c~

📁 操作系统课程设计
💻 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 + -