int fs_getattr(const char *path, struct stat *statbuf) { fprintf(stderr, "fs_getattr(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; char* s3bucket = (char*)ctx; s3dirent_t* dirs = NULL; s3dirent_t* more_dirs = NULL; ssize_t size = s3fs_get_object(s3bucket, path, (uint8_t**)&dirs, 0, 0); if (size<0) { printf("This object does not exist\n"); free(dirs); return -ENOENT; } char* copy_path_1 = strdup(path); char* copy_path_2 = strdup(path); char* directory = dirname(copy_path_1); char* base = basename(copy_path_2); size = s3fs_get_object(s3bucket, directory, (uint8_t**)&more_dirs, 0, 0); if (size < 0) { free(dirs); free(copy_path_1); free(copy_path_2); free(more_dirs); return -EIO; } int entries = size/sizeof(s3dirent_t); printf("ENTRIES = %d\n", entries); int i=0; for(;i<entries;i++) { if ( strcasecmp(more_dirs[i].name, base) == 0) { if (more_dirs[i].type == 'F') { printf("found the file! & doing stat for file!\n"); statbuf->st_mode = more_dirs[i].protection; statbuf->st_uid = more_dirs[i].user_id; statbuf->st_nlink = more_dirs[i].hard_links; statbuf->st_size = more_dirs[i].size; statbuf->st_atime = more_dirs[i].last_access; statbuf->st_mtime = more_dirs[i].mod_time; statbuf->st_ctime = more_dirs[i].status_change; free(copy_path_1); free(copy_path_2); free(more_dirs); free(dirs); return 0; } } } printf("doing stat for a directory!\n"); statbuf->st_mode = dirs[0].protection; statbuf->st_uid = dirs[0].user_id; statbuf->st_nlink = dirs[0].hard_links; statbuf->st_size = dirs[0].size; statbuf->st_atime = dirs[0].last_access; statbuf->st_mtime = dirs[0].mod_time; statbuf->st_ctime = dirs[0].status_change; free(dirs); free(copy_path_1); free(copy_path_2); free(more_dirs); return 0; }
/* * Rename a file. */ int fs_rename(const char *path, const char *newpath) { fprintf(stderr, "fs_rename(fpath=\"%s\", newpath=\"%s\")\n", path, newpath); s3context_t *ctx = GET_PRIVATE_DATA; char* s3bucket = (char*)ctx; FILE* f = NULL; s3dirent_t* more_dirs = NULL; ssize_t size = s3fs_get_object(s3bucket, path, (uint8_t**)&f, 0, 0); if (size<0) { printf("This object does not exist\n"); return -ENOENT; } s3fs_remove_object(s3bucket,path); s3fs_put_object(s3bucket, path, (uint8_t*)f, sizeof(f)); char* copy_path_1 = strdup(path); char* copy_path_2 = strdup(path); char* directory = dirname(copy_path_1); char* base = basename(copy_path_2); char* copy_new_path = strdup(newpath); char* newbase = basename(copy_new_path); size = s3fs_get_object(s3bucket, directory, (uint8_t**)&more_dirs, 0, 0); if (size < 0) { return -EIO; } int entries = size/sizeof(s3dirent_t); printf("ENTRIES = %d\n", entries); int i=0; for(;i<entries;i++) { if ( strcasecmp(more_dirs[i].name,base) == 0) { more_dirs[i].name = newbase; } } s3fs_put_object(s3bucket, directory, (uint8_t*)more_dirs, sizeof(more_dirs)); return -EIO; }
/* * Create a new directory. * * Note that the mode argument may not have the type specification * bits set, i.e. S_ISDIR(mode) can be false. To obtain the * correct directory type bits (for setting in the metadata) * use mode|S_IFDIR. */ int fs_mkdir(const char *path, mode_t mode) { fprintf(stderr, "fs_mkdir(path=\"%s\", mode=0%3o)\n", path, mode); s3context_t *ctx = GET_PRIVATE_DATA; char* s3bucket = (char*)ctx; mode |= S_IFDIR; s3dirent_t* init_dirs = NULL; // check if the directory already exists ssize_t size = s3fs_get_object(s3bucket, path, (uint8_t**)&init_dirs, 0, 0); if (size >= 0) { printf("This Directory Already Exists!\n"); free(init_dirs); return -EIO; } // put a new object s3dirent_t new_dir_obj; new_dir_obj.name = "."; new_dir_obj.type = 'D'; new_dir_obj.protection = mode; new_dir_obj.user_id = getuid(); new_dir_obj.group_id = getgid(); new_dir_obj.hard_links = 0; new_dir_obj.size = 0; new_dir_obj.last_access = time(NULL); new_dir_obj.mod_time = time(NULL); new_dir_obj.status_change = time(NULL); s3fs_put_object(s3bucket, path, (uint8_t*)&new_dir_obj, sizeof(s3dirent_t) ); // add to end of directory printf("JUST ADDED NEW OBJECT WITH KEY %s\n", path); s3dirent_t* dirs = NULL; char* copy_path_1 = strdup(path); char* copy_path_2 = strdup(path); char* directory = dirname(copy_path_1); printf("DIRECTORY = %s\n", directory); char* base = basename(copy_path_2); printf("BASE = %s\n", base); size = s3fs_get_object(s3bucket, directory, (uint8_t**)&dirs, 0, 0); if (size < 0) { free(init_dirs); free(copy_path_1); free(copy_path_2); free(dirs); return -EIO; } int entries = size/sizeof(s3dirent_t); printf("NEW ENTRIES mkdir %d\n", entries); s3dirent_t new_dirent; new_dirent.name = base; s3dirent_t new_arr[entries+1]; int i=0; for(;i<entries;i++) { printf("ADDING TO NEW ARR %s at %d\n", dirs[i].name, i); new_arr[i] = dirs[i]; } new_arr[i] = new_dirent; printf("ADDING TO NEW ARR %s at %d\n", new_dirent.name, i); s3fs_put_object(s3bucket, directory, (uint8_t*)&new_arr, sizeof(s3dirent_t)*(entries+1)); //missing frees free(init_dirs); return 0; }
/* * Change the size of an open file. Very similar to fs_truncate (and, * depending on your implementation), you could possibly treat it the * same as fs_truncate. */ int fs_ftruncate(const char *path, off_t offset, struct fuse_file_info *fi) { char * dir_name = dirname(strdup(path)); char * base_name = basename(strdup(path)); ssize_t ret_val = 0; uint8_t * buffer = NULL; s3context_t *ctx = GET_PRIVATE_DATA; size_t path_len = strlen(path); char * file_content_key = (char *)malloc(path_len + 2); // no point of multiplying by sizeof(char) // since the below code assumes ANSI anyways file_content_key[0] = '~'; memcpy(&file_content_key[1], path, path_len); file_content_key[path_len + 1] = '\0'; ret_val = s3fs_get_object(ctx->s3bucket, file_content_key, &buffer, 0, 0); if (NULL != buffer) { free(buffer); } if (0 > ret_val) { free(file_content_key); return -ENOENT; } ret_val = s3fs_put_object(ctx->s3bucket, file_content_key, NULL, 0); free(file_content_key); // set the new size and times ret_val = s3fs_get_object(ctx->s3bucket, dir_name, &buffer, 0, 0); if (0 > ret_val) { return -EIO; } s3dirent_t * entries = (s3dirent_t *)buffer; int dirent_count = ret_val / sizeof(s3dirent_t); int i = 0; time_t current_time = time(NULL); for (; i < dirent_count; i++) { if (0 == strncmp(entries[i].name, base_name, 256)) { entries[i].size = 0; entries[i].atime = current_time; entries[i].mtime = current_time; if (-1 == s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t *)buffer, ret_val)) { free(buffer); return -EIO; } free(buffer); return 0; } } free(buffer); return -EIO; }
/* * Create a file "node". When a new file is created, this * function will get called. * This is called for creation of all non-directory, non-symlink * nodes. You *only* need to handle creation of regular * files here. (See the man page for mknod (2).) */ int fs_mknod(const char *path, mode_t mode, dev_t dev) { fprintf(stderr, "fs_mknod(path=\"%s\", mode=0%3o)\n", path, mode); s3context_t *ctx = GET_PRIVATE_DATA; char* s3bucket = (char*)ctx; s3dirent_t* dirs = NULL; ssize_t size = s3fs_get_object(s3bucket, path, (uint8_t**)&dirs, 0, 0); if (size >= 0) { printf("This File Already Exists!\n"); return -EIO; } char* copy_path_1 = strdup(path); char* copy_path_2 = strdup(path); char* directory = dirname(copy_path_1); printf("DIRECTORY = %s\n", directory); char* base = basename(copy_path_2); printf("BASE = %s\n", base); // PUT a new file object containing empty content FILE* f = fopen(base,"a+"); if ( s3fs_put_object(s3bucket, path, (uint8_t*)f, sizeof(f) ) < 0 ) { return -EIO; } printf("JUST ADDED NEW FILE OBJECT WITH KEY %s\n", path); // add to end of directory size = s3fs_get_object(s3bucket, directory, (uint8_t**)&dirs, 0, 0); if (size < 0) { return -EIO; } int entries = size/sizeof(s3dirent_t); printf("NUM ENTRIES mknod %d\n", entries); s3dirent_t file_obj; file_obj.name = base; file_obj.type = 'F'; file_obj.protection = mode; file_obj.user_id = getuid(); file_obj.group_id = getgid(); file_obj.hard_links = 0; file_obj.size = sizeof(f); file_obj.last_access = time(0); file_obj.mod_time = time(0); file_obj.status_change = time(0); s3dirent_t new_arr[entries+1]; int i=0; for(;i<entries;i++) { printf("ADDING TO NEW ARR %s at %d\n", dirs[i].name, i); new_arr[i] = dirs[i]; } new_arr[i] = file_obj; printf("ADDING TO NEW NEW ARR %s at %d\n", file_obj.name, i); s3fs_put_object(s3bucket, directory, (uint8_t*)&new_arr, sizeof(s3dirent_t)*(entries+1)); return 0; }
/* STEP 1 * Remove a directory. */ int fs_rmdir(const char *path) { char * dir_name = dirname(strdup(path)); char * base_name = basename(strdup(path)); ssize_t ret_val = 0; uint8_t * buffer = NULL; fprintf(stderr, "fs_rmdir(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; ret_val = s3fs_get_object(ctx->s3bucket, path, &buffer, 0, 0); if (0 > ret_val) { return -ENOENT; } free(buffer); if (sizeof(s3dirent_t) != ret_val) { // more than one entry, I chose to use EINVAL here return -EINVAL; } if (0 != s3fs_remove_object(ctx->s3bucket, path)) { return -EIO; } ret_val = s3fs_get_object(ctx->s3bucket, dir_name, &buffer, 0, 0); if (0 > ret_val) { // no parent return -EIO; } // make room for all entries but the deleted directory s3dirent_t * new_parent_dir = (s3dirent_t *)malloc(ret_val - sizeof(s3dirent_t)); s3dirent_t * entries = (s3dirent_t *)buffer; int dirent_count = ret_val / sizeof(s3dirent_t); int i = 0; int copy_index = 0; for (; i < dirent_count; i++) { if (0 != strncmp(entries[i].name, base_name, 256) && (copy_index < (dirent_count - 1))) { memcpy(&new_parent_dir[copy_index], &entries[i], sizeof(s3dirent_t)); copy_index++; } } ret_val = s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t *)new_parent_dir, (dirent_count - 1) * sizeof(s3dirent_t)); if (-1 == ret_val) { free(new_parent_dir); return -EIO; } free(new_parent_dir); return 0; }
/* * Change the size of a file. */ int fs_truncate(const char *path, off_t newsize) { fprintf(stderr, "fs_truncate(path=\"%s\", newsize=%d)\n", path, (int)newsize); s3context_t *ctx = GET_PRIVATE_DATA; uint8_t *dir = NULL; char *temp_path = strdup(path), *temp_path1 = strdup(path); char *dir_name = strdup(dirname(temp_path)), *base_name = strdup(basename(temp_path1)); free(temp_path); free(temp_path1); if(s3fs_get_object(ctx->s3bucket, path, &dir, 0, 0)<0) { fprintf(stderr, "INVALID PATH: fs_truncate\n"); free(base_name); free(dir_name); return -ENOENT; } char *file = (char *)dir; file = realloc(file, 0); /*if(s3fs_remove_object(ctx->s3bucket, path)!=0) { fprintf(stderr, "error removing object\n"); free(base_name); free(dir_name); return -EIO; }*/ if(s3fs_put_object(ctx->s3bucket, path, file, 0) != 0) { fprintf(stderr, "error putting on truncated file\n"); free(base_name); free(dir_name); return -EIO; } free(file); uint8_t *dir1 = NULL; ssize_t dir_size; if((dir_size=s3fs_get_object(ctx->s3bucket, dir_name, &dir1, 0, 0))< 0) { fprintf(stderr, "ERROR PULLING PARENT DIRECTORY\n"); free(base_name); free(dir_name); return -EIO; } s3dirent_t *dirent = (s3dirent_t *)dir1; int i = 0; for(;i<dir_size/sizeof(s3dirent_t);i++) { if(!strcmp(base_name, dirent[i].name)) { dirent[i].metadata.st_size = 0; printf("size of file in directory: %d\n", dirent[i].metadata.st_size); break; } } printf("new size of parent directory: %d\n",sizeof(*dirent)); if(s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t*)dirent, sizeof(*dirent))!=sizeof(*dirent)) { fprintf(stderr, "Error putting object back: fs_truncate\n"); free(dirent);free(dir_name); free(base_name); return -EIO; } free(dirent); free(dir_name); free(base_name); return 0; }
/* * Read directory. See the project description for how to use the filler * function for filling in directory items. */ int fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { fprintf(stderr, "fs_readdir(path=\"%s\", buf=%p, offset=%d)\n", path, buf, (int)offset); s3context_t *ctx = GET_PRIVATE_DATA; char* temp_path = strdup(path); uint8_t *dir = NULL; ssize_t dir_size = NULL; if((dir_size = s3fs_get_object(ctx->s3bucket, temp_path, &dir, 0,0))<0) { fprintf(stderr, "CANNOT READ FILE: fs_readdir\n"); free(temp_path); return -EIO; } s3dirent_t *directory = (s3dirent_t *)dir; if(directory[0].type != 'D') { fprintf(stderr, "NOT A DIRECTORY!:fs_readdir\n"); free(directory); free(temp_path);return -EIO; } int numdirent = dir_size/sizeof(s3dirent_t), i = 0; for(;i<numdirent;i++) { if(filler(buf, directory[i].name, NULL, 0) != 0) { free(directory);free(temp_path); return -ENOMEM; } } free(directory); free(temp_path); return 0; }
/* * Read data from an open file * * Read should return exactly the number of bytes requested except * on EOF or error, otherwise the rest of the data will be * substituted with zeroes. */ int fs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { fprintf(stderr, "fs_read(path=\"%s\", buf=%p, size=%d, offset=%d)\n", path, buf, (int)size, (int)offset); s3context_t *ctx = GET_PRIVATE_DATA; uint8_t *file = NULL; ssize_t file_size, new_size; int i = offset; if((file_size = s3fs_get_object(ctx->s3bucket, path, &file, 0,0))<0) { fprintf(stderr, "INVALID PATH: fs_read\n"); return -ENOENT; } char *file_data = strdup((char *)file); if(offset+size > file_size) { new_size = offset + size; for(;i<file_size;i++) { buf[i] = file_data[i]; } for(;i<new_size;i++) { buf[i] = 0; } }else { new_size = file_size; for(;i<new_size;i++) { buf[i] = file_data[i]; } } free(file_data); return new_size; }
/* * Find what type of file path, return 1 on directory, 2 on file, 0 if * it does not exist */ int fs_findtype( char *path){ char parent[1024]; char file[1024]; char cpy[1024]; strcpy(cpy,path); strcpy(file, basename(cpy)); strcpy(parent,dirname(cpy)); if(!strcmp(path,"/")){//if looking for root strcpy(file, "."); } uint8_t * buff; int rv = s3fs_get_object(getenv(S3BUCKET), parent, &buff, 0, 0); int dirsize = (rv)/(sizeof(s3dirent_t)); s3dirent_t * parentdir = (s3dirent_t*)buff; int i = 0; fprintf(stderr, "\n%d\n", rv); parentdir[0].atime = time(NULL);// update access time s3fs_put_object(getenv(S3BUCKET), parent, (uint8_t*) parentdir, parentdir[0].st_size); for(;i<dirsize;i++){ fprintf(stderr, "FILE\n%s\n%s\n%s\n", file,parent,parentdir[i].name); if (!(strcmp(parentdir[i].name,file))){ if (parentdir[i].type == 'd'){ free(parentdir); return 1; } free(parentdir); return 2; //assuming that filetype is not corrupted --> may want to add check/ handling later } } free(parentdir); return 0; }
/* * File open operation * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC) * will be passed to open(). Open should check if the operation * is permitted for the given flags. * * Optionally open may also return an arbitrary filehandle in the * fuse_file_info structure (fi->fh). * which will be passed to all file operations. * (In stages 1 and 2, you are advised to keep this function very, * very simple.) */ int fs_open(const char *path, struct fuse_file_info *fi) { char * dir_name = dirname(strdup(path)); char * base_name = basename(strdup(path)); uint8_t * buffer = NULL; ssize_t ret_val = 0; fprintf(stderr, "fs_open(path\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; size_t path_len = strlen(path); char * file_content_key = (char *)malloc(path_len + 2); // no point of multiplying by sizeof(char) // since the below code assumes ANSI anyways file_content_key[0] = '~'; memcpy(&file_content_key[1], path, path_len); file_content_key[path_len + 1] = '\0'; ret_val = s3fs_get_object(ctx->s3bucket, file_content_key, &buffer, 0, 0); if (NULL != buffer) { free(buffer); } free(file_content_key); if (0 > ret_val) { return -ENOENT; } return 0; }
/* * Remove a file. */ int fs_unlink(const char *path) { fprintf(stderr, "fs_unlink(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; char* cpy_path_1 = strdup(path); char* cpy_path_2 = strdup(path); char* d = dirname(cpy_path_1); char* b = basename(cpy_path_2); char* s3bucket = (char*)ctx; s3dirent_t* dirs_rem = NULL; ssize_t size = s3fs_get_object(s3bucket, d, (uint8_t**)&dirs_rem, 0, 0); if (size<0) { return -EIO; // directory does not exist } int entries = size/sizeof(s3dirent_t); s3dirent_t arr[entries-1]; int i=0; int k=0; for (;i<entries;i++) { if (strcasecmp(dirs_rem[i].name,b) != 0) { arr[k] = dirs_rem[i]; k++; } } s3fs_put_object(s3bucket, d, (uint8_t*)&arr, ((sizeof(s3dirent_t))*(entries-1))); s3fs_remove_object(s3bucket, path); return 0; }
/* * Read data from an open file * * Read should return exactly the number of bytes requested except * on EOF or error, otherwise the rest of the data will be * substituted with zeroes. */ int fs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { ssize_t ret_val = 0; uint8_t * buffer = NULL; fprintf(stderr, "fs_read(path=\"%s\", buf=%p, size=%d, offset=%d)\n", path, buf, (int)size, (int)offset); s3context_t *ctx = GET_PRIVATE_DATA; size_t path_len = strlen(path); char * file_content_key = (char *)malloc(path_len + 2); // no point of multiplying by sizeof(char) // since the below code assumes ANSI anyways file_content_key[0] = '~'; memcpy(&file_content_key[1], path, path_len); file_content_key[path_len + 1] = '\0'; ret_val = s3fs_get_object(ctx->s3bucket, file_content_key, &buffer, offset, 0); free(file_content_key); if (0 == ret_val) { return 0; } else if (0 > ret_val) { memset(buf, 0, size); return -1; } if (size > ret_val) { size = ret_val; } memcpy(buf, buffer, size); free(buffer); return size; }
/* STEP 1 * Read directory. See the project description for how to use the filler * function for filling in directory items. */ int fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { ssize_t ret_val = 0; uint8_t * buffer = NULL; s3dirent_t * dir = NULL; fprintf(stderr, "fs_readdir(path=\"%s\", buf=%p, offset=%d)\n", path, buf, (int)offset); s3context_t *ctx = GET_PRIVATE_DATA; ret_val = s3fs_get_object(ctx->s3bucket, path, &buffer, 0, 0); if (0 > ret_val) { return -ENOENT; } dir = (s3dirent_t *)buffer; int dirent_count = ret_val / sizeof(s3dirent_t); int i = 0; for (; i < dirent_count; i++) { if (0 != filler(buf, dir[i].name, NULL, 0)) { free(buffer); return -ENOMEM; } } if (NULL != buffer) { free(buffer); } return 0; }
/* * Remove a directory. */ int fs_rmdir(const char *path) { fprintf(stderr, "fs_rmdir(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; char* s3bucket = (char*)ctx; s3dirent_t* dirs_r = NULL; ssize_t s = s3fs_get_object(s3bucket, path, (uint8_t**)&dirs_r, 0, 0); if (s<0) { free(dirs_r); return -EIO; // directory does not exist } int e = s/sizeof(s3dirent_t); if (e>1) { free(dirs_r); return -EIO; // there is more than one thing in this } char* cpy_path_1 = strdup(path); char* cpy_path_2 = strdup(path); char* d = dirname(cpy_path_1); char* b = basename(cpy_path_2); s3dirent_t* dirs_rem = NULL; ssize_t size = s3fs_get_object(s3bucket, d, (uint8_t**)&dirs_rem, 0, 0); if (size<0) { free(dirs_r); return -EIO; // directory does not exist } int entries = size/sizeof(s3dirent_t); printf("NUM ENTRIES IN REMOVE IS %d\n", entries); s3dirent_t arr[entries-1]; int i=0; int k=0; for (;i<entries;i++) { printf("NAME? in remove %s\n", dirs_rem[i].name); printf("base name is %s\n", b); if (strcasecmp(dirs_rem[i].name,b) != 0) { printf("NOT THE SAME!\n"); arr[k] = dirs_rem[i]; k++; } } printf("ADDING TO NEW ARR IN REM\n"); s3fs_put_object(s3bucket, d, (uint8_t*)&arr, ((sizeof(s3dirent_t))*(entries-1))); printf("REMOVING OBJECT (PATH) %s\n", path); s3fs_remove_object(s3bucket, path); free(dirs_r); return 0; }
int fs_getattr(const char *path, struct stat *statbuf) { fprintf(stderr, "fs_getattr(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; uint8_t *dir = NULL, *dir1 = NULL; int i = 0; char *temp_path1 = strdup(path), *temp_path2 = strdup(path), *temp_path3 = strdup(path); char *dir_name = strdup(dirname(temp_path1)), *base_name = strdup(basename(temp_path2)); free(temp_path1); free(temp_path2); ssize_t dir_size; if(s3fs_get_object(ctx->s3bucket, temp_path3, &dir1, 0,0)< 0) { fprintf(stderr,"INVALID PATH: fs_getattr\n"); free(dir_name); free(base_name); free(temp_path3); return -ENOENT; } if(!strcmp(path, "/")) { s3dirent_t *directory = (s3dirent_t *)dir1; *statbuf = directory[0].metadata; free(directory); free(dir_name); free(base_name); return 0; } if((dir_size = s3fs_get_object(ctx->s3bucket, dir_name, &dir, 0,0))<0) { fprintf(stderr, "INVALID PATH: fs_getattr\n"); free(temp_path3); free(base_name); free(dir_name); return -ENOENT; }else { s3dirent_t *direct = (s3dirent_t*)dir; for(;i<dir_size/sizeof(s3dirent_t);i++) { if(!strcmp(direct[i].name,base_name)) { if(direct[i].type == 'D') { s3dirent_t *new_dirent = (s3dirent_t *)dir1; *statbuf = new_dirent[0].metadata; free(new_dirent); free(direct); free(temp_path3); free(base_name); free(dir_name); return 0; } printf("FOUND A FILE\n"); *statbuf = direct[i].metadata; free(direct); free(temp_path3); free(base_name); free(dir_name); free(dir1); return 0; } } fprintf(stderr, "FS_GETATTR: path not found\n"); free(direct);free(temp_path3); free(base_name); free(dir_name);free(dir1); return -ENOENT; } }
/* * File open operation * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC) * will be passed to open(). Open should check if the operation * is permitted for the given flags. * * Optionally open may also return an arbitrary filehandle in the * fuse_file_info structure (fi->fh). * which will be passed to all file operations. * (In stages 1 and 2, you are advised to keep this function very, * very simple.) */ int fs_open(const char *path, struct fuse_file_info *fi) { fprintf(stderr, "fs_open(path\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; char* s3bucket = (char*)ctx; s3dirent_t* f_dirs = NULL; ssize_t size = s3fs_get_object(s3bucket, path, (uint8_t**)&f_dirs, 0, 0); if (size>=0){ return 0; } return -EIO; }
/* * Open directory * * This method should check if the open operation is permitted for * this directory */ int fs_opendir(const char *path, struct fuse_file_info *fi) { fprintf(stderr, "fs_opendir(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; uint8_t *dir; if(s3fs_get_object(ctx->s3bucket, path, &dir, 0,0) < 0) { fprintf(stderr, "CANNOT ACCESS DIRECTORY: fs_opendir fail\n"); return -EIO; } free(dir); return 0; }
/* * File open operation * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC) * will be passed to open(). Open should check if the operation * is permitted for the given flags. * * Optionally open may also return an arbitrary filehandle in the * fuse_file_info structure (fi->fh). * which will be passed to all file operations. * (In stages 1 and 2, you are advised to keep this function very, * very simple.) */ int fs_open(const char *path, struct fuse_file_info *fi) { fprintf(stderr, "fs_open(path\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; uint8_t* file; if(s3fs_get_object(ctx->s3bucket, path, &file, 0,0)<0) { fprintf(stderr, "INVALID PATH\n"); return -ENOENT; } free(file); return 0; }
/* * Read data from an open file * * Read should return exactly the number of bytes requested except * on EOF or error, otherwise the rest of the data will be * substituted with zeroes. */ int fs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { fprintf(stderr, "fs_read(path=\"%s\", buf=%p, size=%d, offset=%d)\n", path, buf, (int)size, (int)offset); s3context_t *ctx = GET_PRIVATE_DATA; char* s3bucket = (char*)ctx; s3dirent_t* read_f_dirs = NULL; ssize_t size_obj = s3fs_get_object(s3bucket, path, (uint8_t**)&buf, offset, size); if (size_obj<0){ return -EIO; printf("This path does not exist!"); } return 0; }
/* * Check file access permissions. For now, just return 0 (success!) * Later, actually check permissions (don't bother initially). */ int fs_access(const char *path, int mask) { fprintf(stderr, "fs_access(path=\"%s\", mask=0%o)\n", path, mask); s3context_t *ctx = GET_PRIVATE_DATA; uint8_t *dir = NULL, *direct = NULL; ssize_t dir_size; if(s3fs_get_object(ctx->s3bucket, path, &dir, 0,0)<0) { fprintf(stderr, "error retrieving object\n"); return -EIO; } char *temp_path = strdup(path), *temp_path1 = strdup(path); char *dir_name = strdup(dirname(temp_path)), *base_name = strdup(basename(temp_path1)); free(temp_path); free(temp_path1); if((dir_size=s3fs_get_object(ctx->s3bucket, dir_name, &direct, 0,0))<0) { fprintf(stderr, "error retrieving object\n"); return -EIO; } int i = 0; s3dirent_t *dirent = (s3dirent_t*)direct; s3dirent_t *dir1 = (s3dirent_t*)dir; for(;i<dir_size/sizeof(s3dirent_t);i++) { if(!strcmp(base_name, dirent[i].name)) { if(dirent[i].type == 'D') { if(dir1[0].metadata.st_mode ==(dir1[0].metadata.st_mode & mask)) { free(dir_name); free(base_name); free(dir1); free(dirent); return 0; } }else { if(dirent[i].metadata.st_mode == (dirent[i].metadata.st_mode & mask)) { free(dir_name); free(base_name); free(dir1); free(dirent); return 0; } } } } //we assumed logical and would make the most sense becuase it would match up with //the bits you want. However we could not figure it out in time. return 0; }
/* * File open operation * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC) * will be passed to open(). Open should check if the operation * is permitted for the given flags. * * Optionally open may also return an arbitrary filehandle in the * fuse_file_info structure (fi->fh). * which will be passed to all file operations. * (In stages 1 and 2, you are advised to keep this function very, * very simple.) */ int fs_open(const char *path, struct fuse_file_info *fi) { //sommers code fprintf(stderr, "fs_open(path\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; //our code s3dirent_t * dir; if (s3fs_get_object(ctx->s3bucket, path, (uint8_t **)&dir, 0,0)<0) //if not a real directory { fprintf(stderr, "file does not exist"); return -EEXIST; } return 0; }
/* * Write data to an open file * * Write should return exactly the number of bytes requested * except on error. */ int fs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { fprintf(stderr, "fs_write(path=\"%s\", buf=%p, size=%d, offset=%d)\n", path, buf, (int)size, (int)offset); s3context_t *ctx = GET_PRIVATE_DATA; char* s3bucket = (char*)ctx; FILE* f = NULL; ssize_t size_obj = s3fs_get_object(s3bucket, path, (uint8_t**)&f, offset, size); if (size_obj<0){ return -EIO; } fseek(f,offset,SEEK_SET); fwrite(buf,1,size,f); return 0; }
/* * Read data from an open file * * Read should return exactly the number of bytes requested except * on EOF or error, otherwise the rest of the data will be * substituted with zeroes. */ int fs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { //sommers code fprintf(stderr, "fs_read(path=\"%s\", buf=%p, size=%d, offset=%d)\n", path, buf, (int)size, (int)offset); s3context_t *ctx = GET_PRIVATE_DATA; //our code if (s3fs_get_object(ctx->s3bucket, path, (uint8_t **)&buf, offset,size)<0) //if not a real directory { fprintf(stderr, "failed to read file"); return -EIO; } return 0; }
/* STEP 1 * Open directory * * This method should check if the open operation is permitted for * this directory */ int fs_opendir(const char *path, struct fuse_file_info *fi) { ssize_t ret_val = 0; uint8_t * buffer = NULL; fprintf(stderr, "fs_opendir(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; ret_val = s3fs_get_object(ctx->s3bucket, path, &buffer, 0, 0); if (0 > ret_val) { return -ENOENT; } if (NULL != buffer) { free(buffer); } }
/* * Remove a file. */ int fs_unlink(const char *path) { fprintf(stderr, "fs_unlink(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; ssize_t dir_size; int i = 0, j = 0; uint8_t *dir; if(fs_open(path, (struct fuse_file_info *)NULL) != 0) { fprintf(stderr, "INVALID PATH\n"); return -ENOENT; } char *temp_path1 = strdup(path), *temp_path2 = strdup(path); char *dir_name = strdup(dirname(temp_path1)), *base_name = strdup(basename(temp_path2)); free(temp_path1); free(temp_path2); dir_size=s3fs_get_object(ctx->s3bucket, dir_name, &dir, 0, 0); s3dirent_t* direct = (s3dirent_t*)dir; for(;i<dir_size/sizeof(s3dirent_t);i++) { if(!strcmp(direct[i].name, base_name)) { i++; break; } } for(;i<dir_size/sizeof(s3dirent_t);i++) { j = i-1; direct[j] = direct[i]; } s3dirent_t* new_dir; ssize_t new_dir_size; new_dir = malloc(dir_size - sizeof(s3dirent_t)); memcpy(new_dir, direct, dir_size - sizeof(s3dirent_t)); new_dir_size = dir_size - sizeof(s3dirent_t); printf("dir_size: %d new_dir_size: %d\n", dir_size, new_dir_size); printf("updated directory from file remove path: %s\n",dir_name); if(s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t*)new_dir, new_dir_size)!= new_dir_size) { fprintf(stderr, "SOMETHING WENT WRONG WHILE PUTTING TO S3: fs_unlink\n"); free(new_dir); free(direct); free(base_name); free(dir_name); return -EIO; } if(s3fs_remove_object(ctx->s3bucket, path) != 0) { fprintf(stderr, "ERROR WHILE TRYING TO DELTE FILE: fs_unlink"); free(new_dir); free(direct); free(base_name); free(dir_name); return -EIO; } free(new_dir); free(direct); free(base_name); free(dir_name); return 0; }
/* * Read directory. See the project description for how to use the filler * function for filling in directory items. */ int fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { fprintf(stderr, "fs_readdir(path=\"%s\", buf=%p, offset=%d)\n", path, buf, (int)offset); s3context_t *ctx = GET_PRIVATE_DATA; char* s3bucket = (char*)ctx; s3dirent_t* dirs_to_read = NULL; ssize_t size = s3fs_get_object(s3bucket, path, (uint8_t**)&dirs_to_read, 0, 0); int entries = size/sizeof(s3dirent_t); int i=0; for (;i<entries;i++) { if (filler(buf,dirs_to_read[i].name,NULL,0) != 0) { free(dirs_to_read); return -EIO; } } free(dirs_to_read); return 0; }
/* * Read directory. See the project description for how to use the filler * function for filling in directory items. */ int fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { //sommers code fprintf(stderr, "fs_readdir(path=\"%s\", buf=%p, offset=%d)\n", path, buf, (int)offset); s3context_t *ctx = GET_PRIVATE_DATA; //our code s3dirent_t * dir = NULL; if (s3fs_get_object(ctx->s3bucket, path, (uint8_t **)&dir, 0,0)<0) //if not a real directory, else store in dir { fprintf(stderr, "path is not valid"); free(dir); return -EIO; } //check to make sure it is a directory /*if (strcmp((*dir).type, "D")!=0) { fprintf(stderr, "not a real directory"); return -EIO; }*/ int i = 0; printf("%s", "dirarray[i].type: "); printf("%s", dir[i].type); while(strcmp((dir[i].type),"U")!=0) { //call filler function to fill in directory name to supplied buffer if(filler(buf,dir[i].name, NULL, 0) != 0) { free(dir); return -ENOMEM; } i++; } free(dir); //free malloced dir printf("%s\n","-----READDIR FINISHED-------------"); return 0; }
/* * Open directory * * This method should check if the open operation is permitted for * this directory */ int fs_opendir(const char *path, struct fuse_file_info *fi) { //sommers code fprintf(stderr, "fs_opendir(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; //our code s3dirent_t * dir = NULL; if (s3fs_get_object(ctx->s3bucket, path, (uint8_t **)&dir, 0,0)<0) //if not a real directory, else store in dir { fprintf(stderr, "path is not valid"); return -EIO; } //check to see if the type == "directory" if (strcmp((*dir).type, "D")!=0) { fprintf(stderr, "not a real directory"); free(dir); return -EIO; } printf("%s\n","----finished opendir-------"); free(dir); return 0; }
/* * Write data to an open file * * Write should return exactly the number of bytes requested * except on error. */ int fs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { char * dir_name = dirname(strdup(path)); char * base_name = basename(strdup(path)); ssize_t ret_val = 0; uint8_t * buffer = NULL; fprintf(stderr, "fs_write(path=\"%s\", buf=%p, size=%d, offset=%d)\n", path, buf, (int)size, (int)offset); s3context_t *ctx = GET_PRIVATE_DATA; size_t path_len = strlen(path); char * file_content_key = (char *)malloc(path_len + 2); // no point of multiplying by sizeof(char) // since the below code assumes ANSI anyways file_content_key[0] = '~'; memcpy(&file_content_key[1], path, path_len); file_content_key[path_len + 1] = '\0'; ret_val = s3fs_get_object(ctx->s3bucket, file_content_key, &buffer, 0, 0); if (0 > ret_val) { free(file_content_key); return -ENOENT; } int new_buffer_size = ret_val + size; uint8_t * new_buffer = (uint8_t *)malloc(new_buffer_size); if (offset > ret_val) { offset = ret_val; } memcpy(&new_buffer[offset], buf, size); if (0 != offset) { memcpy(new_buffer, buffer, offset); } if (offset < ret_val) { memcpy(&new_buffer[offset + size], &buffer[offset], ret_val - offset); } free(buffer); ret_val = s3fs_put_object(ctx->s3bucket, file_content_key, (uint8_t *)new_buffer, new_buffer_size); free(file_content_key); free(new_buffer); if (-1 == ret_val) { return -1; } // set the new size and times ret_val = s3fs_get_object(ctx->s3bucket, dir_name, &buffer, 0, 0); if (0 > ret_val) { return -EIO; } s3dirent_t * entries = (s3dirent_t *)buffer; int dirent_count = ret_val / sizeof(s3dirent_t); int i = 0; time_t current_time = time(NULL); for (; i < dirent_count; i++) { if (0 == strncmp(entries[i].name, base_name, 256)) { entries[i].size = new_buffer_size; entries[i].atime = current_time; entries[i].mtime = current_time; if (-1 == s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t *)buffer, ret_val)) { free(buffer); return -EIO; } free(buffer); return size; } } free(free(buffer); return -EIO; }