int soGetDirEntryByName (uint32_t nInodeDir, const char *eName, uint32_t *p_nInodeEnt, uint32_t *p_idx) { soColorProbe (312, "07;31", "soGetDirEntryByName (%"PRIu32", \"%s\", %p, %p)\n", nInodeDir, eName, p_nInodeEnt, p_idx); SOSuperBlock *p_sb; SOInode p_Inode; SODataClust clustDir; // Variavel usada para retorno de erros uint32_t status; int i, j; if((status = soLoadSuperBlock())!= 0){ return status; } p_sb = soGetSuperBlock(); if(nInodeDir >= p_sb->iTotal){ return -EINVAL; } // Verificação se o campo eName é igual a NULL ou esta vazio if(eName == NULL || (strlen(eName))==0){ return -EINVAL; } // Verifica se a string nome excede o comprimento máximo if(strlen(eName) > MAX_NAME){ return -ENAMETOOLONG; } // Verifica se a string é um nome de um ficheiro e não um caminho for(i=0; eName[i]!='\0';i++) { if(eName[i] == '/') return -EINVAL; } // Le o inode. Verifica se está em uso if((status = soReadInode(&p_Inode,nInodeDir,IUIN))){ return status; } // Verifica se o nó-i é do tipo diretório if((p_Inode.mode & INODE_TYPE_MASK) != INODE_DIR){ return -ENOTDIR; } if((status = soQCheckDirCont(p_sb,&p_Inode))!=0){ return status; } // Verifica se existe permissão de execução if((status = soAccessGranted(nInodeDir,X))!=0){ return status; } // Numero de entradas de directorio uint32_t numRefMax = p_Inode.size/(DPC*sizeof(SODirEntry)); for (i = 0; i < numRefMax; i++){ //Le o conteudo do cluster referenciado pelo inode if((status = soReadFileCluster(nInodeDir,i,&clustDir))){ return status; } // Procura pelo nome, verificando todas as entradas de directorio for (j = 0; j < DPC; j++){ if (strcmp((char*)(clustDir.info.de[j].name),eName)==0){ // Se o argumento é diferente de NULL retorna o inode referenciado pelo nome if(p_nInodeEnt != NULL){ *p_nInodeEnt = (clustDir.info.de[j].nInode); } if(p_idx != NULL){ *p_idx =((i*DPC)+j); } return 0; } // Verifica se a entrada j esta free if((clustDir.info.de[j].name[0] == '\0') && (clustDir.info.de[j].name[MAX_NAME] == '\0')){ if(p_idx != NULL){ *p_idx = ((i*DPC)+j); } return -ENOENT; } } } // Se nao existir entradas free if(p_idx != NULL){ *p_idx = (p_Inode.cluCount)*DPC; } return -ENOENT; }
int soRead (const char *ePath, void *buff, uint32_t count, int32_t pos) { soColorProbe (229, "07;31", "soRead (\"%s\", %p, %u, %u)\n", ePath, buff, count, pos); int stat; // variavel para o estado SOSuperBlock *p_sb; // ponteiro para o super bloco SOInode p_inode; // pointer to inode table for nBlk block position uint32_t p_nInodeEnt; // ponteiro para a localizacao onde o nº do nó I associado à entrada é armazenado uint32_t offset; // numero do offset () uint32_t p_clustInd; // ponteiro para indice do cluster uint32_t p_clustIndF; // ponteiro para indice do cluster final uint32_t offsetFinal; // offset final int bytesRead = 0; // variável para indicar o numero de bytes lidos em sucesso SODataClust p_buff; // ponteiro para o buffer /*------VALIDATIONS----------*/ /* carregar super bloco*/ if( (stat = soLoadSuperBlock()) != 0) return stat; /* obter super bloco*/ p_sb = soGetSuperBlock(); /* if the pointer to the string is null */ if(ePath == NULL) return -EINVAL; /* if the path does not describe a absolute path*/ if(ePath[0] != '/') return -EINVAL; /*if the path name or any of its components exceed the maximum allowed length*/ if(strlen(ePath) > MAX_PATH) return -ENAMETOOLONG; /* Obter o Inode associado ao ePath e verificar se há erros */ if( (stat = soGetDirEntryByPath(ePath, NULL, &p_nInodeEnt)) != 0) return stat; /* Ler e verificar o inode (tem que ser um ficheiro regular) */ if( (stat = soReadInode(&p_inode, p_nInodeEnt, IUIN)) != 0) return stat; /*verificar se ePath descreve um directorio*/ if( (stat = soQCheckDirCont(p_sb, &p_inode)) != 0) return -EISDIR; /*if any of the components of ePath, but the last one, is not a directory*/ if( (stat != -ENOTDIR)) return stat; /*verificar se o processo tem permissão de execucção*/ if( (stat = soAccessGranted(p_nInodeEnt, X)) != 0) return -EACCES; /*verificar se o processo tem permissao de leitura*/ if( (stat = soAccessGranted(p_nInodeEnt, R)) != 0) return -EPERM; /*if the starting [byte] position in the file data continuum assumes a value passing its maximum size*/ /*Verifica se o pos está fora do ficheiro*/ if(pos > p_inode.size) return -EFBIG; /*------END OF VALIDATIONS-------*/ /* Corrige o count se pos+count ultrapassar o limite do ficheiro */ if((pos + count) > p_inode.size) count = p_inode.size - pos; /* vai obter o clustInd e offset apartir do pos */ if( (stat = soConvertBPIDC(pos, &p_clustInd, &offset)) != 0) return stat; // byte position é definido como : // pos = clustInd * BSLPC + offset /* vai obter o clustInd e offset do final do ficheiro apartir do pos + count */ if( (stat = soConvertBPIDC(pos + count, &p_clustIndF, &offsetFinal)) != 0) return stat; /* leitura do 1º cluster do inode*/ if( (stat = soReadFileCluster(p_nInodeEnt, p_clustInd, &p_buff)) != 0) return stat; /* Se for necessario ler um pedaço do mesmo cluster */ if(p_clustInd == p_clustIndF) { memcpy(buff, &p_buff.info.data[BSLPC] + offset, (offsetFinal - offset)); bytesRead = offsetFinal - offset; return bytesRead; } /*Se for para ler mais que 1 cluster, ler o resto do primeiro */ memcpy(buff, &p_buff.info.data[BSLPC] + offset, (BSLPC - offset)); bytesRead = BSLPC - offset; p_clustInd++; // incrementa o indice do cluster /* ler proximo cluster*/ if( (stat = soReadFileCluster(p_nInodeEnt, p_clustInd, &p_buff)) != 0) return stat; /* ler clusters "intermédios" */ while(p_clustInd < p_clustIndF) { memcpy(buff+bytesRead, &p_buff.info.data[BSLPC], BSLPC); bytesRead += BSLPC; /*ler proximo cluster */ if( (stat = soReadFileCluster(p_nInodeEnt, p_clustInd, &p_buff)) != 0) return stat; } /* caso o que cluster que vamos ler é o ultimo*/ memcpy(buff + bytesRead, &p_buff.info.data[BSLPC], offsetFinal); bytesRead += offsetFinal; return bytesRead; }
int soRenameDirEntry (uint32_t nInodeDir, const char *oldName, const char *newName) { soColorProbe (315, "07;31", "soRenameDirEntry (%"PRIu32", \"%s\", \"%s\")\n", nInodeDir, oldName, newName); SOSuperBlock *p_sb; SOInode inode; SODataClust dirClust; int size; int stat; uint32_t p_idx; //uint32_t p_nInodeEnt; // obter informação do superbloco if((stat=soLoadSuperBlock())!=0) { return stat; } // ponteiro para o superblock p_sb=soGetSuperBlock(); // verificação de validade do iNode if(nInodeDir>=p_sb->iTotal || nInodeDir < 0) { return -EINVAL; } if (oldName == NULL || newName == NULL) { return -EINVAL; } // check ao tamanho do nome antigo size = strlen(oldName); if(size > (MAX_NAME)) { return -ENAMETOOLONG; } // check ao tamanho do novo nome size = strlen(newName); if(size > (MAX_NAME)) { return -ENAMETOOLONG; } /* verificaçã odas string, estas nao podem conter '/' no seu conteudo char test; test=strchr(&newName,'/'); if(test != NULL) { return -EINVAL; } test=strchr(&oldName,'/'); { return -EINVAL } esta verificação e feita pela funçao pela soGetEntryByName */ // leitura do inode if ((stat=soReadInode(&inode,nInodeDir,IUIN))!=0) { return stat; } if((stat=soQCheckInodeIU(p_sb,&inode))!=0) { return stat; } // verificação de permissoes de execução if((stat=soAccessGranted(nInodeDir,X))!=0) { return -EACCES; } // verificação de permissoes de escrita if((stat=soAccessGranted(nInodeDir,W))!=0) { return -EPERM; } // verificação se o inodeDir e um directorio if((inode.mode & INODE_DIR)!= INODE_DIR) { return -ENOTDIR; } /*if((stat=soQCheckDirCont(p_sb,&inode))!=0) { return stat; } perror("antesQcheck");*/ //verificação se o novo nome a alterar existe if((stat=soGetDirEntryByName(nInodeDir,oldName,NULL,&p_idx))!= 0){ return stat; } if((stat=soGetDirEntryByName(nInodeDir,newName,NULL,NULL)) == 0){ return -EEXIST; } /*if(stat != 0) { return stat; }*/ /* vamos carregar o cluster que possui a entrada de directorio que pretendemos renomear*/ if((stat=soReadFileCluster(nInodeDir,p_idx/DPC, &dirClust))!=0) { return stat; } // copiar nova string para a entrada onde se encontrava o oldName //memcpy((char*)dirClust.info.de[p_idx%DPC].name,(char*)newName,MAX_NAME+1); int i = 0; for(i=0;i < MAX_NAME+1;i++) { dirClust.info.de[p_idx%DPC].name[i]=0; } strcpy((char*)dirClust.info.de[p_idx%DPC].name,(char*)newName); if((stat=soWriteFileCluster(nInodeDir,p_idx/DPC, &dirClust))!=0) { return stat; } return 0; }