#include "dir.h" #include #include #include #include #include #include #include "defs.h" #include "block_walker.h" uint16_t dir_create(const char *disk_mem, mode_t mode) { uint16_t ipos = 0; dir *d = NULL; time_t new_time = NEW_TIME; assert (disk_mem != NULL); ipos = inode_allocate_block(disk_mem); if(ipos == 0) return 0; d = (dir *) disk_mem + INODEPOOL_OFFSET + (ipos * INODE_SIZE); d->uid = getuid(); d->gid = getgid(); d->mode = mode; d->size = 0; d->type = I_DIR; d->nlinks = 1; d->ctime = new_time; d->mtime = new_time; d->atime = new_time; return (ipos); } uint16_t dir_add_direntry(const char *disk_mem, dir *d, const char *name, uint16_t inumber, uint16_t sym) { bwalker *walker = NULL; uint16_t block = 0; direntry *dentry = NULL; uint16_t i = 0; int result = 0; assert (disk_mem != NULL); assert (d != NULL); assert (name != NULL); assert (strlen(name) < NAME_LENGTH); walker = bwalker_create(disk_mem, d->size, &(d->indirect)); if(bwalker_direct_length(walker)*BLOCK_SIZEsize+32){ block = bwalker_allocate_block(walker); }else{ block = bwalker_last_block(walker); if(!block) goto CLEAN; } dentry = (direntry *) disk_mem + BLOCKPOOL_OFFSET + (block * BLOCK_SIZE); for(i = 0; i < 16; i++){ if(strcmp(dentry[i].name, "\0") == 0){ d->size += sizeof(direntry); /* Deberia ser 32*/ dentry = &(dentry[i]); strcpy(dentry->name, name); dentry->inum = inumber; dentry->symlink = sym; result = 1; goto CLEAN; } } CLEAN: bwalker_destroy(walker); return result; } uint16_t dir_remove_direntry(const char *disk_mem, dir *d, const char *name) { bwalker *walker = NULL; uint16_t result = 0; uint16_t block = 0; direntry *rm_dentry = NULL; direntry *last_dentry = NULL; uint16_t i; assert(disk_mem != NULL); assert(d != NULL); assert(name != NULL); assert(strlen(name) < NAME_LENGTH); walker = bwalker_create(disk_mem, d->size, &(d->indirect)); /* Conseguimos el ultimo direntry */ block = bwalker_last_block(walker); assert(block != 0); last_dentry = (direntry *) disk_mem + BLOCKPOOL_OFFSET + (block * BLOCK_SIZE); assert(last_dentry[0].inum != 0); for(i = 0; i < 16; i++){ if(last_dentry[i].inum == 0) break; } assert(i > 0); last_dentry = &(last_dentry[i-1]); while((block = bwalker_next(walker))) { rm_dentry = (direntry *) disk_mem + BLOCKPOOL_OFFSET + (block * BLOCK_SIZE); for(i = 0; i < 16; i++) if(strcmp(name, rm_dentry[i].name) == 0) { /* Retornamos esto para eliminarlo fuera. */ result = rm_dentry[i].inum; /* Copiamos a la nueva posicion para ahorrarnos la * fragmentacion externa. */ strcpy(rm_dentry[i].name, last_dentry->name); rm_dentry[i].inum = last_dentry->inum; rm_dentry[i].symlink = last_dentry->symlink; /* Borramos los contenidos del ultimo. */ last_dentry->name[0] = '\0'; last_dentry->inum = 0; last_dentry->symlink = 0; goto END; } if(bwalker_block_is_last(walker)) break; } END: bwalker_destroy(walker); return result; } dir *dir_get_from_path(const char *disk_mem, const char *path) { uint16_t inum = 0; char *dir_name = NULL; assert (disk_mem != NULL); assert (path != NULL); dir_name = calloc(strlen(path) + 1, sizeof(char)); strcpy(dir_name, path); inum = get_inode_from_path(disk_mem, dirname(dir_name), 1); free(dir_name); if(inum==0){ return NULL; } return ((dir *)disk_mem+INODEPOOL_OFFSET+INODE_SIZE*inum); } uint16_t dir_search(const char *disk_mem, dir *idir,const char *name) { bwalker *bw = NULL; direntry *dentry; uint16_t bnum, i; assert(disk_mem != NULL); assert(idir != NULL); assert(name != NULL); assert(strcmp(name, "")); /* Salimos si esto esta vacio obviamente. */ if(idir->size == 0){ return 0; } bw = bwalker_create(disk_mem, idir->size, &(idir->indirect)); while ((bnum = bwalker_next(bw))) { dentry=(direntry *) disk_mem + BLOCKPOOL_OFFSET + (bnum*BLOCK_SIZE); for(i=0; i<16; i++){ if(strcmp(name, dentry[i].name) == 0){ bwalker_destroy(bw); return dentry[i].inum; } } if(bwalker_block_is_last(bw)) break; } bwalker_destroy(bw); return 0; } int dir_rename_inode(const char *disk_mem, dir *d, const char *old_name, const char *new_name) { bwalker *bw = NULL; direntry *dentry; uint16_t i; uint16_t bnum; assert(disk_mem != NULL); assert(d != NULL); assert(strcmp(old_name, "")); assert(new_name != NULL); assert(old_name != NULL); assert(strlen(new_name) < NAME_LENGTH); /* Salimos si esto esta vacio obviamente. */ if(d->size == 0){ return 0; } bw = bwalker_create(disk_mem, d->size, &(d->indirect)); while ((bnum = bwalker_next(bw))) { dentry=(direntry *) disk_mem + BLOCKPOOL_OFFSET + (bnum*BLOCK_SIZE); for(i=0; i<16; i++){ if(strcmp(old_name, dentry[i].name) == 0){ bwalker_destroy(bw); strcpy(dentry[i].name,new_name); return 1; } } if(bwalker_block_is_last(bw)) break; } bwalker_destroy(bw); return 0; } uint16_t dir_readdir(const char *disk_mem, dir *d, void *buf, fuse_fill_dir_t filler) { bwalker *bw = NULL; direntry *dentry; uint16_t bnum, i; assert(disk_mem != NULL); assert(d != NULL); /* Salimos si esto esta vacio obviamente. */ if(d->size == 0) return 0; bw = bwalker_create(disk_mem, d->size, &(d->indirect)); while ((bnum = bwalker_next(bw))){ dentry=(direntry *) disk_mem + BLOCKPOOL_OFFSET + (bnum*BLOCK_SIZE); for(i=0; i<16 && dentry[i].name[0] != '\0' ; i++){ filler(buf, (const char *)&(dentry[i].name), NULL, 0); } if(bwalker_block_is_last(bw)) break; } bwalker_destroy(bw); return 0; }