计算机操作系统汤晓丹版的实验A.7源代码

要求:


具体代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#define umask 18 //0000010010
#define mode_read 256 //0100000000
#define mode_write 128 //0010000000
#define mode_execute 64 //0001000000
/*权限部分:模仿unix的权限,文件创建、文件读写权限检查函数
the / directory is only allowed uid=0 to creat the dire
*/struct f_position
{char dev_name[32];int start_pos;int block_num;int length_bytes;
};struct f_logic_structure
{
//0:stream file; 1:record filechar type;int num_record;
//0:fixed length record; 1:variable length recordchar type_record;
};struct current_use_info
{int num_of_processes;
//0:unlock;1:lockchar locked;char modified;
};/*
struct inode{
int uid;
int gid;
//0:relugar file,1:direcotry file,2:special file
char type;
int privilege;
int addr[13];
int length;
int count;
int time_process;
int time_modified;
int time_inode_modified;
}
*/struct inode
{struct f_position position;struct f_logic_structure f_l_structure;
//0:sequence file,1:chain-connected file,2:index fileint f_physical_structure;int privilege;int date_create;int time_create;int date_modify;int time_modify;struct current_use_info use_info;int f_uid;int f_gid;
};struct fcb
{char file_name[32];struct inode f_inode;
};/*
struct node
{char name[32];struct node *sbiling;struct node *parent;struct node *child;struct fcb pointer_fcb;
//0:directory;1:filechar type;
};
*/
struct node
{char name[32];//-1: no sbilingint sbiling;int parent;int child;struct fcb pointer_fcb;//0:directory;1:filechar type;
};int *unused;
int *fat[260111];
void *other;int uid,gid;int check_permission(struct node *p,int mode){if(uid!=0){int m;m=mode;if(uid==p->pointer_fcb.f_inode.f_uid){if((m&p->pointer_fcb.f_inode.privilege&448)!=m){//user can't write0 010 000 000,448 0111000000return 0;}}else if(gid==p->pointer_fcb.f_inode.f_gid){m = m >>3;if((m&p->pointer_fcb.f_inode.privilege&56)!=m){//user can't write, 0000111000return 0;}}else{m = m >>6;if((m&p->pointer_fcb.f_inode.privilege&7)!=m){//user can't write, 0000000111return 0;}}}return 1;
}
void
directory_read (struct node *p, int first_block);
void
file_write (int first_block, int pos, void *value, int len);int f_chmod(struct node *current_directory,int mode,char name[32]){struct node tmpnode2;directory_read(&tmpnode2,current_directory->child);if(strncmp(tmpnode2.name,name,strlen(tmpnode2.name)>strlen(name)?strlen(tmpnode2.name):strlen(name))==0){int target_node_block;struct node target_node;target_node_block=current_directory->child;memcpy(&target_node,&tmpnode2,sizeof(struct node));//if(uid!=target_node.pointer_fcb.f_inode.f_uid){return -1;//not the owner}else{int privilege;privilege=((mode/100)<<6)+((mode/10%10)<<3)+(mode%10);void *p1,*p2;p1=&target_node;p2=&target_node.pointer_fcb.f_inode.privilege;file_write(target_node_block,p2-p1,&privilege,sizeof(int));return 1;}//}else{int r;r=tmpnode2.sbiling;directory_read(&tmpnode2,r);int target_node_block;struct node target_node;while(1){if(strncmp(tmpnode2.name,name,strlen(tmpnode2.name)>strlen(name)?strlen(tmpnode2.name):strlen(name))==0){target_node_block=r;directory_read(&target_node,r);break;}r=tmpnode2.sbiling;directory_read(&tmpnode2,r);}//未进行错误判断,目录必须存在//if(uid!=target_node.pointer_fcb.f_inode.f_uid){//user can't cdreturn -1;//not the owner}else{int privilege;privilege=((mode/100)<<6)+((mode/10%10)<<3)+(mode%10);void *p1,*p2;p1=&target_node;p2=&target_node.pointer_fcb.f_inode.privilege;file_write(target_node_block,p2-p1,&privilege,sizeof(int));return 1;}//}
}int
directory_create (char directory_name[32], int current_directory_block)
{
//check the permission is allowed?
if(current_directory_block==-1){if(uid!=0){
return -3;//the previlege is not sufficient}
}
else{struct node tmpnode2;directory_read(&tmpnode2,current_directory_block);if(check_permission(&tmpnode2,mode_write)!=1){//user can't write0 010 000 000return -3;}
}
//if ==-1,used for creating the root 
if(current_directory_block!=-1){
struct node tmpnode;
directory_read(&tmpnode,current_directory_block);
if(tmpnode.child!=-1){directory_read(&tmpnode,tmpnode.child);if(strncmp(tmpnode.name,directory_name,strlen(tmpnode.name)>strlen(directory_name)?strlen(tmpnode.name):strlen(directory_name))==0){//this name is same to an existed name, direct childreturn -2;}
while(tmpnode.sbiling!=-1){directory_read(&tmpnode,tmpnode.sbiling);if(strncmp(tmpnode.name,directory_name,strlen(tmpnode.name)>strlen(directory_name)?strlen(tmpnode.name):strlen(directory_name))==0){return -2;}
}
}
}int m;if (sizeof (struct node) % 512 == 0){m = sizeof (struct node) / 512;}else{m = sizeof (struct node) / 512 + 1;}struct node sample_node;if (m <= *unused){//the first 1M is used for FAT//struct node sample_node;memset (&sample_node, 0x00, sizeof (struct node));strncpy (sample_node.name, directory_name, strlen (directory_name));sample_node.sbiling = -1;sample_node.parent = current_directory_block;sample_node.child = -1;sample_node.pointer_fcb.f_inode.privilege=511-umask;//0 111 111 111 - umasksample_node.pointer_fcb.f_inode.f_uid=uid;sample_node.pointer_fcb.f_inode.f_gid=gid;sample_node.type = 0;int i;int m_counter, temp;temp = 0;void *p;p = &sample_node;m_counter = 0;int position;for (i = 0; i < 26011; i++){if (*fat[i] == 0){if (m_counter == 0){//sample_node.pointer_fcb.f_inode.position.start_pos = i;position=i;}if (m == 1){memcpy (other + i * 512, p, sizeof (struct node));*fat[i] = -1;break;}else if (m > 1 && m_counter < m){if (temp != 0){*fat[temp] = i;}temp = i;memcpy (other + i * 512, p, 512);m_counter++;p = p + 512;}else if (m_counter == m){memcpy (other + i * 512, p,sizeof (struct node) - (m - 1) * 512);*fat[i] = -1;break;}else{}}}*unused = *unused - m;//return sample_node.pointer_fcb.f_inode.position.start_pos;return position;}else{//printf ("no enough space.\n");return -1;}
}int
file_node_create (char file_name[32], int current_directory_block)
{
//check permission
if(current_directory_block==-1){if(uid!=0){
return -3;//the previlege is not sufficient
}
}
else{struct node tmpnode2;directory_read(&tmpnode2,current_directory_block);if(check_permission(&tmpnode2,mode_write)!=1){user can't write0 010 000 000return -3;}
}
struct node tmpnode;
directory_read(&tmpnode,current_directory_block);
if(tmpnode.child!=-1){directory_read(&tmpnode,tmpnode.child);if(strncmp(tmpnode.name,file_name,strlen(tmpnode.name)>strlen(file_name)?strlen(tmpnode.name):strlen(file_name))==0){//this name is same to an existed name, direct childreturn -2;}
while(tmpnode.sbiling!=-1){directory_read(&tmpnode,tmpnode.sbiling);if(strncmp(tmpnode.name,file_name,strlen(tmpnode.name)>strlen(file_name)?strlen(tmpnode.name):strlen(file_name))==0){return -2;}
}
}int m;if (sizeof (struct node) % 512 == 0){m = sizeof (struct node) / 512;}else{m = sizeof (struct node) / 512 + 1;}struct node sample_node;if (m <= *unused){//the first 1M is used for FAT//struct node sample_node;memset (&sample_node, 0x00, sizeof (struct node));strncpy (sample_node.name, file_name, strlen (file_name));sample_node.sbiling = -1;sample_node.parent = current_directory_block;sample_node.child = -1;sample_node.pointer_fcb.f_inode.privilege=511-umask;sample_node.pointer_fcb.f_inode.position.length_bytes=0;sample_node.type = 1;int i;int m_counter, temp;temp = 0;void *p;p = &sample_node;m_counter = 0;int position;for (i = 0; i < 26011; i++){if (*fat[i] == 0){if (m_counter == 0){//sample_node.pointer_fcb.f_inode.position.start_pos = i;position=i;}if (m == 1){memcpy (other + i * 512, p, sizeof (struct node));*fat[i] = -1;break;}else if (m > 1 && m_counter < m){if (temp != 0){*fat[temp] = i;}temp = i;memcpy (other + i * 512, p, 512);m_counter++;p = p + 512;}else if (m_counter == m){memcpy (other + i * 512, p,sizeof (struct node) - (m - 1) * 512);*fat[i] = -1;break;}else{}}}*unused = *unused - m;//return sample_node.pointer_fcb.f_inode.position.start_pos;return position;}else{//printf ("no enough space.\n");return -1;}
}//return the file node's block
int file_open(char file_name[32],struct node *current_directory,int current_directory_block){struct node tmpnode;directory_read(&tmpnode,current_directory->child);if(tmpnode.type==1){if(strncmp(tmpnode.name,file_name,strlen(tmpnode.name)>strlen(file_name)?strlen(tmpnode.name):strlen(file_name))==0){return current_directory->child;}}else{int t;t=tmpnode.sbiling;directory_read(&tmpnode,t);while(1){if(tmpnode.type==1){if(strncmp(tmpnode.name,file_name,strlen(tmpnode.name)>strlen(file_name)?strlen(tmpnode.name):strlen(file_name))==0){return t;}}t=tmpnode.sbiling;directory_read(&tmpnode,t);}}
}//the length is 2^16,so 2GB file
int
file_content_create (int file_node_block,char *file_content, int length)
{
//check permission
struct node tmpnode;
directory_read(&tmpnode,file_node_block);
if(check_permission(&tmpnode,mode_write)!=1){user can't write0 010 000 000return -3;
}int m;if (length % 512 == 0){m = length / 512;}else{m = length / 512 + 1;}if (m <= *unused){int i;int m_counter, temp;temp = 0;m_counter = 0;int position;for (i = 0; i < 26011; i++){if (*fat[i] == 0){if (m_counter == 0){struct node sample_node;void *p1,*p2;p1=&sample_node;p2=&sample_node.pointer_fcb.f_inode.position.start_pos;//sample_node.pointer_fcb.f_inode.position.start_pos = i;file_write(file_node_block,p2-p1,&i,sizeof(int));p2=&sample_node.pointer_fcb.f_inode.position.block_num;file_write(file_node_block,p2-p1,&m,sizeof(int));p2=&sample_node.pointer_fcb.f_inode.position.length_bytes;file_write(file_node_block,p2-p1,&length,sizeof(int));position=i;}if (m == 1){memcpy (other + i * 512, file_content, length);*fat[i] = -1;break;}else if (m > 1 && m_counter < m){if (temp != 0){*fat[temp] = i;}temp = i;memcpy (other + i * 512, file_content, 512);m_counter++;file_content = file_content+ 512;}else if (m_counter == m){memcpy (other + i * 512, file_content,length - (m - 1) * 512);*fat[i] = -1;break;}else{}}}*unused = *unused - m;//return sample_node.pointer_fcb.f_inode.position.start_pos;return position;}else{//printf ("no enough space.\n");return -1;}
}int file_append(int file_node_block,char *append_content,int append_length){
struct node file;
directory_read(&file,file_node_block);
int length;
length=file.pointer_fcb.f_inode.position.length_bytes+append_length;int m;if (length % 512 == 0){m = length / 512;}else{m = length / 512 + 1;}m=m-file.pointer_fcb.f_inode.position.block_num;if (m <= *unused){int i;int m_counter;m_counter = 1;int t,y;t=file.pointer_fcb.f_inode.position.start_pos;y=*fat[t];while(y!=-1){t=y;y=*fat[y];}for (i = 0; i < 26011; i++){if (*fat[i] == 0){if (m == 0){break;}else if (m > 0 && m_counter < m){*fat[t] = i;t = i;m_counter++;}else if (m_counter == m){*fat[t] = i;*fat[i] = -1;break;}else{}}}*unused = *unused - m;//return sample_node.pointer_fcb.f_inode.position.start_pos;}else{//printf ("no enough space.\n");return -1;}
file_write(file.pointer_fcb.f_inode.position.start_pos,file.pointer_fcb.f_inode.position.length_bytes,append_content,append_length);
void *p1,*p2;
p1=&file;
p2=&file.pointer_fcb.f_inode.position.block_num;
m=m+file.pointer_fcb.f_inode.position.block_num;
file_write(file_node_block,p2-p1,&m,sizeof(int));
file.pointer_fcb.f_inode.position.block_num=m;
p2=&file.pointer_fcb.f_inode.position.length_bytes;
file_write(file_node_block,p2-p1,&length,sizeof(int));
file.pointer_fcb.f_inode.position.length_bytes=length;
return 0;
}int file_truncate(int file_node_block,int new_length){//check permissionstruct node tmpnode;directory_read(&tmpnode,file_node_block);if(check_permission(&tmpnode,mode_write)!=1){user can't write0 010 000 000return -3;}int m;if(new_length%512==0){m=new_length/512;}if(new_length%512!=0){m=new_length/512+1;}//struct node tmpnode;//directory_read(&tmpnode,file_node_block);int t,y;t=tmpnode.pointer_fcb.f_inode.position.start_pos;int n;n=m;if(m==0){while(*fat[t]!=-1){y=*fat[t];*fat[t]=0;t=y;}*fat[t]=0;tmpnode.pointer_fcb.f_inode.position.block_num=n;void *p1,*p2;p1=&tmpnode;p2=&tmpnode.pointer_fcb.f_inode.position.block_num;file_write(file_node_block,p2-p1,&n,sizeof(int));tmpnode.pointer_fcb.f_inode.position.length_bytes=new_length;p2=&tmpnode.pointer_fcb.f_inode.position.length_bytes;file_write(file_node_block,p2-p1,&new_length,sizeof(int));return 0;}while(m>0){y=t;t=*fat[t];m--;}if(t==-1){//the block num is sametmpnode.pointer_fcb.f_inode.position.length_bytes=new_length;void *p1,*p2;p1=&tmpnode;p2=&tmpnode.pointer_fcb.f_inode.position.length_bytes;file_write(file_node_block,p2-p1,&new_length,sizeof(int));return 0;}else{*fat[y]=-1;while(*fat[t]!=-1){y=*fat[t];*fat[t]=0;t=y;}*fat[t]=0;tmpnode.pointer_fcb.f_inode.position.block_num=n;void *p1,*p2;p1=&tmpnode;p2=&tmpnode.pointer_fcb.f_inode.position.block_num;file_write(file_node_block,p2-p1,&n,sizeof(int));tmpnode.pointer_fcb.f_inode.position.length_bytes=new_length;p2=&tmpnode.pointer_fcb.f_inode.position.length_bytes;file_write(file_node_block,p2-p1,&new_length,sizeof(int));return 0;}
}void
directory_read (struct node *p, int first_block)
{int i;i = 0;int next, current;current = first_block;next = *fat[current];while (1){if (next == -1){memcpy (p + i * 512, other + 512 * current,sizeof (struct node) - i * 512);break;}else{memcpy (p + i * 512, other + 512 * current, 512);i++;current = next;next = *fat[current];}}
}void
file_write (int first_block, int pos, void *value, int len)
{int m = 0, i, written_block_start = first_block;while (pos / 512 > 1){m++;pos = pos - 512;}for (i = 0; i < m; i++){written_block_start = *fat[written_block_start];}while (1){if (len > 512 - pos){memcpy (other + 512 * written_block_start + pos, value, 512 - pos);len = len - (512 - pos);value = value + 512 - pos;pos = 0;written_block_start = *fat[written_block_start];}else{memcpy (other + 512 * written_block_start + pos, value, len);break;}}
}void
file_read (int first_block, int pos, void *s, int len)
{int m = 0, i, read_block_start = first_block;while (pos / 512 > 1){m++;pos = pos - 512;}for (i = 0; i < m; i++){read_block_start = *fat[read_block_start];}while (1){if (len > 512 - pos){memcpy (s, other + 512 * read_block_start + pos, 512 - pos);len = len - (512 - pos);s = s + 512 - pos;pos = 0;read_block_start = *fat[read_block_start];}else{memcpy (s, other + 512 * read_block_start + pos, len);break;}}
}int directory_delete(struct node *current_directory,int current_directory_block,char dirname[32]){//check for permission?if(check_permission(current_directory,mode_write|mode_execute)!=1){//user can't delete th dirreturn -3;}struct node tmpnode;directory_read(&tmpnode,current_directory->child);if(strncmp(tmpnode.name,dirname,strlen(dirname)>strlen(tmpnode.name)?strlen(dirname):strlen(tmpnode.name))==0){int z,tmp;tmp=current_directory->child;void *p1,*p2;p1=&tmpnode;p2=&tmpnode.child;file_write(current_directory_block,p2-p1,&tmpnode.sbiling,sizeof(int));current_directory->child=tmpnode.sbiling;//don't forget to update this always-exist variablewhile(*fat[tmp]!=-1){z=*fat[tmp];*fat[tmp]=0;tmp=z;}*fat[tmp]=0;}else{int t,y;y=current_directory->child;t=tmpnode.sbiling;directory_read(&tmpnode,t);while(strncmp(tmpnode.name,dirname,strlen(dirname)>strlen(tmpnode.name)?strlen(dirname):strlen(tmpnode.name))!=0){y=t;t=tmpnode.sbiling;directory_read(&tmpnode,t);}void *p1,*p2;p1=&tmpnode;p2=&tmpnode.sbiling;file_write(y,p2-p1,&tmpnode.sbiling,sizeof(int));int z;while(*fat[t]!=-1){z=*fat[t];*fat[t]=0;t=z;}*fat[t]=0;}
}int file_delete(char file_name[32],struct node * current_directory,int current_directory_block){//check permissionif(check_permission(current_directory,mode_write|mode_execute)!=1){//user can't delete th filereturn -3;}struct node tmpnode;directory_read(&tmpnode,current_directory->child);if(strncmp(tmpnode.name,file_name,strlen(file_name)>strlen(tmpnode.name)?strlen(file_name):strlen(tmpnode.name))==0){int z,tmp;tmp=current_directory->child;void *p1,*p2;p1=&tmpnode;p2=&tmpnode.child;file_write(current_directory_block,p2-p1,&tmpnode.sbiling,sizeof(int));current_directory->child=tmpnode.sbiling;//don't forget to update this always-exist variable//while(*fat[tmp]!=-1){z=*fat[tmp];*fat[tmp]=0;tmp=z;}*fat[tmp]=0;//then delete the file contentif(tmpnode.pointer_fcb.f_inode.position.length_bytes>0){int tmp_content;tmp_content=tmpnode.pointer_fcb.f_inode.position.start_pos;while(*fat[tmp_content]!=-1){z=*fat[tmp_content];*fat[tmp_content]=0;tmp_content=z;}*fat[tmp_content]=0;}}else{int t,y;y=current_directory->child;t=tmpnode.sbiling;directory_read(&tmpnode,t);while(strncmp(tmpnode.name,file_name,strlen(file_name)>strlen(tmpnode.name)?strlen(file_name):strlen(tmpnode.name))!=0){y=t;t=tmpnode.sbiling;directory_read(&tmpnode,t);}void *p1,*p2;p1=&tmpnode;p2=&tmpnode.sbiling;file_write(y,p2-p1,&tmpnode.sbiling,sizeof(int));int z;while(*fat[t]!=-1){z=*fat[t];*fat[t]=0;t=z;}*fat[t]=0;//then delete the file contentif(tmpnode.pointer_fcb.f_inode.position.length_bytes>0){int t_content;t_content=tmpnode.pointer_fcb.f_inode.position.start_pos;while(*fat[t_content]!=-1){z=*fat[t_content];*fat[t_content]=0;t_content=z;}*fat[t_content]=0;}}
}int cat(char file_name[32],struct node * current_directory,int current_directory_block){int file_node_block;file_node_block=file_open(file_name,current_directory,current_directory_block);struct node tmpnode;file_read(file_node_block,0,&tmpnode,sizeof(struct node));//check permission in fact,need the parent direc has execute privilegeif(check_permission(&tmpnode,mode_read)!=1){//user can't read th filereturn -3;}void *p;p=malloc(tmpnode.pointer_fcb.f_inode.position.length_bytes);file_read(tmpnode.pointer_fcb.f_inode.position.start_pos,0,p,tmpnode.pointer_fcb.f_inode.position.length_bytes);int i;for(i=0;i<tmpnode.pointer_fcb.f_inode.position.length_bytes;i++){printf("%c", *(char *)(p+i));}printf("\n");free(p);
}int test(struct node *current_directory,int current_directory_block){int length=256;int m,n;if (sizeof (struct node) % 512 == 0){m = sizeof (struct node) / 512;}else{m = sizeof (struct node) / 512 + 1;}if (length % 512 == 0){n = length / 512;}else{n = length / 512 + 1;}if(m+n>*unused){//no enough spaceprintf("no enough space\n");return -1;}int file_node_block;file_node_block=file_node_create("test1",current_directory_block);if(file_node_block==-1){return -1;}else if (file_node_block==-2){printf("this name is same to an existed name.\n");return -2;}else if (file_node_block==-3){printf("infufficient privilege.\n");return -3;}else{newdirectory->parent=current_directory_block;if (current_directory->child == -1){struct node tmpnode;void *p1, *p2;p1 = &tmpnode;p2 = &tmpnode.child;file_write (current_directory_block, p2 - p1, &file_node_block,sizeof (int));///directory_read(¤t_directory,current_directory_block);current_directory->child = file_node_block;}else{int tmpnode_block;struct node tmpnode;tmpnode_block = current_directory->child;while (1){directory_read (&tmpnode, tmpnode_block);if (tmpnode.sbiling != -1){tmpnode_block = tmpnode.sbiling;}else{break;}}void *p3, *p4;p3 = &tmpnode;p4 = &tmpnode.sbiling;file_write (tmpnode_block, p4 - p3, &file_node_block, sizeof (int));tmpnode.sbiling = file_node_block;}char file[256];memset(file,0x31,256);int t;t=file_content_create(file_node_block,file,256);if(t==-3){printf("file_content_create(): insufficient privilege\n");return -3;}struct node tt;//这里的file_open不同于linux kernel中的fopenfile_node_block=file_open("test1",current_directory,current_directory_block);file_read(file_node_block,0,&tt,sizeof(struct node));printf("%d\n",tt.pointer_fcb.f_inode.position.length_bytes);char s[32];memset(s,0x32,32);file_append(file_node_block,s,32);file_read(file_node_block,0,&tt,sizeof(struct node));printf("%d\n",tt.pointer_fcb.f_inode.position.length_bytes);if(-3==file_truncate(file_node_block,160)){printf("file_truncate(): insufficient privilege\n");return -3;}file_read(file_node_block,0,&tt,sizeof(struct node));printf("%d\n",tt.pointer_fcb.f_inode.position.length_bytes);return t;}
}main (int argc, char *argv[])
{int fd;fd = open (argv[1], O_RDWR);void *fs;if (fd == -1){
//128M filefs = malloc (134217728);memset (fs, 0x00, 134217728);fd = open (argv[1], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);write (fd, fs, 134217728);close (fd);free (fs);fd = open (argv[1], O_RDWR);}off_t pa_offset;pa_offset = 0 & ~(sysconf (_SC_PAGE_SIZE) - 1);fs =mmap (NULL, 134217728 - pa_offset, PROT_WRITE | PROT_READ, MAP_SHARED, fd,pa_offset);unused = fs - pa_offset;
//452 unused space
//1040444 bytes:fat
//133176832 bytes:fsint i;for (i = 0; i < 260111; i++){fat[i] = fs - pa_offset + 452 + 4 * i;}//here we think format always uses the first block to set the root directory if (*fat[0]==0){*unused = 260111;}other = fs - pa_offset + 452 + 1040444;//struct node *root;int root;//root=fs - pa_offset +452;root = 0;//uid,gid is declared in the globaluid=atoi(argv[2]);gid=0;struct node current_directory;int current_directory_block;if (*unused == 260111){directory_create ("/", -1);}current_directory_block = 0;//directory_read不应该负责权限的检查directory_read (¤t_directory, root);while (1){printf ("newfs>");char option[16];memset (option, 0x00, 16);fgets (option, 16, stdin);
//int i;for (i = 0; i < 15; i++){if (option[i] == '\n'){option[i] = '\0';break;}}if (strncmp (option, "help", 4) == 0){printf("help\n");printf("ls\n");printf("mkdir\n");printf("rmdir\n");printf("cd\n");printf("f_chmod\n");printf("test\n");printf("rm\n");printf("cat\n");printf("format\n");printf("quit\n");continue;}if (strncmp (option, "format", 6) == 0){//to decrease the working load, not the standard procedureif(uid!=0){printf("only uid=0 can format\n");continue;}*unused = 260111;for(i=0;i<260111;i++){if(*fat[i]!=0){*fat[i]=0;}}current_directory_block = 0;directory_create ("/", -1);directory_read (¤t_directory, root);continue;}if (strncmp (option, "ls", 2) == 0){//check pwd +x +r permission?if(check_permission(¤t_directory,mode_read|mode_execute)!=1){//user can't lsprintf("insufficient privilege\n");continue;}//struct node *fsnode;int fsnode, flag = 0;fsnode = current_directory.child;if (fsnode != -1){flag = 1;}while (fsnode != -1){struct node tmpnode;i = 0;int next, current;current = fsnode;next = *fat[fsnode];while (1){if (next == -1){memcpy (&tmpnode + i * 512, other + 512 * current,sizeof (struct node) - i * 512);break;}else{memcpy (&tmpnode + i * 512, other + 512 * current, 512);i++;current = next;next = *fat[current];//memcpy(&tmpnode+i*512,other+512*next,512);}}printf ("%s\t", tmpnode.name);fsnode = tmpnode.sbiling;}if (flag == 1){printf ("\n");}continue;}if (strncmp (option, "cd", 2) == 0)//open.c:428 according to test,only x needs{char dirname2[32];memset (dirname2, 0x00, 32);strncpy (dirname2, option + 3, strlen (option) - 3);if(strncmp(dirname2,"..",2)==0){//check permission? ?int target_directory_block;struct node target_directory;target_directory_block=current_directory.parent;directory_read(&target_directory,target_directory_block);if(check_permission(&target_directory,mode_execute)!=1){//user can't cdprintf("insufficient privilege\n");continue;}current_directory_block=current_directory.parent;memcpy(¤t_directory,&target_directory,sizeof(struct node));continue;}struct node tmpnode2;directory_read(&tmpnode2,current_directory.child);if(tmpnode2.type==0){if(strncmp(tmpnode2.name,dirname2,strlen(tmpnode2.name)>strlen(dirname2)?strlen(tmpnode2.name):strlen(dirname2))==0){int target_directory_block;struct node target_directory;target_directory_block=current_directory.child;memcpy(&target_directory,&tmpnode2,sizeof(struct node));//if(check_permission(&target_directory,mode_execute)!=1){//user can't cdprintf("insufficient privilege\n");continue;}//current_directory_block=target_directory_block;memcpy(¤t_directory,&tmpnode2,sizeof(struct node));continue;}}//this logic should be removed//else{int r;r=tmpnode2.sbiling;directory_read(&tmpnode2,r);int target_directory_block;struct node target_directory;while(1){if(tmpnode2.type==0){if(strncmp(tmpnode2.name,dirname2,strlen(tmpnode2.name)>strlen(dirname2)?strlen(tmpnode2.name):strlen(dirname2))==0){target_directory_block=r;directory_read(&target_directory,r);break;}}r=tmpnode2.sbiling;directory_read(&tmpnode2,r);}//if(check_permission(&target_directory,mode_execute)!=1){//user can't cdprintf("permission insufficient\n");continue;}//current_directory_block=r;memcpy(¤t_directory,&tmpnode2,sizeof(struct node));//未进行错误判断,目录必须存在continue;}if (strncmp (option, "mkdir", 5) == 0){char dirname[32];memset (dirname, 0x00, 32);strncpy (dirname, option + 6, strlen (option) - 6);int newnode;newnode = directory_create (dirname, current_directory_block);if(newnode==-1){printf("no enough space.\n");continue;}if(newnode==-2){printf("this name is same to an existed name.\n");continue;}if(newnode==-3){printf("insufficient privilege.\n");continue;}newdirectory->parent=current_directory_block;if (current_directory.child == -1){void *p1, *p2;p1 = ¤t_directory;p2 = ¤t_directory.child;file_write (current_directory_block, p2 - p1, &newnode,sizeof (int));///directory_read(¤t_directory,current_directory_block);current_directory.child = newnode;}else{int tmpnode_block;struct node tmpnode;tmpnode_block = current_directory.child;while (1){directory_read (&tmpnode, tmpnode_block);if (tmpnode.sbiling != -1){tmpnode_block = tmpnode.sbiling;}else{break;}}void *p3, *p4;p3 = &tmpnode;p4 = &tmpnode.sbiling;file_write (tmpnode_block, p4 - p3, &newnode, sizeof (int));tmpnode.sbiling = newnode;}continue;}if (strncmp (option, "rmdir", 5) == 0){char dirname[32];memset (dirname, 0x00, 32);strncpy (dirname, option + 6, strlen (option) - 6);if(-3==directory_delete(¤t_directory,current_directory_block,dirname)){printf("insufficient privilege!\n");}continue;}if (strncmp (option, "test", 4) == 0){test(¤t_directory,current_directory_block);continue;}if (strncmp (option, "rm", 2) == 0){char file_name[32];memset (file_name, 0x00, 32);strncpy (file_name, option + 3, strlen (option) - 3);if(-3==file_delete(file_name,¤t_directory,current_directory_block)){printf("file_delete(): insufficient privilege\n");}continue;}if (strncmp (option, "cat", 3) == 0){char filename[32];memset (filename, 0x00, 32);strncpy (filename, option + 4, strlen (option) - 4);if(cat(filename,¤t_directory,current_directory_block)==-3){printf("cat(): insufficient privilege\n");}continue;}if(strncmp(option,"f_chmod",7)==0){char *p1,*p2;p1=strchr(option,' ');p1++;// is modep2=strrchr(option,' ');memset(p2,0x00,1);p2++;// is node's nameif(-1==f_chmod(¤t_directory,atoi(p1),p2)){printf("not the owner.\n");}continue;}if (strncmp (option, "su", 2) == 0){char id[6];memset (id, 0x00, 6);strncpy (id, option + 3, strlen (option) - 3);uid=atoi(id);continue;}if (strncmp (option, "quit", 4) == 0){break;}}munmap (fs, 134217728 - pa_offset);close (fd);
}

说明:按照题目要求,支持mkdir
rmdir
cd
rm
ls
文件的打开、读、写、删除、追加、
为了测试多用户,增加了f_chown(模仿linux中的chown,因为stat.h中有chown()函数,不能重名,所以改名为f_chown),su
具体使用,
./prog 用来测试的文件名(如果没有,会自动创建) 用户id
test是一个测试文件操作的测试函数
内置命令的使用说明:
rm rmdir cd命令不要输入不存在文件名,否则程序会报错
fchown:f_chown 777 文件名 (这里的权限位与linux一样)
su: su id,将全局uid切换成id

本文链接:https://my.lmcjl.com/post/10667.html

展开阅读全文

4 评论

留下您的评论.