/**
 *  \brief Get an entry by path.
 *
 *  The directory hierarchy of the file system is traversed to find an entry whose name is the rightmost component of
 *  <tt>ePath</tt>. The path is supposed to be absolute and each component of <tt>ePath</tt>, with the exception of the
 *  rightmost one, should be a directory name or symbolic link name to a path.
 *
 *  The process that calls the operation must have execution (x) permission on all the components of the path with
 *  exception of the rightmost one.
 *
 *  \param ePath pointer to the string holding the name of the path
 *  \param p_nInodeDir pointer to the location where the number of the inode associated to the directory that holds the
 *                     entry is to be stored
 *                     (nothing is stored if \c NULL)
 *  \param p_nInodeEnt pointer to the location where the number of the inode associated to the entry is to be stored
 *                     (nothing is stored if \c NULL)
 *
 *  \return <tt>0 (zero)</tt>, on success
 *  \return -\c EINVAL, if the pointer to the string is \c NULL or the path string does not describe an absolute path
 *  \return -\c ENAMETOOLONG, if the path or any of the path components exceed the maximum allowed length
 *  \return -\c ERELPATH, if the path is relative and it is not a symbolic link
 *  \return -\c ENOTDIR, if any of the components of <tt>ePath</tt>, but the last one, is not a directory
 *  \return -\c ELOOP, if the path resolves to more than one symbolic link
 *  \return -\c ENOENT,  if no entry with a name equal to any of the components of <tt>ePath</tt> is found
 *  \return -\c EACCES, if the process that calls the operation has not execution permission on any of the components
 *                      of <tt>ePath</tt>, but the last one
 *  \return -\c EDIRINVAL, if the directory is inconsistent
 *  \return -\c EDEINVAL, if the directory entry is inconsistent
 *  \return -\c EIUININVAL, if the inode in use is inconsistent
 *  \return -\c ELDCININVAL, if the list of data cluster references belonging to an inode is inconsistent
 *  \return -\c EDCINVAL, if the data cluster header is inconsistent
 *  \return -\c ELIBBAD, if some kind of inconsistency was detected at some internal storage lower level
 *  \return -<em>other specific error</em> issued by \e lseek system call
 */
int soGetDirEntryByPath (const char *ePath, uint32_t *p_nInodeDir, uint32_t *p_nInodeEnt)
{
  soProbe (111, "soGetDirEntryByPath (\"%s\", %p, %p)\n", ePath, p_nInodeDir, p_nInodeEnt);

  printf("\nePath = %s\n", ePath);

  /** Variables **/
  int error;
  char absPath[1];
  char auxPath[MAX_PATH + 1];
  char dirPath[MAX_PATH + 1];
  char basePath[MAX_NAME + 1];
  uint32_t nInodeDir;
  uint32_t nInodeEnt;
  SOSuperBlock *sb;

  /** Parameter check **/
  if(ePath == NULL)
    return -EINVAL;
  /** Conformity check **/
  if(strlen(ePath) > MAX_PATH + 1)
    return -ENAMETOOLONG;

  /** Check if ePath is an absolute path **/
  absPath[0] = '/';
  if(ePath[0] != absPath[0])
    return -ERELPATH;

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

  /** Loading SuperBlock **/
  if((error = soLoadSuperBlock()) != 0)
    return error;
  if((sb = soGetSuperBlock()) == NULL)
    return -EBADF;

  /** Get parent directory inode number **/
  if((error = soTraversePath(sb, dirPath, NULL, &nInodeDir)) != 0)
    return error;

  /** Get entry inode number **/
  /*if((error = soGetDirEntryByName_bin(nInodeDir, basePath, &nInodeEnt, NULL)) != 0)
    return error;*/

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

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

  /** Operation successful **/
  return 0;

}
Example #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;

}
/*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;
}