char* find_name(MINODE *mip)
{
    int my_ino = 0;
    int parent_ino = 0;
    findino(mip, &my_ino, &parent_ino);

    MINODE* parent_mip = iget(running->cwd->device, parent_ino);

    char* my_name = NULL;
    findmyname(parent_mip, my_ino, &my_name);

    iput(parent_mip);
    return my_name;
}
Beispiel #2
0
off_t xml_listdir(char *d, int *dt, int *ft, u_long lev, dev_t dev)
{
  char *path;
  bool nlf = FALSE;
  long pathsize = 0;
  struct _info **dir, **sav;
  struct stat sb;
  int t, n, mt;

  if ((Level >= 0) && (lev > Level)) {
    if (!noindent) fputc('\n',outfile);
    return 0;
  }

  if (xdev && lev == 0) {
    stat(d,&sb);
    dev = sb.st_dev;
  }

  sav = dir = read_dir(d,&n);
  if (!dir && n) {
    fprintf(outfile,"<error>opening dir</error>\n");
    return 0;
  }
  if (!n) {
    if (!noindent) fputc('\n', outfile);
    free_dir(sav);
    return 0;
  }
  if (flimit > 0 && n > flimit) {
    fprintf(outfile,"<error>%d entries exceeds filelimit, not opening dir</error>%s",n,noindent?"":"\n");
    free_dir(sav);
    return 0;
  }

  if (cmpfunc) qsort(dir,n,sizeof(struct _info *), cmpfunc);
  if (lev >= maxdirs-1) {
    dirs = xrealloc(dirs,sizeof(int) * (maxdirs += 1024));
    memset(dirs+(maxdirs-1024), 0, sizeof(int) * 1024);
  }
  dirs[lev] = 1;
  if (!*(dir+1)) dirs[lev] = 2;
  if (!noindent) fprintf(outfile,"\n");

  path = malloc(pathsize=4096);

  while(*dir) {
    if (!noindent) xml_indent(lev);

    if ((*dir)->lnk) mt = (*dir)->mode & S_IFMT;
    else mt = (*dir)->mode & S_IFMT;
    for(t=0;ifmt[t];t++)
      if (ifmt[t] == mt) break;
    fprintf(outfile,"<%s", ftype[t]);

    if (fflag) {
      if (sizeof(char) * (strlen(d)+strlen((*dir)->name)+2) > pathsize)
	path=xrealloc(path,pathsize=(sizeof(char) * (strlen(d)+strlen((*dir)->name)+1024)));
      if (!strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name);
      else sprintf(path,"%s/%s",d,(*dir)->name);
    } else {
      if (sizeof(char) * (strlen((*dir)->name)+1) > pathsize)
	path=xrealloc(path,pathsize=(sizeof(char) * (strlen((*dir)->name)+1024)));
      sprintf(path,"%s",(*dir)->name);
    }

    fprintf(outfile, " name=\"");
    html_encode(outfile,path);
    fputc('"',outfile);

    if ((*dir)->lnk) {
      fprintf(outfile, " target=\"");
      html_encode(outfile,(*dir)->lnk);
      fputc('"',outfile);
    }
    xml_fillinfo(*dir);
    fputc('>',outfile);

    if ((*dir)->isdir) {
      if ((*dir)->lnk) {
	if (lflag && !(xdev && dev != (*dir)->dev)) {
	  if (findino((*dir)->inode,(*dir)->dev)) {
	    fprintf(outfile,"<error>recursive, not followed</error>");
	  } else {
	    saveino((*dir)->inode, (*dir)->dev);
	    if (*(*dir)->lnk == '/')
	      listdir((*dir)->lnk,dt,ft,lev+1,dev);
	    else {
	      if (strlen(d)+strlen((*dir)->lnk)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024));
	      if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->lnk);
	      else sprintf(path,"%s/%s",d,(*dir)->lnk);
	      listdir(path,dt,ft,lev+1,dev);
	    }
	    nlf = TRUE;
	  }
	}
      } else if (!(xdev && dev != (*dir)->dev)) {
	if (strlen(d)+strlen((*dir)->name)+2 > pathsize) path=xrealloc(path,pathsize=(strlen(d)+strlen((*dir)->name)+1024));
	if (fflag && !strcmp(d,"/")) sprintf(path,"%s%s",d,(*dir)->name);
	else sprintf(path,"%s/%s",d,(*dir)->name);
	saveino((*dir)->inode, (*dir)->dev);
	listdir(path,dt,ft,lev+1,dev);
	nlf = TRUE;
      }
      *dt += 1;
    } else *ft += 1;
    if (*(dir+1) && !*(dir+2)) dirs[lev] = 2;
    if (nlf) {
      nlf = FALSE;
      if (!noindent) xml_indent(lev);
    }
    fprintf(outfile,"</%s>%s",ftype[t],noindent?"":"\n");
    dir++;
  }
  dirs[lev] = 0;
  free(path);
  free_dir(sav);
  return 0;
}
int my_rmdir(int argc, char* argv[])
{
    result_t result = NONE;
    const int uid = running->uid;
    const int device = running->cwd->device;

    if(argc < 2)
    {
        fprintf(stderr, "rmdir: missing operand\n");
        return MISSING_OPERAND;
    }

    // rmdir each path given by user
    int i = 1;
    while(i < argc)
    {
        char* path  = argv[i];
        int ino     = getino(device, path);
        MINODE* mip = iget(device, ino);

        // Verify file exists
        if(!mip)
        {
            result = DOES_NOT_EXIST;
            fprintf(stderr, "rmdir: failed to remove '%s':"
                    " No such file or directory\n", path);
            goto clean_up;
        }
        // Verify user has permission to remove the directory
        else if(uid != SUPER_USER && uid != mip->inode.i_uid)
        {
            result = PERM_DENIED;
            fprintf(stderr, "rmdir: failed to remove '%s':"
                    " Permission denied\n", path);
            goto clean_up;
        }
        // Verify that it is a directory
        else if(!S_ISDIR(mip->inode.i_mode))
        {
            result = NOT_DIR;
            fprintf(stderr, "rmdir: failed to remove '%s':"
                    " Not a directory\n", path);
            goto clean_up;
        }
        // Verify that it is not busy
        else if(mip->refCount > 1)
        {
            result = BUSY;
            fprintf(stderr, "rmdir: failed to remove directory '%s':"
                    " Directory busy\n", path);
            goto clean_up;
        }
        // Verify that it is empty
        else if(!isEmptyDir(mip))
        {
            result = NOT_EMPTY;
            fprintf(stderr, "rmdir: failed to remove directory '%s':"
                    " Directory not empty\n", path);
            goto clean_up;
        }

        // If removing multiple directories, display
        if(argc > 2)
            printf("rmdir: removing directory '%s'\n", path);

        INODE* ip = &mip->inode;

        // Get parent DIR's ino and Minode
        int parent_ino = 0;
        findino(mip, &ino, &parent_ino);
        MINODE* parent_mip = iget(device, parent_ino); 
        INODE*   parent_ip = &parent_mip->inode;

        // Deallocate its blocks
        for(int b = 0; b < NUM_DIRECT_BLOCKS && ip->i_block[b] != 0; b++)
            bfree(device, ip->i_block[b]);

        // Deallocate its inode
        ifree(device, ino);

        // Remove entry from parent directory
        rm_child(parent_mip, ino); 

        // Update parent's info
        parent_ip->i_links_count--;
        parent_ip->i_atime = time(0L);
        parent_ip->i_mtime = time(0L);
        parent_mip->dirty = true;

        // Write parent changes to disk
        iput(parent_mip);

clean_up:
        // Write changes to deleted directory to disk and clear refCount
        iput(mip); 

        if(result != NONE)
            return result;

        i++;
    }

    return SUCCESS;
}