Beispiel #1
0
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;
}
Beispiel #2
0
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;

}
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;
}
/*Auxiliary function to traverse the parent directory(s)*/
static int soTraversePath(SOSuperBlock *p_sb, char *ePath, uint32_t *p_nInodeDir, uint32_t *p_nInodeEnt){

  /** Variables **/
  int error;
  int entryFound;
  char auxPath[MAX_PATH + 1];
  char dirPath[MAX_PATH + 1];
  char basePath[MAX_NAME + 1];
  SOInode parentDirInode;
  uint32_t nInodeDir;
  uint32_t nInodeEnt;

  /** Get basename and dirname of ePath **/
  strcpy((char *)auxPath, ePath);
  strcpy(dirPath, dirname(auxPath));
  strcpy((char *)auxPath, ePath);
  strcpy(basePath, basename(auxPath));

  entryFound = 0;
  /** Get current dir inode number **/
  if(strcmp(dirPath, "/") == 0){
    /*Parent directory is the ".." entry*/
    if((error = soGetDirEntryByName(0, "..", &nInodeDir, NULL)) != 0)
      return error;

    /*Get entry inode number*/
    if(strcmp(basePath, "/") != 0){
      if((error = soGetDirEntryByName(0, basePath, &nInodeEnt, NULL)) != 0)
        return error;
    }
    /*Entry directory of root direcrory is "."*/
    else if((error = soGetDirEntryByName(0, ".", &nInodeEnt, NULL)) != 0)
      return error;
    /*Update auxiliary variable*/

    entryFound = 1;
  }
  else if((error = soTraversePath(p_sb, dirPath, NULL, &nInodeDir)) != 0)
    return error;


  /** Read Parent directory inode **/
  if((error = soReadInode(&parentDirInode, nInodeDir, IUIN)) != 0)
    return error;

  /** Check if inode of parent directory indeed refers to a directory **/
  if((parentDirInode.mode & INODE_DIR) != INODE_DIR)
    return -ENOTDIR;

  /** Check parent directory consistency **/
  if((error = soQCheckDirCont(p_sb, &parentDirInode)) != 0)
    return error;

  /** Check execution permission on parent directory **/
  if((error = soAccessGranted(nInodeDir, X)) != 0)
    return error;

  /** Get Entry inode number if needed**/
  if(entryFound == 0){
    if((error = soGetDirEntryByName(nInodeDir, basePath, &nInodeEnt, NULL)) != 0)
      return error;
  }

  /** Update return values **/
  if(p_nInodeDir != NULL)
    *p_nInodeDir = nInodeDir;
  if(p_nInodeEnt != NULL)
    *p_nInodeEnt = nInodeEnt;

  /** Traverse successful **/
  return 0;
}