Beispiel #1
0
/*
新建文件:
1.分配inode,设置imap
2.分配data_sector,设置smap
3.新建目录项,更新目录项内容(inode_index,filename)
4.新建inode,更新inode的内容
*/
static int create_file(const char *dir_name,const char *file_name,int file_type){
    int inode_index=alloc_imap_bit(0);
    if(inode_index<0){
        set_error_index(IMAP_NOT_ENOUGH);
        return -1;
    }
#ifdef DEBUG_FS
    printl("inode_index=%d(in create_file)\n",inode_index);
#endif

    int data_index=alloc_smap_bit(0,DEFAULT_FILE_SECTOR_LENGTH);//相对于数据区的sector_index
    if(data_index<0){
        set_error_index(SMAP_NOT_ENOUGH);
        return -1;
    }
#ifdef DEBUG_FS
    printl("data_index=%d(in create_file)\n",data_index);
#endif
    data_index+=get_data_block_first_index(super_block);//绝对sector_index
#ifdef DEBUG_FS
    printl("data_index=%d(in create_file)\n",data_index);
#endif


    if(!new_dir_entry(dir_name,inode_index,file_name)){
        set_error_index(DIR_CREATE_ERROR);
        return -1;
    }

    if(!new_inode(inode_index,file_type,data_index,DEFAULT_FILE_SECTOR_LENGTH)){
        set_error_index(INODE_CREATE_ERROR);
        return -1;
    }
    return inode_index;
}
Beispiel #2
0
// callback : have received a Pdu from the target host with given read comm str
// this is really simplistic, but gives the general idea
int agent_impl::handle_get( Pdu &pdu, UdpTarget &target)
{
  ACE_TRACE("agent_impl::handle_get");
  OctetStr mgr_rd_str, agent_rd_str;
  target.get_read_community(mgr_rd_str); // requster's read community string
  tgt_.get_read_community(agent_rd_str); // this agent's read community string

  //  1. verify we have a valid read string else drop pdu (no response to caller)
  if (mgr_rd_str != agent_rd_str) {
     ACE_DEBUG((LM_DEBUG, "agent_impl::handle_get: invalid read community recvd\n"));
     return 0;
  }

  // 2. iterate over each varbind in the pdu, filling providing responses
  int fdone = 0;
  for (int i = 0; (i < pdu.get_vb_count()) && !fdone; i++) {
    Vb vb;
    pdu.get_vb(vb, i);
    if (get_response(vb)) { // set a value for the oid if we can else
      set_error_status(&pdu, SNMP_ERROR_NO_SUCH_NAME); // these ought to be member
      set_error_index(&pdu, i); // functions but are not yet...
      fdone++; // trigger flag to exit loop early
    }
    else // failed, return noSuch error
      pdu.set_vb(vb, i);
  }

  // 3. lastly, return the pkt to the caller
  return respond(pdu, target);
}
Beispiel #3
0
// return a pdu from a buffer
int wpdu::get_pdu(Pdu& pdu, snmp_version& version)
{
  if (iovec_.iov_len == 0)
    return -1; // NO DATA

  snmp_pdu *raw_pdu;
  raw_pdu = cmu_snmp::pdu_create(0);
  if (!raw_pdu) {
    return SNMP_CLASS_RESOURCE_UNAVAIL;
  }

  // max value a client can send us - TODO: replace this with an
  // api to get actual string length
  int status = cmu_snmp::parse( raw_pdu, (unsigned char *)iovec_.iov_base,
                     community_name, comm_len,
                     version, iovec_.iov_len);
  if (status != 0)
    return SNMP_CLASS_INTERNAL_ERROR;

  community_name[comm_len] = 0; // set null based on returned length
  set_request_id( &pdu, raw_pdu->reqid);
  set_error_status( &pdu, (int) raw_pdu->errstat);
  set_error_index( &pdu, (int) raw_pdu->errindex);
  pdu.set_type( raw_pdu->command);

  if (restore_vbs(pdu, raw_pdu)) {
    cmu_snmp::free_pdu(raw_pdu);
    return SNMP_CLASS_INTERNAL_ERROR;
  }

  cmu_snmp::free_pdu(raw_pdu);
  return 0;
}
Beispiel #4
0
static BOOL do_create(MESSAGE *message){
    const char *path;
    char dirname[MAX_FILENAME_LENGTH]={0};
    char filename[MAX_FILENAME_LENGTH]={0};
    int flags,inode_index;

    path=message->arg_pointer;
    flags=message->flags;

    //分离父目录路径和文件名
    if(!strip_path(path,dirname,filename)){
        return FALSE;
    }

    inode_index=search_file(dirname,filename,GET_FILE_TYPE(flags));
    if(inode_index<0){
        inode_index=create_file(dirname,filename,GET_FILE_TYPE(flags));
        if(inode_index<0){
            return FALSE;
        }
    }
    else{
        set_error_index(FILE_EXIST);
        return FALSE;
    }
    return TRUE;
}
Beispiel #5
0
//有问题:调用的rw_sector中读取数据长度必须为SECTOR_SIZE的整数倍
//该函数还发现一个问题:如果fsbuf为全局静态变量,由于开始读目录内容填充了fsbuf,然后在比较的时候又读取了硬盘,再次填充了fsbuf,导致之前的数据被覆盖。所以fsbuf还是设定成局部变量。
//切忌:尽量减少全局变量的使用。
static int get_inode_by_name(const char *dir_name,const char *file_name,int file_type,INODE *p_inode){
    INODE dir_inode;
    DIR_ENTRY *dir_entry;
    int dir_entry_index;
    int dir_entry_count;
    u8 fsbuf[SECTOR_SIZE*2];
    
    if(get_dir_inode_by_name(dir_name,&dir_inode)<0){
        set_error_index(DIR_NOT_EXIST);
        return -1;
    }
    dir_entry_count=dir_inode.i_size/DIR_ENTRY_SIZE; 

    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (dir_inode.i_start_sector_index)*SECTOR_SIZE,
              dir_inode.i_size,
              TASK_FS,
              fsbuf);

    for(dir_entry_index=0;dir_entry_index<dir_entry_count;dir_entry_index++){
        dir_entry=(DIR_ENTRY *)(fsbuf+dir_entry_index*DIR_ENTRY_SIZE);

/* #ifdef DEBUG_FS */
/*         printl("dir_index=%d dir_name=%s filename=%s cmp=%d\n", */
/*                dir_entry->inode_index, */
/*                dir_entry->name, */
/*                file_name, */
/*                strcmp(dir_entry->name,file_name)==0); */
/* #endif */
        //此处的dir_entry->inode_index=0:表示该文件建立后删除了
        if(dir_entry->inode_index>0 && strcmp(dir_entry->name,file_name)==0){
            if(get_inode_by_index(dir_entry->inode_index,p_inode)){
                if((p_inode->i_mode & file_type) !=0){
                    /* printl("get inode by name data_sector_index=%d\n",p_inode->i_start_sector_index); */
                    return dir_entry->inode_index;
                }
            }
        }
    }
    set_error_index(FILE_NOT_EXIST);
    return -1;
}
Beispiel #6
0
static BOOL do_unlink(MESSAGE *message){
    int inode_index,flags,sector_index,sector_length;
    const char *path;
    char dir_name[MAX_FILENAME_LENGTH]={0};
    char file_name[MAX_FILENAME_LENGTH]={0};
    INODE inode;

    flags=message->flags;
    path=message->arg_pointer;
    //分离父目录路径和文件名
    if(!strip_path(path,dir_name,file_name)){
        return FALSE;
    }
    
    //1.get inode_index,and remove the dir_entry
    inode_index=search_file(dir_name,file_name,GET_FILE_TYPE(flags));
#ifdef DEBUG_FS
    printl("inode_index=%d(in do_unlink)\n",inode_index);
#endif
    if(inode_index<0){
        set_error_index(FILE_NOT_EXIST);
        return FALSE;
    }
    if(!remove_dir_entry(dir_name,inode_index)){
        set_error_index(FILE_NOT_EXIST);
        return FALSE;
    }
    //2.get file inode by inode_index
    get_inode_by_index(inode_index,&inode);
    
    //3.clear imap by inode_index
    free_imap_bit(inode_index);
    
    //4.clear smap inode
    sector_index=inode.i_start_sector_index-get_data_block_first_index(super_block);
    sector_length=inode.i_sectors_length;
    /* printl("sector_index=%d sector_length=%d data_first_index=%d\n",inode.i_start_sector_index,sector_length,get_data_block_first_index(super_block)); */
    free_smap_bit(sector_index,sector_length);
    
    return TRUE;
}
Beispiel #7
0
static BOOL strip_path(const char *path,char *dir_name,char *file_name){
    if(*path!='/'){
        set_error_index(FILE_NAME_ERROR);
        return FALSE;
    }else{
        //获得父目录地址
        *dir_name++=*path++;
        *dir_name=0;
        
        //获得文件名
        while(*path!=0){
            if(*path=='/'){//目前只处理但目录结构
                set_error_index(FILE_NAME_ERROR);
                return FALSE;
            }
            *file_name++=*path++;
        }
        *file_name=0;
        return TRUE;
    }
}
Beispiel #8
0
static void/* int */ do_read(MESSAGE *message){
    char fsbuf[SECTOR_SIZE*DEFAULT_FILE_SECTOR_LENGTH];
    char *buf;
    int start_position,sector_length,length,data_sector_index;
    PROCESS *process;
    struct s_file_descriptor* pfd;

    process=pid2process(message->source_pid);
    pfd=process->file_descriptor[message->fd];
    if((pfd->fd_op_mode & O_RDONLY)==0 && (pfd->fd_op_mode & O_RDWR)==0){
        set_error_index(FILE_CANNOT_READ);
        message->length=-1;
        return;
    }
    buf=message->res_pointer;
    start_position=pfd->fd_position;
    if(start_position > pfd->fd_inode->i_size){
        set_error_index(END_OF_FILE);
        message->length=-1;
        return;
    }
    assert(start_position<=pfd->fd_inode->i_size,"file read over");
    length=min(start_position+message->length,pfd->fd_inode->i_size);
    sector_length=(length+SECTOR_SIZE-1)/SECTOR_SIZE;
    data_sector_index=pfd->fd_inode->i_start_sector_index;
    
    /* printl("data_sector_index=%d sector_length=%d\n",data_sector_index,sector_length); */

    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (data_sector_index)*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              fsbuf);
    strncpy(buf,fsbuf+start_position,length-start_position);

    pfd->fd_position=length;
    
    message->length=length-start_position;  
}
Beispiel #9
0
static int do_close(MESSAGE *message){
    PROCESS *process=pid2process(message->source_pid);
    int fd=message->fd;
    
    if(process->file_descriptor[fd]!=NULL &&
       process->file_descriptor[fd]->fd_inode!=NULL &&
       process->file_descriptor[fd]->fd_inode->i_share_count>0
        ){
        free_inode(process->file_descriptor[fd]->fd_inode);
        free_fd(process->file_descriptor[fd]);
        process->file_descriptor[fd]=NULL;
        
        return 0;
    }
    else{
        set_error_index(FILE_NOT_OPEN);
        return -1;
    }
}
Beispiel #10
0
/*
返回目录下文件/目录的个数
*/
static int get_filename_in_dir(const char* dir_name,char *files){
    INODE dir_inode;
    DIR_ENTRY *dir_entry;
    int dir_entry_index;
    int dir_entry_count;
    int files_index,files_off;
    u8 fsbuf[SECTOR_SIZE*2];
    
    if(get_dir_inode_by_name(dir_name,&dir_inode)<0){
        set_error_index(DIR_NOT_EXIST);
        return -1;
    }
    dir_entry_count=dir_inode.i_size/DIR_ENTRY_SIZE; 

    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (dir_inode.i_start_sector_index)*SECTOR_SIZE,
              dir_inode.i_size,
              TASK_FS,
              fsbuf);

    files_off=0;
    files_index=0;
    for(dir_entry_index=0;dir_entry_index<dir_entry_count;dir_entry_index++){
        dir_entry=(DIR_ENTRY *)(fsbuf+dir_entry_index*DIR_ENTRY_SIZE);
        //此处的dir_entry->inode_index=0:表示该文件建立后删除了
        if(dir_entry->inode_index>0){
            strcpy(files+files_off,dir_entry->name);
#ifdef DEBUG_FS
            printl("%d:%s\n",files_index,files+files_off);
#endif
            files_off+=strlen(dir_entry->name)+1;
            files_index++;
        }
    }
    return files_index;
}
Beispiel #11
0
static /* int */void do_write(MESSAGE *message){
    u8 fsbuf[SECTOR_SIZE*DEFAULT_FILE_SECTOR_LENGTH];
    const char *buf;
    int start_position,sector_length,length,data_sector_index;
    PROCESS *process;
    struct s_file_descriptor* pfd;

    process=pid2process(message->source_pid);
    if(message->fd==STDOUT && process->file_descriptor[message->fd]==NULL){
#ifdef DEBUG_FS
        printl("pid=%d (in do_write)\n",message->source_pid);
#endif
/*pfd->fd_inode->i_mode & I_CHAR_SPECIAL !=0*/
        /* int device=pfd->fd_inode->i_start_sector_index; */
        message->process_index=message->source_pid;
        send_receive(SEND,TASK_TTY/* dd_map[DRIVER(device)] */,message);
        /* message->type=INFO_SUSPEND_PROCESS; */
    }else{
        
        pfd=process->file_descriptor[message->fd];
        if((pfd->fd_op_mode & O_WRONLY)==0 && (pfd->fd_op_mode & O_RDWR)==0){
            set_error_index(FILE_CANNOT_WRITE);
            message->length=-1;
            return;
        }
        buf=message->arg_pointer;
        
        start_position=pfd->fd_position;
        if(start_position >= pfd->fd_inode->i_sectors_length*SECTOR_SIZE){
            set_error_index(FILE_ALLOC_MEM_USEUP);
            message->length=-1;
            return;
        }
        length=min(start_position+message->length,pfd->fd_inode->i_sectors_length*SECTOR_SIZE);
        sector_length=(length+SECTOR_SIZE-1)/SECTOR_SIZE;
        data_sector_index=pfd->fd_inode->i_start_sector_index;
        
#ifdef DEBUG_FS
        /* printl("1 %d %d length=%d\n",start_position,message->length,length); */
        printl("sector_index=%d sector_length=%d(in do_write)\n",data_sector_index,sector_length);
#endif
        rw_sector(INFO_FS_READ,
                  ROOT_DEVICE,
                  (data_sector_index)*SECTOR_SIZE,
                  sector_length*SECTOR_SIZE,
                  TASK_FS,
                  fsbuf);
        memcpy(fsbuf+start_position,buf,length-start_position);
        /* printl("2 %d %d\n",data_sector_index,length); */
        rw_sector(INFO_FS_WRITE,
                  ROOT_DEVICE,
                  (data_sector_index)*SECTOR_SIZE,
                  sector_length*SECTOR_SIZE,
                  TASK_FS,
                  fsbuf);
        
        /* printl("3 inode.i_size=%d\n",pfd->fd_inode->i_size); */
        pfd->fd_inode->i_size=length;
        /* printl("inode_index=%d\n",pfd->fd_inode->i_inode_index); */
        sync_inode(pfd->fd_inode->i_inode_index,*(pfd->fd_inode));
        
        pfd->fd_position=length;  
        message->length=length-start_position;
    }
}
Beispiel #12
0
static int do_open(MESSAGE *message){
    int i,fd=-1;
    const char *path;
    char dirname[MAX_FILENAME_LENGTH]={0};
    char filename[MAX_FILENAME_LENGTH]={0};
    int flags;
    int inode_index;
    struct s_file_descriptor *pfd=NULL;
    struct s_inode *pinode=NULL;
    /* struct s_inode parent_dir_inode; */
    PROCESS *process;

    path=message->arg_pointer;
    flags=message->flags;
    process=pid2process(message->source_pid);
    
    pfd=get_free_fd_from_table();
    pinode=get_free_inode_from_table();
    if(pfd==NULL || pinode==NULL){
        set_error_index(NO_FD_INODE);
        return -1;
    }
    
    //分离父目录路径和文件名
    if(!strip_path(path,dirname,filename)){
        return -1;
    }
#ifdef DEBUG_FS
    printl("dir_name=%s file_name=%s\n",dirname,filename);
#endif

    //搜索文件
    inode_index=search_file(dirname,filename,GET_FILE_TYPE(flags));
    if(inode_index<0){
        if((flags & O_CREATE)==0){
            return -1;
        }
        inode_index=create_file(dirname,filename,GET_FILE_TYPE(flags));
        if(inode_index<0){
            return -1;
        }
    }
    assert(inode_index>=0,"");
    get_inode_by_index(inode_index,pinode);
#ifdef DEBUG_FS
    printl("pinode.start_index=%d(in do_open)",pinode->i_start_sector_index);
#endif
    /*SDTIN=0,STDOUT=1,STDERROR=2*/
    for(i=3;i<FILE_COUNT;i++){
        if(process->file_descriptor[i]==NULL){
            fd=i;
            break;
        }
    }
    
    if(fd>=0){
        process->file_descriptor[fd]=pfd;
    
        pfd->fd_inode=pinode;
        pfd->fd_op_mode=GET_FILE_OP(flags);
        pfd->fd_position=0;

        pinode->i_inode_index=inode_index;
#ifdef DEBUG_FS
        printl("inode_index=%d(in do_open)\n",pinode->i_inode_index);
        printl("data_sector_index=%d data_sector_length=%d\n",process->file_descriptor[fd]->fd_inode->i_start_sector_index,process->file_descriptor[fd]->fd_inode->i_sectors_length);
#endif
        return fd;
    }else{
        set_error_index(PROCESS_FD_POINTER_NOT_ENOUGH);
        return -1;
    }
}