static void get_args(int argc, char *argv[], extension_list_t **curext, exclude_list_t **curexcl) { int opt; exclude_list_t *tmpexcl; extension_list_t *tmpext; while ((opt = getopt(argc, argv, "hit:refx:")) != -1) { switch (opt) { case 'h': usage(); break; case 'i': strcpy(mainsearch.options, "-i"); break; case 't': //FIXME: maybe the LL is empty hehe ... tmpext = malloc(sizeof(extension_list_t)); strncpy(tmpext->ext, optarg, LINE_MAX); tmpext->next = NULL; (*curext)->next = tmpext; *curext = tmpext; break; case 'r': mainsearch_attr.raw = 1; break; case 'e': mainsearch.is_regex = 1; break; case 'f': mainsearch_attr.follow_symlinks = 1; break; case 'x': tmpexcl = malloc(sizeof(exclude_list_t)); if (!mainsearch_attr.firstexcl) { mainsearch_attr.has_excludes = 1; mainsearch_attr.firstexcl = tmpexcl; } else { (*curexcl)->next = tmpexcl; } tmpexcl->d_ino = get_inode_from_path(optarg); tmpexcl->next = NULL; *curexcl = tmpexcl; break; default: exit(-1); break; } } }
int lfs_truncate(const char *path, off_t length) { int res = 0; struct inode* node; node = malloc(BLOCK_SIZE); if (!node) { res = -ENOMEM; } else { res = get_inode_from_path(log_system, path, node); if (!res) { res = node_trunc(log_system, node, length); } free(node); } return res; }
int lfs_open(const char *path, struct fuse_file_info *fi) { int res = 0; struct inode* node; //printf("open: (path=%s)\n", path); node = malloc(INODE_SIZE); if (!node) { res = -ENOMEM; } else { res = get_inode_from_path(log_system, path, node); if (!res) { fi->fh = node->inode_number; open_file = fi; //TODO flags and stuff } } return res; }
/** Get file attributes. * * Gets file attributes and saves them in the stbuff * struct. */ int lfs_getattr(const char *path, struct stat *stbuf) { int res = 0; struct inode* node; printf("getattr: (path=%s)\n", path); memset(stbuf, 0, sizeof(struct stat)); if (strncmp(path, "/.Trash", 7) == 0) { //TODO what to do here? return 0; } node = malloc(INODE_SIZE); if (!node) { perror("lfs_getattr, malloc"); res = -ENOMEM; } else { if (strcmp(path, "/") == 0) { res = get_root_inode(log_system, node); if (!res) { stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 2 + node->number_of_children; } } else { res = get_inode_from_path(log_system, path, node); if (res) { perror("lfs_getattr, get_inode_from_path"); printf("getattr: get inode from path returned %d\n", res); res = -ENOENT; } else { if (node->is_dir) { stbuf->st_mode = S_IFDIR | 0755; } else { stbuf->st_mode = S_IFREG | 0777; } stbuf->st_nlink = 1; } } if (!res) { stbuf->st_size = node->file_size; stbuf->st_ino = node->inode_number; stbuf->st_blksize = BLOCK_SIZE; } } free(node); printf("get_attr done\n"); return res; }
int bb_getattr(const char *path, struct stat *statbuf) { int retstat = 0; log_msg("\nbb_getattr(path=\"%s\", statbuf=0x%08x)\n", path, statbuf); inode_t inode; inumber_t inumber; inumber = get_inode_from_path(path, &inode); log_msg("inumber = %d\n", inumber); if (inumber == 0 || inumber == INODE_COUNT + 1) { return -ENOENT; } if (inode.attr.type == DIR_T) { statbuf->st_mode = S_IFDIR | 0755; } else if (inode.attr.type == FILE_T) { statbuf->st_mode = S_IFREG | 0644; statbuf->st_size = inode.attr.size; } statbuf->st_ino = inode.inumber; statbuf->st_uid = getuid(); statbuf->st_gid = getgid(); statbuf->st_atime = inode.attr.creation_time; statbuf->st_ctime = inode.attr.creation_time; statbuf->st_mtime = inode.attr.creation_time; log_stat(statbuf); return retstat; }
int bb_opendir(const char *path, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_opendir(path=\"%s\", fi=0x%08x)\n", path, fi); inode_t inode; get_inode_from_path(path, &inode); fi->fh = 0; if (inode.inumber > 0 && inode.inumber < INODE_COUNT + 1) { return 0; } else { return -ENOENT; } log_fi(fi); return retstat; }
/** Reads a directory */ int lfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { struct inode* node; struct inode* child; unsigned int* block; int res = 0; //printf("readdir: (path=%s)\n", path); node = malloc(INODE_SIZE); if (!node) { res = -ENOMEM; } else { if (strcmp(path, "/") == 0) { res = get_root_inode(log_system, node); if (!res) { struct stat* stbuf = malloc(sizeof(struct stat)); if (!stbuf) { res = -ENOMEM; } else { stbuf->st_ino = node->inode_number; stbuf->st_mode = S_IFDIR | 755; filler(buf, ".", stbuf, 0); filler(buf, "..", NULL, 0); free(stbuf); } } } else { res = get_inode_from_path(log_system, path, node); if (res) { return -ENOENT; } else { if (!node->is_dir) { ////printf("Well, that explains it\n"); res = -ENOTDIR; } else { ////printf("readdir: 1\n"); block = malloc(BLOCK_SIZE); if (!block) { res = -ENOMEM; } else { struct stat* stbuf = malloc(sizeof(struct stat)); if (!stbuf) { res = -ENOMEM; } else { int i; ////printf("readdir: 3\n"); stbuf->st_ino = node->inode_number; stbuf->st_mode = S_IFDIR; filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); for (i = 0; (i < node->number_of_children) && !res; i++) { ////printf("readdir: 4,%d\n", i); child = malloc(INODE_SIZE); if (!child) { res = -ENOMEM; } else { res = read_inode(log_system, node->block_placements[i], child); stbuf->st_ino = child->inode_number; if (child->is_dir) { stbuf->st_mode = S_IFDIR | 755; } else { stbuf->st_mode = S_IFREG | 755; } filler(buf, child->file_name, stbuf, 0); free(child); } } free(stbuf); } free(block); } } } } free(node); } return res; }
int lfs_rmdir(const char *path) { int res = 0; int i; struct inode* node; struct inode* parent; unsigned int* block; node = malloc(INODE_SIZE); if (!node) { res = -ENOMEM; } else { res = get_inode_from_path(log_system, path, node); if (!res) { if (node->is_dir) { res = -ENOTDIR; } else { parent = malloc(INODE_SIZE); if (!parent) { res = -ENOMEM; } else { res = read_inode(log_system, node->parent_inode_number, parent); if (!res) { if (node->number_of_children > 0) { res = -ENOTEMPTY; } else { block = malloc(BLOCK_SIZE); if (!block) { res = -ENOMEM; } else { res = read_block(log_system, block, parent->block_placements[0]); if (!res) { int found = 0; for (i = 0; i <= parent->number_of_children; i++) { if (found) { block[i - 1] = block[i]; } else if (block[i] == node->inode_number) { found = 1; } } parent->number_of_children--; parent->blocks_changed[0] = 1; res = update_inode_table(log_system, node->inode_number, 0); if (!res) { log_system->number_of_inodes--; res = buff_write_inode_with_changes(log_system, parent, block); } } free(block); } } } } free(parent); } } } free(node); return res; }
int lfs_unlink(const char *filename) { int res = 0; struct inode* node; struct inode* parent; node = malloc(INODE_SIZE); if (!node) { res = -ENOMEM; } else { res = get_inode_from_path(log_system, filename, node); if (res) { perror("unlink"); } else { if (node->is_dir) { res = -EBADF; } else { parent = malloc(INODE_SIZE); if (!parent) { res = -ENOMEM; } else { res = read_inode(log_system, node->parent_inode_number, parent); if (res) { perror("unlink"); } else { int i, found = 0; unsigned int block[BLOCK_SIZE]; res = read_block(log_system, block, parent->block_placements[0]); if (res) { perror("unlink"); } else { for (i = 0; i < parent->number_of_children; i++) { if (found) { block[i - 1] = block[i]; } else if (block[i] == node->inode_number) { found = 1; } } if (found) { block[parent->number_of_children] = 0; parent->number_of_children--; res = buff_write_inode_with_changes(log_system, parent, block); if (res) { perror("unlink"); } else { unsigned int inode_table[BLOCK_SIZE]; res = read_inode_table(log_system, inode_table); if (res) { perror("unlink"); } else { inode_table[node->inode_number] = 0; i = 0; while (log_system->buffer_summary[i] > 0) { i++; } copy_one_block(inode_table, log_system->buffer, 0, i * BLOCK_SIZE + BLOCKS_PR_SEGMENT + log_system->next_segment * SEGMENT_SIZE); log_system->number_of_inodes--; } } } } } free(parent); } } } free(node); } return res; }
int lfs_mkdir(const char *path, mode_t mode) { int res = 0; struct inode* node; struct inode* parent; char* name; printf("%s\n", "lfs_mkdir"); node = malloc(INODE_SIZE); if (!node) { res = -ENOMEM; } else { if (get_inode_from_path(log_system, path, node) == 0) { free(node); printf("mkdir: dir exists\n"); return -EEXIST; } name = malloc(FILE_NAME_LENGTH_MAX); if (!name) { res = -ENOMEM; } else { //printf("mkdir: 1\n"); res = get_filename(path, name); if (!res) { //printf("mkdir: 2\n"); parent = malloc(INODE_SIZE); if (!parent) { res = -ENOMEM; } else { //printf("mkdir: 3\n"); res = get_root_inode(log_system, parent); if (!res) { //printf("mkdir: 4\n"); char* temp = malloc(strlen(path)); if (!temp) { res = -ENOMEM; } else { //printf("mkdir: 5\n"); strcpy(temp, path); while ((strcmp(temp, name) != 0) && (strcmp(temp + 1, name) != 0) && !res) { //printf("mkdir: temp now = %s\n", temp); res = traverse_path(log_system, temp, parent, node, temp); if (!res) { parent = node; } } if (!res) { printf("mkdir: 6\n"); printf("mkdir: parent is %s\n", parent->file_name); node->inode_number = log_system->number_of_inodes + INODE_NUMBERS_MIN; node->is_dir = 1; memcpy(node->file_name, name, strlen(name)); node->number_of_blocks = 0; //printf("mkdir: child is %s\n", node->file_name); node->number_of_children = 0; node->file_size = strlen(name); memset(node->block_placements, 0, BLOCKS_PR_INODE); memset(node->blocks_changed, 0, BLOCKS_PR_INODE); //printf("mkdir: 9\n"); res = add_child_to_dir(log_system, parent, node); //printf("mkdir: parent has %d children\n", parent->number_of_children); } free(temp); } } } } free(name); } } //printf("mkdir: returning %d\n", res); return res; }