/*递归删除文件夹*/ int del_file(int inode, char* name, int deepth) { int child, i, t; Inode temp; if (!strcmp(name, ".") || !strcmp(name, "..")) { /*不允许删除.和..*/ printf("rmdir: failed to remove '%s': Invalid argument\n", name); return -1; } child = check_name(inode, name); /*读取当前子目录的Inode结构*/ fseek(Disk, InodeBeg + sizeof(Inode)*child, SEEK_SET); fread(&temp, sizeof(Inode), 1, Disk); if (temp.type == File) { /*如果是文件则释放相应Inode即可*/ free_inode(child); /*若是最上层文件,需调整目录*/ if (deepth == 0) { adjust_dir(name); } return 1; } else { /*否则进入子目录*/ enter_child_dir(inode, name); } for (i = 2; i<dir_num; ++i) { del_file(child, dir_table[i].name, deepth + 1); } enter_child_dir(child, "..");//返回上层目录 free_inode(child); if (deepth == 0) { /*删除自身在目录中的内容*/ if (dir_num / DirPerBlk != (dir_num - 1) / DirPerBlk) { /*有磁盘块可以释放*/ curr_inode.blk_num--; t = curr_inode.blk_identifier[curr_inode.blk_num]; free_blk(t);//释放相应的磁盘块 } adjust_dir(name);//因为可能在非末尾处删除,因此要移动dir_table的内容 }/*非初始目录直接释放Inode*/ return 1; }
int eat_path(char* name) { int tmp = inode_num;//记录原始inode节点 char dst[30][NameLength]; int cnt = split(dst, name, "/"); if (name[0] == '/') {//从根目录开始 //printf("1111111111\n"); close_dir(inode_num); inode_num = 0; open_dir(inode_num); } for (int i = 0; i < cnt - 1; i++) { //printf("%d\n", i); int res = enter_child_dir(inode_num, dst[i]); if (res == -1) { inode_num = tmp; open_dir(inode_num); return -1; } } if (cnt == 0) strcpy(name, "."); else strcpy(name, dst[cnt - 1]); return 0; }
int enter_dir(char* name) { int tmp = inode_num;//记录原始inode节点 char tmpPath[40], nameCopy[30]; char dst[30][NameLength]; strcpy(tmpPath, path); strcpy(nameCopy, name); int cnt = split(dst, nameCopy, "/"); if (name[0] == '/') {//从根目录开始 //printf("1111111111\n"); close_dir(inode_num); inode_num = 0; open_dir(inode_num); strcpy(path, "monitor@root:"); } for (int i = 0; i < cnt; i++) { //printf("%d\n", i); int res = enter_child_dir(inode_num, dst[i]); change_path(dst[i]); if (res == -1) { inode_num = tmp; open_dir(inode_num); strcpy(path, tmpPath); return -1; } } return 0; }
int file_move(char* name, char* mvname) { int originalInode = inode_num;//记录当前的inode int source_inode_num, dest_inode_num; int inode;//原文件的inode char originalNamePath[30]; char originalMvNamePath[30]; strcpy(originalNamePath, name); strcpy(originalMvNamePath, mvname); if (eat_path(name) == -1) { printf("mv: cannot stat ‘%s’: No such file or directory\n", originalNamePath); return -1; } if (type_check(name) != File) { printf("mv: cannot move '%s': Not a file or no exist\n", originalNamePath); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } source_inode_num = inode_num;//记录原文件的父目录节点 close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 if (eat_path(mvname) == -1) { printf("mv: cannot stat ‘%s’: No such file or directory\n", originalMvNamePath); return -1; } dest_inode_num = inode_num;//记录目标目录的父目录节点 if (source_inode_num == dest_inode_num && strcmp(name, mvname) == 0) { printf("mv: '%s' and '%s' are the same file\n", originalNamePath, originalMvNamePath); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } Inode temp; /*读取原文件目录的inode节点,判断该目录是否可写*/ fseek(Disk, InodeBeg + sizeof(Inode)*source_inode_num, SEEK_SET); fread(&temp, sizeof(Inode), 1, Disk); if (temp.access[1][user_num] == 0) { //原文件目录不可写 if (type_check(mvname) == Directory) printf("mv: cannot move ‘%s’ to ‘%s/%s’: Permission denied\n", originalNamePath, originalMvNamePath, name); else printf("mv: cannot move ‘%s’ to ‘%s’: Permission denied\n", originalNamePath, originalMvNamePath); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } /*形如:mv a.txt b.txt*/ if (type_check(mvname) == -1) { //如果b.txt不存在 /*读取b.txt的父目录的inode,判断是否可写*/ fseek(Disk, InodeBeg + sizeof(Inode)*dest_inode_num, SEEK_SET); fread(&temp, sizeof(temp), 1, Disk); if (temp.access[1][user_num] == 0) { //b.txt的父目录不可写 printf("mv: cannot move ‘%s’ to ‘%s’: Permission denied\n", originalNamePath, originalMvNamePath); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } if (source_inode_num == dest_inode_num) {//如果b.txt不存在,且a.txt 与 b.txt 在同一父目录下,则相当于a.txt重命名 for (int pos = 0; pos < dir_num; ++pos) { if (strcmp(dir_table[pos].name, name) == 0) strcpy(dir_table[pos].name, mvname); } } else {//如果b.txt不存在,且a.txt 与 b.txt 不在同一父目录下,则将a.txt的目录项删除,创建b.txt的目录项指向a.txt的inode inode_num = source_inode_num; open_dir(source_inode_num);//返回a.txt父目录位置 inode = check_name(inode_num, name); adjust_dir(name);//删除a.txt的目录项 close_dir(inode_num); inode_num = dest_inode_num; open_dir(dest_inode_num);//返回b.txt父目录位置 strcpy(dir_table[dir_num].name, mvname); dir_table[dir_num++].inode_num = inode; } } else if (type_check(mvname) == File) {//如果b.txt为文件 if (source_inode_num == dest_inode_num) {//若b.txt 与 a.txt在同一父目录下,则删除b.txt的目录项,同时将a.txt的目录项重命名 adjust_dir(mvname); //b.txt 与 a.txt在同一父目录下,则b.txt的父目录权限在前面已经判断,是可写的 for (int pos = 0; pos < dir_num; ++pos) { if (strcmp(dir_table[pos].name, name) == 0) strcpy(dir_table[pos].name, mvname); } } else {//b.txt 已经存在 且 a.txt与b.txt不在同一目录,则将a.txt的目录项删除,修改b.txt的目录项指向a.txt的inode inode_num = source_inode_num; open_dir(source_inode_num);//返回a.txt父目录位置 inode = check_name(inode_num, name); adjust_dir(name);//删除a.txt的目录项 close_dir(inode_num); inode_num = dest_inode_num; open_dir(dest_inode_num);//返回b.txt父目录位置 for (int pos = 0; pos < dir_num; ++pos) { if (strcmp(dir_table[pos].name, mvname) == 0) dir_table[pos].inode_num = inode; } } } else { //如果b.txt为目录 if (source_inode_num == dest_inode_num && strcmp(mvname, ".") == 0) { printf("mv: '%s' and '%s/%s' are the same file\n", originalNamePath, originalMvNamePath, name); return -1;//移动到本目录下,即不需要移动 } //如果b.txt是目录项,进入b.txt目录中,创建一个目录项指向a.txt, 再将a.txt的目录项删除, inode_num = source_inode_num; open_dir(source_inode_num);//返回a.txt父目录位置 inode = check_name(inode_num, name);//记录a.txt的inode close_dir(inode_num); inode_num = dest_inode_num; open_dir(dest_inode_num);//返回b.txt父目录位置 enter_child_dir(inode_num, mvname); if (check_name(inode_num, mvname) == -1) { //b.txt目录下不存在与a.txt重名的项目,则创建一个目录项指向a.txt /*读取b.txt的inode,判断是否可写*/ fseek(Disk, InodeBeg + sizeof(Inode)*inode_num, SEEK_SET); fread(&temp, sizeof(Inode), 1, Disk); if (temp.access[1][user_num] == 0) { //b.txt不可写 printf("mv: cannot move ‘%s’ to ‘%s/%s’: Permission denied\n", originalNamePath, originalMvNamePath, name); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } strcpy(dir_table[dir_num].name, name); dir_table[dir_num++].inode_num = inode; } else { //b.txt目录下存在与a.txt重名的项目,修改该项目的目录项指向a.txt的inode dir_table[check_name(inode, mvname)].inode_num = inode; } close_dir(inode_num); inode_num = source_inode_num; open_dir(source_inode_num);//返回a.txt父目录位置 inode = check_name(inode_num, name); adjust_dir(name);//删除a.txt的目录项 } close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return 0; }
int file_copy(char* name, char* cpname) { int originalInode = inode_num;//记录当前的inode int source_inode_num, dest_inode_num; char originalNamePath[30]; char originalCpNamePath[30]; strcpy(originalNamePath, name); strcpy(originalCpNamePath, cpname); if (eat_path(name) == -1) { printf("cp: cannot stat ‘%s’: No such file or directory\n", originalNamePath); return -1; } if (type_check(name) != File) { printf("cp: cannot copy '%s': Not a file\n", originalNamePath); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } if (file_read(name) == -1) {//若原文件不可读 printf("cp: cannot open '%s' for reading: Permission denied\n", originalNamePath); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } source_inode_num = inode_num;//记录原文件的父目录节点 close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 if (eat_path(cpname) == -1) { printf("cp: cannot stat ‘%s’: No such file or directory\n", originalCpNamePath); return -1; } dest_inode_num = inode_num;//记录目标目录的父目录节点 if (source_inode_num == dest_inode_num && strcmp(name, cpname) == 0) { printf("cp: '%s' and '%s' are the same file\n", originalNamePath, originalCpNamePath); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } Inode temp; /*将原文件拷贝到另一文件中*/ if (type_check(cpname) != Directory) { if (check_name(inode_num, cpname) != -1) {//目标文件已经存在,则将数据拷贝进去 if (file_write(cpname) == -1) { //若目标文件不可写 printf("cp: cannot create regular file‘%s’: Permission denied\n", originalCpNamePath); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } } else { //目标文件不存在,创建文件,并将数据拷贝进去 /*读取目标目录的inode节点,判断该目录是否可写*/ fseek(Disk, InodeBeg + sizeof(Inode)*dest_inode_num, SEEK_SET); fread(&temp, sizeof(Inode), 1, Disk); if (temp.access[1][user_num] == 0) { //目标目录不可写 printf("cp: cannot create regular file ‘%s’: Permission denied\n", originalCpNamePath); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } make_file(inode_num, cpname, File); file_write(cpname);//将数据从BUFF写入文件 } } /*将原文件拷贝到某个子目录下,包括当前目录(.), 原目录的父目录(..)*/ else { if (source_inode_num == dest_inode_num && strcmp(cpname, ".") == 0) {//将当前目录下的某个文件复制到当前目录,提示已经存在 printf("cp: '%s' and '%s/%s' are the same file\n", originalNamePath, originalCpNamePath, name); return -1; } enter_child_dir(inode_num, cpname);//进入子目录或父目录 /*记录原目录名*/ int pos = strlen(path) - 1; for (; pos >= 0; --pos) { if (path[pos] == '/') { break; } } char curDirName[30]; int i = 0; for (pos = pos + 1; pos <= strlen(path); ++pos) curDirName[i++] = path[pos]; //printf("%s\n", curDirName); if (check_name(inode_num, name) != -1) {//是否已有同名文件 file_write(name);//将数据从BUFF写入文件 } else { /*读取目标目录的inode节点,判断该目录是否可写*/ fseek(Disk, InodeBeg + sizeof(Inode)*inode_num, SEEK_SET); fread(&temp, sizeof(Inode), 1, Disk); if (temp.access[1][user_num] == 0) { //目标目录不可写 printf("cp: cannot create regular file ‘./%s’: Permission denied\n", name); close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return -1; } make_file(inode_num, name, File); file_write(name);//将数据从BUFF写入文件 } /*返回原目录*/ if (strcmp(cpname, "..") == 0) enter_child_dir(inode_num, curDirName);//如果复制到父目录,则复制完返回原目录 else enter_child_dir(inode_num, "..");//如果复制到子目录,则复制完返回到子目录的".."目录,即原目录 } close_dir(inode_num); inode_num = originalInode; open_dir(inode_num);//返回操作前的目录位置 return 0; }