/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * Initialize the file system. This is called once upon * file system startup. */ void *fs_init(struct fuse_conn_info *conn) { fprintf(stderr, "fs_init --- initializing file system.\n"); s3context_t *ctx = GET_PRIVATE_DATA; if(s3fs_clear_bucket(ctx->s3bucket)!=0) { fprintf(stderr, "Failed to initialize file system: Error clearing bucket"); return -EIO; } s3dirent_t root; struct stat meta;//= malloc(sizeof(struct stat)); meta.st_mode = (S_IFDIR | S_IRWXU); meta.st_nlink = 1; meta.st_uid = getuid(); meta.st_gid = getgid(); struct timeval tv; time_t the_time; gettimeofday(&tv, NULL); the_time = tv.tv_sec; meta.st_atime = the_time; meta.st_mtime = the_time; meta.st_ctime = the_time; strcpy(root.name, "."); root.num_entries = 1; root.type = 'D'; root.metadata = meta; root.metadata.st_size = sizeof(s3dirent_t); printf("ROOT PERMISSIONS: %o\n",root.metadata.st_mode); if(s3fs_put_object(ctx->s3bucket, "/", (uint8_t *)&root, sizeof(root)) != sizeof(root)) { fprintf(stderr, "PUT OBJECT FAILED IN FS_INIT"); return ctx; } printf("init worked? \n"); return ctx; }
/* STEP 1 * Initialize the file system. This is called once upon * file system startup. */ void *fs_init(struct fuse_conn_info *conn) { ssize_t ret_val = 0; time_t current_time = time(NULL); fprintf(stderr, "fs_init --- initializing file system.\n"); s3context_t *ctx = GET_PRIVATE_DATA; s3fs_clear_bucket(ctx->s3bucket); s3dirent_t * root_dir = (s3dirent_t *)malloc(sizeof(s3dirent_t)); root_dir->type = S3FS_TYPE_DIR; memset(root_dir->name, 0, 256); strncpy(root_dir->name, ".", 1); root_dir->mode = ROOT_DIR_MODE; root_dir->nlink = 0; root_dir->uid = fuse_get_context()->uid; root_dir->gid = fuse_get_context()->gid; root_dir->size = 0; root_dir->blocks = 0; root_dir->atime = current_time; root_dir->mtime = current_time; root_dir->ctime = current_time; ret_val = s3fs_put_object(ctx->s3bucket, "/", (uint8_t *)root_dir, sizeof(s3dirent_t)); if (-1 == ret_val) { free(root_dir); return NULL; } free(root_dir); return ctx; }
/* * 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; }
/* 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; }
/* * 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; }
/* * 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; }
/* * Initialize the file system. This is called once upon * file system startup. */ void *fs_init(struct fuse_conn_info *conn) { fprintf(stderr, "fs_init --- initializing file system.\n"); s3context_t *ctx = GET_PRIVATE_DATA; char* s3bucket = (char*)ctx; s3fs_clear_bucket(s3bucket); s3dirent_t root_dir; root_dir.type = 'D'; root_dir.name = "."; char* key = "/"; root_dir.protection = S_IFDIR; root_dir.type = 'D'; root_dir.user_id = getuid(); root_dir.group_id = getgid(); root_dir.hard_links = 0; root_dir.size = 0; root_dir.last_access = time(NULL); root_dir.mod_time = time(NULL); root_dir.status_change = time(NULL); s3fs_put_object(s3bucket, key, (uint8_t*)&root_dir, sizeof(s3dirent_t)); return ctx; }
/* * Initialize the file system. This is called once upon * file system startup. */ void *fs_init(struct fuse_conn_info *conn) //ALMOST DONE { //sommers code fprintf(stderr, "fs_init --- initializing file system.\n"); s3context_t *ctx = GET_PRIVATE_DATA; //our code //need to completely destroy everything in this bucket s3fs_clear_bucket(ctx->s3bucket); //not sure about parameter //do we need to check that the clear did not fail? //create a directory object to represent your root directory and store that on S3 s3dirent_t dir[2]; //create directory structur time_t temp; //create temporory timestamp time(&temp); //get current time strcpy(dir[0].name, "."); //set name of directory to ".". dir[0].size = sizeof(s3dirent_t); //set directory size to size of s3dirent struct strcpy(dir[0].type,"D"); //set diretory type to directory dir[0].timeAccess = temp; //set directory last access time to temp dir[0].timeMod = temp; //set directory last modified time to temp dir[0].userID = getuid(); //get user ID dir[0].groupID = getgid(); //get group ID dir[0].protection = (S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR); strcpy(dir[1].type, "U"); //set type to unused, indicating end //initialize object (put object in s3), unless fail. then return error if ((s3fs_put_object(ctx->s3bucket, "/", (const uint8_t *)&dir, sizeof(dir)))!=sizeof(dir)) { fprintf(stderr, "failed to intialize"); return -EIO; } //everything worked as planned. continue printf("%s\n","-------FINISHED INIT-------"); return ctx; }
/* * 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; ssize_t dir_size, dir_size1; uint8_t *dir = NULL, *dir1 = NULL; char type; int i = 0, j = NULL; char *temp_path = strdup(path), *temp_path1 = strdup(path), *temp_new_path1 = strdup(newpath), *temp_new_path2=strdup(newpath); char* dir_name = strdup(dirname(temp_path)), *base_name = strdup(basename(temp_path1)); char *new_dir_name=strdup(dirname(temp_new_path1)), *new_base_name = strdup(basename(temp_new_path2)); char *temp_new_path3=strdup(newpath); free(temp_path); free(temp_path1); free(temp_new_path1); free(temp_new_path2); if(!strcmp("/", path)) { fprintf(stderr,"CANNOT RENAME ROOT DIRECTORY: fs_rename\n"); free(dir_name); free(base_name); free(new_dir_name); free(new_base_name); return -EPERM; } if((dir_size1=s3fs_get_object(ctx->s3bucket, path, &dir1, 0, 0))>=0) { printf("PATH TO REMOVE IN FS_RENAME DIRECTORY: %s\n",path); if((dir_size=s3fs_get_object(ctx->s3bucket, dir_name, &dir, 0, 0))<0) { fprintf(stderr, "INVALID PATH: fs_rename\n"); free(base_name); free(dir_name); free(new_dir_name); free(new_base_name);free(temp_new_path3);free(dir1); return -ENOENT; } s3dirent_t *dirent = (s3dirent_t*)dir; for(;i<dir_size/sizeof(s3dirent_t);i++) { if(!strcmp(dirent[i].name, base_name)) { j = i; }else if(!strcmp(dirent[i].name, new_base_name)) { fprintf(stderr, "FILE NAME ALREADY USED: fs_rename\n"); free(base_name); free(dir_name); free(new_dir_name); free(new_base_name); free(dirent);free(temp_new_path3); free(dir1); return -EEXIST; } } if(j==NULL) { fprintf(stderr, "INVALID PATH: fs_rename\n"); free(base_name); free(dir_name); free(new_dir_name); free(new_base_name);free(temp_new_path3);free(dir1); return -ENOENT; } strcpy(dirent[j].name,new_base_name); if(s3fs_put_object(ctx->s3bucket, new_dir_name, (uint8_t *)dirent, dir_size)!=dir_size) { fprintf(stderr, "ERROR WHILE PUTTING UPDATED DIRECTORY TO S3: fs_rename\n"); free(base_name); free(dir_name); free(new_dir_name); free(new_base_name); free(dirent); free(temp_new_path3); free(dir1); return -EIO; } if(s3fs_remove_object(ctx->s3bucket, path)!=0) { fprintf(stderr, "ERROR WHILE ERASING ORIGINAL DIRECTORY TO RENAME: fs_rename\n"); free(dirent); free(base_name); free(dir_name); free(new_dir_name); free(new_base_name);free(temp_new_path3); free(dir1); return -EIO; } if(s3fs_put_object(ctx->s3bucket, newpath, dir1, dir_size1)!=dir_size1) { fprintf(stderr, "ERROR WHILE PUTTING RENAMED OBJECT BACK: fs_rename\n"); free(dirent); free(base_name); free(dir_name); free(new_dir_name); free(new_base_name);free(temp_new_path3); free(dir1); return -EIO; } free(dirent); free(base_name); free(dir_name); free(new_dir_name); free(new_base_name);free(temp_new_path3); free(dir1); return 0; }else { fprintf(stderr, "INVALID PATH:fs_rename\n"); free(base_name); free(dir_name); free(new_dir_name); free(new_base_name); free(temp_new_path3); return -ENOENT; } }
/* * Remove a file. */ int fs_unlink(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_unlink(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 (0 > ret_val) { free(file_content_key); return -ENOENT; } free(buffer); if (0 != s3fs_remove_object(ctx->s3bucket, file_content_key)) { free(file_content_key); return -EIO; } free(file_content_key); // remove the entry ret_val = s3fs_get_object(ctx->s3bucket, dir_name, &buffer, 0, 0); s3dirent_t * entries = (s3dirent_t *)buffer; s3dirent_t * new_parent_dir = (s3dirent_t *)malloc(ret_val - sizeof(s3dirent_t)); int dirent_count = ret_val / sizeof(s3dirent_t); int i = 0, copy_index = 0; for (; i < dirent_count; i++) { if (0 != strncmp(entries[i].name, base_name, 256)) { memcpy(&new_parent_dir[copy_index], &entries[i], sizeof(s3dirent_t)); copy_index++; } } free(buffer); if (1 != (i - copy_index)) { free(new_parent_dir); return -EIO; } if (0 > s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t *)new_parent_dir, (ret_val - sizeof(s3dirent_t)))) { free(new_parent_dir); return -EIO; } free(new_parent_dir); return 0; }
/* STEP 1 * 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) { char * dir_name = dirname(strdup(path)); char * base_name = basename(strdup(path)); ssize_t ret_val = 0; uint8_t * buffer = NULL; fprintf(stderr, "fs_mkdir(path=\"%s\", mode=0%3o)\n", path, mode); s3context_t *ctx = GET_PRIVATE_DATA; mode |= S_IFDIR; ret_val = s3fs_get_object(ctx->s3bucket, path, &buffer, 0, 0); if (0 <= ret_val) { free(buffer); return -EEXIST; } s3dirent_t * new_dir = (s3dirent_t *)malloc(sizeof(s3dirent_t)); time_t current_time = time(NULL); new_dir->type = S3FS_TYPE_DIR; memset(new_dir->name, 0, 256); strncpy(new_dir->name, ".", 1); new_dir->mode = mode; new_dir->nlink = 0; new_dir->uid = fuse_get_context()->uid; new_dir->gid = fuse_get_context()->gid; new_dir->size = 0; new_dir->blocks = 0; new_dir->atime = current_time; new_dir->mtime = current_time; new_dir->ctime = current_time; ret_val = s3fs_put_object(ctx->s3bucket, path, (uint8_t *)new_dir, sizeof(s3dirent_t)); free(new_dir); if (-1 == ret_val) { return -EIO; } ret_val = s3fs_get_object(ctx->s3bucket, dir_name, &buffer, 0, 0); if (0 > ret_val) { return -EIO; } int dirent_count = ret_val / sizeof(s3dirent_t); s3dirent_t * new_parent_dir = (s3dirent_t *)malloc(sizeof(s3dirent_t) * (dirent_count + 1)); memset(new_parent_dir, 0, sizeof(s3dirent_t) * (dirent_count + 1)); memcpy(new_parent_dir, buffer, ret_val); free(buffer); strncpy(new_parent_dir[dirent_count].name, base_name, 256); ret_val = s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t *)new_parent_dir, (sizeof(s3dirent_t) * (dirent_count + 1))); if (-1 == ret_val) { free(new_parent_dir); return -EIO; } free(new_parent_dir); return 0; }
/* STEP 2 * 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) { char * dir_name = dirname(strdup(path)); char * base_name = basename(strdup(path)); uint8_t * buffer = NULL; ssize_t ret_val = 0; fprintf(stderr, "\n\n\n\nfs_mknod(path=\"%s\", mode=0%3o)\n\n\n\n\n", path, mode); s3context_t *ctx = GET_PRIVATE_DATA; // file content is stored at the S3 key of the path prefixed with ~ 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); free(buffer); if (0 <= ret_val) { free(file_content_key); return -EEXIST; } // check if parent exists ret_val = s3fs_get_object(ctx->s3bucket, dir_name, &buffer, 0, 0); if (0 > ret_val) { free(file_content_key); // again I chose EINVAL in case a file is being created without an existing parent folder return -EINVAL; } int dirent_count = ret_val / sizeof(s3dirent_t); s3dirent_t * new_parent_dir = (s3dirent_t *)malloc(ret_val + sizeof(s3dirent_t)); memcpy(new_parent_dir, buffer, ret_val); free(buffer); s3dirent_t * file_entry = (s3dirent_t *)malloc(sizeof(s3dirent_t)); time_t current_time = time(NULL); file_entry->type = S3FS_TYPE_FILE; memset(file_entry->name, 0, 256); strncpy(file_entry->name, base_name, strlen(base_name)); file_entry->mode = mode; file_entry->nlink = 0; file_entry->uid = fuse_get_context()->uid; file_entry->gid = fuse_get_context()->gid; file_entry->size = 0; file_entry->blocks = 0; file_entry->rdev = dev; file_entry->atime = current_time; file_entry->mtime = current_time; file_entry->ctime = current_time; memcpy(&new_parent_dir[dirent_count], file_entry, sizeof(s3dirent_t)); ret_val = s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t *)new_parent_dir, ret_val + sizeof(s3dirent_t)); free(new_parent_dir); free(file_entry); if (-1 == ret_val) { free(file_content_key); return -EIO; } ret_val = s3fs_put_object(ctx->s3bucket, file_content_key, NULL, 0); free(file_content_key); if (-1 == ret_val) { return -EIO; } return 0; }
/* * 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); printf("after initial function print\n"); s3context_t *ctx = GET_PRIVATE_DATA; printf("after get private data: fs_mknod\n"); uint8_t *file = NULL,*dir = NULL; if(s3fs_get_object(ctx->s3bucket, path, &file, 0, 0)>=0) { fprintf(stderr, "ALREADY A FILE WITH THAT NAME: fs_mknod\n"); free(file); return -EEXIST; } printf("after check for duplicate name\n"); 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)); ssize_t dir_size, new_dir_size; if((dir_size = s3fs_get_object(ctx->s3bucket, dir_name, &dir, 0,0))<0) { fprintf(stderr, "PARENT DIRECTORY NOT FOUND: fs_mknod\n"); free(temp_path1); free(temp_path2); free(temp_path3); free(dir_name); free(base_name); return -ENOENT; } printf("after get parent directory: fs_mknod"); s3dirent_t *parent_dir, file_entry; parent_dir = (s3dirent_t*)dir; //file_entry= malloc(sizeof(s3dirent_t)); if(parent_dir->type != 'D') { fprintf(stderr, "PARENT MUST BE A DIRECTORY: fs_mknod\n"); free(temp_path1); free(temp_path2); free(temp_path3); free(dir_name); free(base_name);free(parent_dir); //free(file_entry); return ENOTDIR; } printf("after check if parent dir is dir: fs_mknod\n"); struct stat meta; meta.st_dev = dev; meta.st_mode = mode; meta.st_nlink = 1; meta.st_uid = getuid(); meta.st_gid = getgid(); struct timeval tv; time_t the_time; gettimeofday(&tv, NULL); the_time = tv.tv_sec; meta.st_atime = the_time; meta.st_mtime = the_time; meta.st_ctime = the_time; file_entry.type = 'F'; strcpy(file_entry.name, base_name); meta.st_size = 0; file_entry.metadata = meta; new_dir_size = dir_size + sizeof(s3dirent_t); parent_dir = realloc(parent_dir, new_dir_size); parent_dir[dir_size/sizeof(s3dirent_t)] = file_entry;//TRY TO DO = *FILE_ENTRY, OR MAKE IT A STACK VARIABLE printf("after assign new file_entry to dir, before put update array back: fs_mknod\n"); printf("dir_name: %s\n",dir_name); printf("after dir_name\n"); if(s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t*)parent_dir, new_dir_size)!= new_dir_size) { fprintf(stderr, "UPDATED DIRECTORY DID NOT GET PUT BACK CORRECTLY, REMOVE AND TRY AGAIN: fs_mknod"); free(temp_path1); free(temp_path2); free(temp_path3); free(dir_name); free(base_name); free(parent_dir); return -EIO; } uint8_t *new_file = NULL; if(s3fs_put_object(ctx->s3bucket, path, new_file, 0) != 0) { fprintf(stderr, "NEW FILE DID NOT GET PUT BACK CORRECTLY: fs_mknod\n"); free(temp_path1); free(temp_path2); free(temp_path3); free(dir_name); free(base_name); free(parent_dir); return -EIO; } printf("after put back updated dir: fs_mknod\n"); free(temp_path1); free(temp_path2); free(temp_path3); free(dir_name); free(base_name); free(parent_dir); return 0; }
/* * 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) { //sommers code fprintf(stderr, "fs_mkdir(path=\"%s\", mode=0%3o)\n", path, mode); s3context_t *ctx = GET_PRIVATE_DATA; mode |= S_IFDIR; //our code s3dirent_t * dir = NULL; printf("%s\n","test .5"); char* directoryPath = strdup(path); char* directoryName = strdup(path); //strcat(directoryPath, path); //strcat(directoryName, path); printf("%s\n","test .7"); directoryPath = strdup(dirname(directoryPath)); //get path and malloc directoryName = strdup(basename(directoryName)); //get name and malloc printf("%s","directory path: "); printf("%s\n",directoryPath); printf("%s","directory name: "); printf("%s\n",directoryName); char* tempPath; //pull if (s3fs_get_object(ctx->s3bucket, directoryPath, (uint8_t **)&dir, 0,0)<0) //if not a real directory { fprintf(stderr, "path is not valid"); free(directoryPath); free(directoryName); return -EIO; } printf("%s\n","test 1"); //make sure where you are trying to put is infact a directory if (strcmp(dir[0].type, "D")!=0) { fprintf(stderr, "object is not a not a directory. Can not place here"); free(directoryPath); free(directoryName); free(dir); return -EIO; } //iterate through files and make sure name does not already exist int i = 0; while(strcmp((dir[i].type),"U")!=0) { //check if name already exists. if(strcmp(dir[i].name, directoryName)==0) { fprintf(stderr, "name already exists!"); free(directoryPath); free(directoryName); free(dir); return -EEXIST; } i++; } printf("%s\n","test 2"); //if got to here, then safe to make directory and add it s3dirent_t newDir[2]; //create new directory struct time_t temp; //create temporory timestamp time(&temp); //get current time strcpy(newDir[0].name, "."); //set name of directory to ".". newDir[0].timeAccess = temp; //set directory last access time to temp newDir[0].timeMod = temp; //set directory last modified time to temp newDir[0].size = sizeof(s3dirent_t); //set directory size to size of s3dirent struct strcpy(newDir[0].type, "D"); //set diretory type to directory newDir[0].userID = getuid(); //get user ID newDir[0].groupID = getgid(); //get group ID newDir[0].protection = (S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR); strcpy(newDir[1].type, "U"); //set type to unused, indicating end printf("%s\n","put new dir into s3"); //upload new Dir if ((s3fs_put_object(ctx->s3bucket, path, (const uint8_t *)&newDir, sizeof(newDir)))!=sizeof(newDir)) { fprintf(stderr, "failed to add the new directory"); free(directoryPath); free(directoryName); free(dir); return -EIO; } //update parent directory s3dirent_t newParentDir[i+2]; //create new directory struct //copy over all metadata strcpy(newParentDir[0].name, dir[0].name); //set name of directory to ".". newParentDir[0].timeAccess = dir[0].timeAccess; //set directory last access time to temp newParentDir[0].timeMod = dir[0].timeMod; //set directory last modified time to temp newParentDir[0].size = sizeof(newParentDir); //set directory size to size of s3dirent struct strcpy(newParentDir[0].type, dir[0].type); //set diretory type to directory newParentDir[0].userID = dir[0].userID; //get user ID newParentDir[0].groupID = dir[0].groupID; //get group ID newParentDir[0].protection = (S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR); //copy over file names and types i = 1; while (strcmp(dir[i].type,"U")!=0) { printf("%d\n",i); strcpy(newParentDir[i].name,dir[i].name); strcpy(newParentDir[i].type,dir[i].type); i++; } //copy over new file printf("%d\n",i); printf("%s","directory Name: "); printf("%s\n",directoryName); strcpy(newParentDir[i].name, directoryName); //how do u find the name of the dir??? strcpy(newParentDir[i].type, "D"); //mark last as U i++; strcpy(newParentDir[i].type, "U"); printf("%s\n", "put new parent into s3"); //re-upload new parent directory if ((s3fs_put_object(ctx->s3bucket, directoryPath, (const uint8_t *)&newParentDir, sizeof(newParentDir)))!=sizeof(newParentDir)) { fprintf(stderr, "failed to add the new directory"); free(dir); free(directoryPath); free(directoryName); return -EIO; } printf("%s\n","--------------FINISHED MKDIR----------"); //free everything malloced free(dir); free(directoryPath); free(directoryName); return 0; }
/* * Rename a file. */ int fs_rename(const char *path, const char *newpath) { char * dir_name = dirname(strdup(path)); char * base_name = basename(strdup(path)); char * new_dir_name = dirname(strdup(newpath)); char * new_base_name = basename(strdup(newpath)); ssize_t ret_val = 0; uint8_t * buffer = NULL; uint8_t * _unused_buffer = NULL; fprintf(stderr, "fs_rename(fpath=\"%s\", newpath=\"%s\")\n", path, newpath); 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'; size_t new_path_len = strlen(newpath); char * new_file_content_key = (char *)malloc(new_path_len + 2); // no point of multiplying by sizeof(char) // since the below code assumes ANSI anyways new_file_content_key[0] = '~'; memcpy(&new_file_content_key[1], newpath, new_path_len); new_file_content_key[new_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); free(new_file_content_key); return -ENOENT; } // check if new file doesnt already exist, if it does return error if (0 <= s3fs_get_object(ctx->s3bucket, new_file_content_key, &_unused_buffer, 0, 0)) { free(buffer); free(_unused_buffer); free(new_file_content_key); free(file_content_key); return -EEXIST; } free(_unused_buffer); if (0 != s3fs_remove_object(ctx->s3bucket, file_content_key)) { free(buffer); free(new_file_content_key); free(file_content_key); return -EIO; } free(file_content_key); ret_val = s3fs_put_object(ctx->s3bucket, new_file_content_key, buffer, ret_val); free(buffer); free(new_file_content_key); // get and remove the original entry ret_val = s3fs_get_object(ctx->s3bucket, dir_name, &buffer, 0, 0); s3dirent_t * entries = (s3dirent_t *)buffer; s3dirent_t * file_entry = (s3dirent_t *)malloc(sizeof(s3dirent_t)); s3dirent_t * new_parent_dir = (s3dirent_t *)malloc(ret_val - sizeof(s3dirent_t)); int dirent_count = ret_val / sizeof(s3dirent_t); int i = 0, copy_index = 0; for (; i < dirent_count; i++) { if (0 == strncmp(entries[i].name, base_name, 256)) { // save the file entry so that could add it to the new path memcpy(file_entry, &entries[i], sizeof(s3dirent_t)); } else { memcpy(&new_parent_dir[copy_index], &entries[i], sizeof(s3dirent_t)); copy_index++; } } free(buffer); if (1 != (i - copy_index)) { free(new_parent_dir); free(file_entry); return -EIO; } if (0 > s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t *)new_parent_dir, (ret_val - sizeof(s3dirent_t)))) { free(new_parent_dir); free(file_entry); return -EIO; } free(new_parent_dir); // rename in parent ret_val = s3fs_get_object(ctx->s3bucket, new_dir_name, &buffer, 0, 0); if (0 > ret_val) { free(file_entry); return -EIO; } dirent_count = ret_val / sizeof(s3dirent_t); new_parent_dir = (s3dirent_t *)malloc(ret_val + sizeof(s3dirent_t)); memcpy(new_parent_dir, buffer, ret_val); free(buffer); time_t current_time = time(NULL); memset(file_entry->name, 0, 256); strcpy(file_entry->name, new_base_name); file_entry->atime = current_time; file_entry->mtime = current_time; // add the entry memcpy(&new_parent_dir[dirent_count], file_entry, sizeof(s3dirent_t)); if (0 > s3fs_put_object(ctx->s3bucket, new_dir_name, (uint8_t *)new_parent_dir, (ret_val + sizeof(s3dirent_t)))) { free(new_parent_dir); free(file_entry); return -EIO; } free(new_parent_dir); free(file_entry); return 0; }
/* * 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; printf("FIRST CHECK PATH TO MKDIR: %s\n\n",path); char *temp_path1 = strdup(path), *temp_path2 = strdup(path), *temp_path3 = strdup(path); printf("FIRST CHECK OF TEMP_PATH MKDRI: %s\n\n",temp_path1); char *dir_name = strdup(dirname(temp_path1)); printf("DIR NAME: %s\n\n", dir_name); char *base_name = strdup(basename(temp_path2)); printf("BASE NAME: %s\n\n", base_name); uint8_t *directory = NULL, *temp = NULL; printf("PATH TO MKDIR CHECK: %s\n\n", path); if(s3fs_get_object(ctx->s3bucket, temp_path3, &temp, 0, 0) >= 0) { fprintf(stderr, "Directory name already exists"); free(temp); free(temp_path1); free(temp_path2); free(temp_path3); free(dir_name); free(base_name); return -EEXIST; } free(temp); printf("PAST GET OBJECT IN MKDIR CHECK\n\n"); ssize_t directory_size = NULL; struct stat meta; if((directory_size = s3fs_get_object(ctx->s3bucket, dir_name, &directory, 0, 0)) < 0) { fprintf(stderr, "Could not find parent directory: fs_mkdir"); free(temp_path1); free(temp_path2); free(temp_path3); free(base_name); free(dir_name); return -ENOENT; } s3dirent_t *dir_update = (s3dirent_t*)directory; printf("PAST GET PARENT DIRECTORY IN MKDIR CHECK\n\n"); meta.st_mode = (S_IFDIR | S_IRWXU); printf("past mode bitwise or set\n"); meta.st_nlink = 1; meta.st_uid = getuid(); meta.st_gid = getgid(); struct timeval tv; time_t the_time; gettimeofday(&tv, NULL); the_time = tv.tv_sec; meta.st_atime = the_time; meta.st_mtime = the_time; meta.st_ctime = the_time; printf("before malloc\n"); s3dirent_t *new_dir_self = malloc(sizeof(s3dirent_t)), new_dir; printf("before strcpy\n"); strcpy(new_dir_self->name, "."); printf("after strcpy on same line\n");new_dir_self->type = 'D'; new_dir_self->num_entries = 1; printf("in between strncpys\n"); strcpy(new_dir.name,base_name); new_dir.type = 'D'; new_dir.num_entries = 0; printf("new_dir name: %s \n",new_dir.name); printf("after second strncpy\n"); meta.st_size = sizeof(*new_dir_self); printf("size of new dir: %d\n", meta.st_size); printf("same line as metadata assign\n");new_dir_self->metadata = meta; printf("right before realloc\n"); dir_update=realloc(dir_update, directory_size + sizeof(new_dir)); printf("after realloc\n"); printf("right before array index input\n"); printf("dir_update size then index: %d, %d\n",directory_size + sizeof(new_dir),directory_size/sizeof(s3dirent_t)); dir_update[directory_size/sizeof(s3dirent_t)] = new_dir; ssize_t dir_update_size = directory_size + sizeof(s3dirent_t); dir_update[0].metadata.st_size = (off_t)dir_update_size; printf("right before put back updated directory\n"); printf("updated directory path: %s \n",dir_name); if(s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t *)dir_update, dir_update_size) != dir_update_size) { fprintf(stderr, "OBJECT DID NOT TRANSFER CORRECTLY: fs_mkdir"); free(temp_path1); free(temp_path2); free(temp_path3); free(new_dir_self); free(dir_update); free(base_name); free(dir_name); return -EIO; } printf("after updated directory put, before new directory put\n"); printf("new directory path: %s \n", path); if(s3fs_put_object(ctx->s3bucket, path, (uint8_t *)new_dir_self, sizeof(s3dirent_t)) != sizeof(s3dirent_t)) { fprintf(stderr, "OBJECT DID NOT TRANSFER CORRECTLY: fs_mkdir"); free(temp_path1); free(temp_path2); free(temp_path3); free(new_dir_self); free(dir_update); free(base_name); free(dir_name); return -EIO; } printf("FINISHED MKDIR\n\n"); free(base_name); free(dir_name); free(dir_update);free(temp_path1); free(temp_path2); free(temp_path3); free(new_dir_self); return 0; }
/* * Rename a file. */ int fs_rename(const char *path, const char *newpath) { //sommers code fprintf(stderr, "fs_rename(fpath=\"%s\", newpath=\"%s\")\n", path, newpath); s3context_t *ctx = GET_PRIVATE_DATA; //our code FILE *fp = NULL; char* directoryPath = strdup(path); char* directoryName = strdup(path); char* newDirectoryName = strdup(path); directoryPath = strdup(dirname(directoryPath)); //get path and malloc directoryName = strdup(basename(directoryName)); //get name and malloc newDirectoryName = strdup(basename(newDirectoryName)); //get name and malloc if (s3fs_get_object(ctx->s3bucket, path, (uint8_t **)&fp, 0,0)<0) //if not a real directory { fprintf(stderr, "failed to read file"); return -EIO; } if (s3fs_remove_object(ctx->s3bucket, path) == -1) { fprintf(stderr, "remove directory failed"); return -EIO; } if ((s3fs_put_object(ctx->s3bucket, newpath, (const uint8_t *)&fp, sizeof(fp)))!=sizeof(fp)) { fprintf(stderr, "failed to reupload to new path"); return -EIO; } //update parent directory s3dirent_t * dirParent = NULL; if (s3fs_get_object(ctx->s3bucket, directoryPath, (uint8_t **)&dirParent, 0,0)<0) //if not a real directory { fprintf(stderr, "path is not valid"); return -EIO; } int i = 0; printf("%s\n","testing 100"); printf("%s\n",dirParent[i].name); while(strcmp((dirParent[i].type),"U")!=0) { if(strcmp(dirParent[i].name, directoryName)==0) { strcpy(dirParent[i].name, newDirectoryName); } i++; } //re-upload new parent directory printf("%s\n","uploading parent directory to following path:"); printf("%s\n",directoryPath); printf("%s", "size of direparentnew: "); printf("%d\n", sizeof(dirParent)); if ((s3fs_put_object(ctx->s3bucket, newpath, (const uint8_t *)&dirParent, sizeof(dirParent)))!=sizeof(dirParent)) { fprintf(stderr, "failed to add the new directory"); return -EIO; } }
/* * 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) { //sommers code 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; //our code FILE *fp = NULL; //our code char* filePath = strdup(path); char* fileName = strdup(path); printf("%s\n","test .7"); filePath = strdup(dirname(filePath)); //get path and malloc fileName = strdup(basename(fileName)); //get name and malloc if (s3fs_get_object(ctx->s3bucket, path, (uint8_t **)&fp, 0,0)<0) //if not a real directory { fprintf(stderr, "failed to read file"); return -EIO; } fseek(fp,0,offset); fwrite(buf, 1, size, fp); //put new file if ((s3fs_put_object(ctx->s3bucket, path, (const uint8_t *)&fp, sizeof(fp)))!=sizeof(fp)) { fprintf(stderr, "failed to add the new file"); return -EIO; } s3dirent_t * dir = NULL; if (s3fs_get_object(ctx->s3bucket, filePath, (uint8_t **)&dir, 0,0)<0) //if not a real directory { fprintf(stderr, "failed to pull directory"); return -EIO; } //update parent directory s3dirent_t newParentDir[sizeof(dir)+1]; //create new directory struct //copy over file names and types int i = 0; while (strcmp(dir[i].type,"U")!=0) { printf("%d\n",i); newParentDir[i] = dir[i]; i++; } //update size newParentDir[i].size = sizeof(fp); //set directory size to size of s3dirent struct printf("%s\n", "put new parent into s3"); //re-upload new parent directory if ((s3fs_put_object(ctx->s3bucket, filePath, (const uint8_t *)&newParentDir, sizeof(newParentDir)))!=sizeof(newParentDir)) { fprintf(stderr, "failed to add the new directory"); return -EIO; } fclose(fp); return 0; }
/* * 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) { //sommers code fprintf(stderr, "fs_mknod(path=\"%s\", mode=0%3o)\n", path, mode); s3context_t *ctx = GET_PRIVATE_DATA; //our code char* filePath = strdup(path); char* fileName = strdup(path); //strcat(directoryPath, path); //strcat(directoryName, path); printf("%s\n","test .7"); filePath = strdup(dirname(filePath)); //get path and malloc fileName = strdup(basename(fileName)); //get name and malloc printf("%s","directory path: "); printf("%s\n",filePath); printf("%s","directory name: "); printf("%s\n",fileName); FILE *fp = fopen(fileName,"a+"); //put file if ((s3fs_put_object(ctx->s3bucket, path, (const uint8_t *)&fp, sizeof(fp)))!=sizeof(fp)) { fprintf(stderr, "failed to add the new file"); return -EIO; } s3dirent_t * dir = NULL; if (s3fs_get_object(ctx->s3bucket, filePath, (uint8_t **)&dir, 0,0)<0) //if not a real directory { fprintf(stderr, "failed to pull directory"); return -EIO; } //update parent directory s3dirent_t newParentDir[sizeof(dir)+1]; //create new directory struct //copy over file names and types int i = 0; while (strcmp(dir[i].type,"U")!=0) { printf("%d\n",i); newParentDir[i] = dir[i]; i++; } //copy over new file printf("%d\n",i); printf("%s","directory Name: "); printf("%s\n",fileName); strcpy(newParentDir[i].type, "F"); time_t temp; //create temporory timestamp time(&temp); //get current time strcpy(newParentDir[i].name, fileName); //set name of directory to ".". newParentDir[i].timeAccess = temp; //set directory last access time to temp newParentDir[i].timeMod = temp; //set directory last modified time to temp newParentDir[i].size = sizeof(fp); //set directory size to size of s3dirent struct strcpy(newParentDir[i].type, "F"); //set diretory type to directory newParentDir[i].userID = getuid(); //get user ID newParentDir[i].groupID = getgid(); //get group ID newParentDir[i].protection = mode; //mark last as U i++; strcpy(newParentDir[i].type, "U"); printf("%s\n", "put new parent into s3"); //re-upload new parent directory if ((s3fs_put_object(ctx->s3bucket, filePath, (const uint8_t *)&newParentDir, sizeof(newParentDir)))!=sizeof(newParentDir)) { fprintf(stderr, "failed to add the new directory"); return -EIO; } i=0; while(strcmp((newParentDir[i].type),"U")!=0) { printf("%s","current name: "); printf("%s\n",newParentDir[i].name); printf("%s","current type: "); printf("%s\n",newParentDir[i].type); i++; } fclose(fp); 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; }
/* * Remove a directory. */ int fs_rmdir(const char *path) { fprintf(stderr, "fs_rmdir(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; uint8_t *dir = NULL; char *temp_path = strdup(path), *temp_path1 = strdup(path), *temp_path2 = strdup(path); char* dir_name = strdup(dirname(temp_path)), *base_name = strdup(basename(temp_path1)); printf("DIR_NAME: %s , BASE_NAME: %s\n",dir_name, base_name); ssize_t dir_size; if((dir_size = s3fs_get_object(ctx->s3bucket, temp_path2, &dir, 0, 0)) < 0){ fprintf(stderr, "INVALID DIRECTORY: fs_rmdir\n"); free(temp_path); free(temp_path1); free(temp_path2);free(dir_name); free(base_name); return -ENOENT; } printf("after getting dir to remove\n"); s3dirent_t *directory = (s3dirent_t *)dir; if(dir_size/sizeof(s3dirent_t) > 1) { fprintf(stderr, "CANT DELETE DIRECTORY WITH OTHER THINGS IN IT: fs_rmdir\n"); free(directory);free(temp_path); free(temp_path1); free(temp_path2);free(dir_name); free(base_name); return -ENOTEMPTY; } printf("before removing dir\n"); if(s3fs_remove_object(ctx->s3bucket, temp_path2) != 0) { fprintf(stderr, "COULD NOT DELETE OBJECT: fs_rmdir\n"); free(directory);free(temp_path); free(temp_path1); free(temp_path2);free(dir_name); free(base_name); return -EIO; } printf("after removing dir, before getting parent dir\n"); if((dir_size = s3fs_get_object(ctx->s3bucket, dir_name, &dir, 0, 0)) < 0){ fprintf(stderr, "INVALID DIRECTORY: fs_rmdir\n"); free(directory); free(temp_path); free(temp_path1); free(temp_path2);free(dir_name); free(base_name); return -ENOENT; } s3dirent_t *dirent = (s3dirent_t *)dir; int numdirents = dir_size/sizeof(s3dirent_t), i = 0; printf("before for loop to find entry in parent to remove\n"); for(;i<numdirents;i++) { if(!strcmp(dirent[i].name, base_name)) { break; } } if(i>=numdirents) { fprintf(stderr, "NO DIRECTORY ENTRY TO REMOVE IN PARENT: fs_rmdir\n"); free(dirent);free(temp_path); free(temp_path1); free(temp_path2);free(dir_name); free(base_name); return -EIO; } i++; int j = 0; for(;i<numdirents;i++) { j = i-1; dirent[j] = dirent[i]; } printf("before updating entry\n"); ssize_t new_dir_size; s3dirent_t *new_dirent = malloc(dir_size - sizeof(s3dirent_t)); memcpy(new_dirent, dirent, dir_size - sizeof(s3dirent_t)); new_dir_size = dir_size - sizeof(s3dirent_t); if((dir_size = s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t *)new_dirent, new_dir_size)) !=new_dir_size) { fprintf(stderr, "DID NOT PUT OBJECT BACK CORRECTLY\n"); free(new_dirent); free(dirent);free(temp_path); free(temp_path1); free(temp_path2);free(dir_name); free(base_name); return -EIO; } free(dirent); free(new_dirent);free(temp_path); free(temp_path1); free(temp_path2);free(dir_name); free(base_name); printf("SUCCESSFULLY REMOVED DIRECTORY!\n"); return 0; }
/* * Remove a file. */ int fs_unlink(const char *path) { //sommers code fprintf(stderr, "fs_unlink(path=\"%s\")\n", path); s3context_t *ctx = GET_PRIVATE_DATA; //our code char* directoryPath = strdup(path); char* directoryName = strdup(path); directoryPath = strdup(dirname(directoryPath)); //get path and malloc directoryName = strdup(basename(directoryName)); //get name and malloc printf("%s","directory path: "); printf("%s\n",directoryPath); printf("%s","directory name: "); printf("%s\n",directoryName); printf("%s", "removing directory from following path: "); printf("%s\n",path); if (s3fs_remove_object(ctx->s3bucket, path) == -1) { fprintf(stderr, "remove directory failed"); return -EIO; } s3dirent_t * dirParent = NULL; if (s3fs_get_object(ctx->s3bucket, directoryPath, (uint8_t **)&dirParent, 0,0)<0) //if not a real directory { fprintf(stderr, "path is not valid"); return -EIO; } int i = 0; int j = 0; printf("%s\n","testing 100"); printf("%s\n",dirParent[i].name); s3dirent_t dirParentNew[sizeof(dirParent)-1]; while(strcmp((dirParent[i].type),"U")!=0) { printf("%s\n",dirParent[i].name); if(strcmp(dirParent[i].name, directoryName)!=0) { dirParentNew[j] = dirParent[i]; printf("%s","name of what is being moved back: "); printf("%s\n",dirParentNew[j].name); j++; } i++; } //at the last element if (strcmp((dirParent[i].type),"U")==0) { if(strcmp(dirParent[i].name, directoryName)!=0) { //strcpy(dirParent[i].type,"U"); dirParentNew[j] = dirParent[i]; strcpy(dirParentNew[j].type,"U"); } else { //not going to add the last thing; strcpy(dirParentNew[j].type,"U"); } } printf("%s\n","contents of newParentDir"); i=0; while(strcmp((dirParent[i].type),"U")!=0) { printf("%s","name: "); printf("%s\n",dirParentNew[i].name); printf("%s","type: "); printf("%s\n",dirParentNew[i].type); i++; } //re-upload new parent directory printf("%s\n","uploading parent directory to following path:"); printf("%s\n",directoryPath); printf("%s", "size of direparentnew: "); printf("%d\n", sizeof(dirParentNew)); if ((s3fs_put_object(ctx->s3bucket, directoryPath, (const uint8_t *)&dirParentNew, sizeof(dirParentNew)))!=sizeof(dirParentNew)) { fprintf(stderr, "failed to add the new directory"); return -EIO; } 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; if(!strcmp(path, "/")) { fprintf(stderr,"CANNOT WRITE TO A DIRECTORY ESPECIALLY ROOT: fs_write\n"); return -EPERM; } uint8_t* file = NULL; ssize_t file_size; printf("before grab the file\n"); if((file_size=s3fs_get_object(ctx->s3bucket, path, &file, 0, 0))<0) { fprintf(stderr, "INVALID PATH: fs_write\n"); return -ENOENT; } printf("grabbed file\n"); ssize_t new_size; char *file_data = (char *)file; printf("strdup file data\n"); if(file_size <= offset + size) { new_size = offset + size - file_size; file_data = realloc(file_data, sizeof(char)*new_size); }else { new_size = file_size; } printf("after assigning new size/ realloc\n"); int i = offset; for(;i<new_size;i++) { file_data[i] = buf[i]; } printf("after transfering data\n"); if(s3fs_remove_object(ctx->s3bucket, path)!=0) { fprintf(stderr, "object not removed correctly\n"); free(file_data); return -EIO; } if(s3fs_put_object(ctx->s3bucket, path, (uint8_t *)file_data, new_size) != new_size) { fprintf(stderr,"WRITTEN FILE DID NOT PUT BACK CORRECTLY: fs_write\n"); free(file_data); return -EIO; } free(file_data); uint8_t *file_entry = NULL; ssize_t file_entry_size; 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((file_entry_size = s3fs_get_object(ctx->s3bucket, dir_name, &file_entry, 0, 0))< 0) { fprintf(stderr, "COULD NOT UPDATE FILE ENTRY AFTER WRITE: fs_write\n"); free(dir_name); free(base_name); return -EIO; } printf("after grabbed directory to update entry size meta\n"); s3dirent_t *update_file_entry = (s3dirent_t *)file_entry; printf("update size: %d\n",new_size); printf("base name: %s\n",base_name); for(i=0;i<file_entry_size/sizeof(s3dirent_t);i++) { printf("directory entry names: %s\n",update_file_entry[i].name); if(!strcmp(update_file_entry[i].name, base_name)) { update_file_entry[i].metadata.st_size = new_size; printf("st_size of direct entry: %d \n",update_file_entry[i].metadata.st_size); } } if(s3fs_remove_object(ctx->s3bucket, dir_name)!=0) { fprintf(stderr,"could not remove object\n"); free(dir_name); free(base_name);free(update_file_entry); return -EIO; } if(s3fs_put_object(ctx->s3bucket, dir_name, (uint8_t *)update_file_entry, file_entry_size)!=file_entry_size) { fprintf(stderr, "COULD NOT PUT UPDATED DIRECTORY ENTRY BACK: fs_write\n"); free(dir_name); free(base_name); free(update_file_entry); return -EIO; } printf("yay wrote to a file\n"); return new_size; }