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