예제 #1
0
// Implements EMPTY directory deletion
void myrmdir(char *path){
  // if it's an abs path then return to root
  if (path[0] == '/'){
    mychdir("root");
  }

  // if the folder is empty, i.e. the first item is it's list is the ENDOFDIR tag
  if (strcmp(mylistdir(path)[1], "ENDOFDIR") == 0) {
    // keep a track of where we start the process as the current dir changes in here, somewhere...
    int initial_current_dir_index = current_dir_index;
    int initial_current_dir_first_block = current_dir->first_block;

    // calculate the parent of the dir to remove and chdir to it
    char *target = strstr(path, last_entry_in_path(path_to_array(path)));
    int position = target - path;
    char parent_path[position+1];
    for(int i = 0; i < position + 1; i++){
      parent_path[i] = '\0';
    }

    strncpy(parent_path, path, position);
    if(strcmp(parent_path,"") != 0) {
      mychdir(parent_path);
    }
    // find the entry for the dir to be deleted
    int entrylist_target = file_entry_index(last_entry_in_path(path_to_array(path)));

    // find the start of it's block chain
    int block_chain_target = virtual_disk[current_dir_index].dir.entrylist[entrylist_target].first_block;

    // clear the dir entry and it's name ready for reuse (still don't have that feature)
    direntry_t *dir_entry = &virtual_disk[current_dir_index].dir.entrylist[entrylist_target];
    dir_entry->first_block = 0;
    dir_entry->unused = 1;
    int length = strlen(dir_entry->name);
    for (int i = 0; i < length; i++){
      dir_entry->name[i] = '\0';
    }

    // clear the dirs block chain and update the fat
    int next_block_chain_target;
    while(1){
      next_block_chain_target = FAT[block_chain_target];
      FAT[block_chain_target] = UNUSED;
      if (next_block_chain_target == ENDOFCHAIN) break;
      block_chain_target = next_block_chain_target;
    }
    copy_fat(FAT);

    // go back to where we started!
    current_dir_index = initial_current_dir_index;
    current_dir->first_block = initial_current_dir_first_block;
  } else {
    printf("That directory has content and cannot be deleted.\n");
  }
}
예제 #2
0
// Implements the opening of files in various modes (r,w,a)
my_file_t *myfopen(char *path, char *mode)
{
  int initial_current_dir_index = current_dir_index;
  int initial_current_dir_first_block = current_dir->first_block;

  // only cd if we have a path with many levels
  if(number_of_entries_in_path(path_to_array(path)) > 1){
    mychdir(path);
  }

  char filename[MAXNAME];
  strcpy(filename, last_entry_in_path(path_to_array(path)));
  strcat(filename, "\0");

  int dir_entry_index = file_entry_index(filename);

  // if it doesn't exist then create it
  if(dir_entry_index == -1 && strncmp(mode, "r", 1) != 0){
    printf("File did not exist. Creating new file: %s\n", path);

    // create a block for it on the disk
    int block_index = next_unallocated_block();
    create_block(block_index, DATA);

    // create a dir entry for it in the current directory
    dir_entry_index = add_block_to_directory(block_index, filename, FALSE);
  }

  // load up it's dir entry
  direntry_t dir_entry = virtual_disk[current_dir_index].dir.entrylist[dir_entry_index];

  // create a file object to return
  my_file_t *file = malloc(sizeof(my_file_t));
  file->pos = 0;
  file->writing = 0;
  memcpy(file->mode, mode, strlen(mode));
  file->blockno = dir_entry.first_block;
  file->buffer = virtual_disk[dir_entry.first_block];

  // move to the end if in append mode
  if(strncmp(file->mode, "a", 1) == 0){
    move_pos_to_end(file);
  }

  current_dir_index = initial_current_dir_index;
  current_dir->first_block = initial_current_dir_first_block;

  return file;
}
예제 #3
0
파일: tagfs.c 프로젝트: williamwoelke/TagFS
int tagfs_rename(const char *path, const char *newpath) {
	char **tag_array = NULL;
	int file_id = 0;
	int i = 0;
	int num_tags = 0;
	int retstat = 0;

	DEBUG(ENTRY);
	INFO("Moving %s to %s", path, newpath);

	file_id = file_id_from_path(path);
	remove_tags(file_id);

	if(strcmp(dirname(newpath), "/") != 0) { /* deleting will put the file at root. Nothing to add */
		num_tags = path_to_array(dirname(newpath), &tag_array);

		for(i = 0; i < num_tags; i++) {
			add_tag_to_file(tag_id_from_tag_name(tag_array[i]), file_id);
		}

		free_double_ptr((void ***)&tag_array, num_tags);
	}

	DEBUG(EXIT);
	return retstat;
}
예제 #4
0
// Implements file deletion for a given path
void myremove(char *path){
  int initial_current_dir_index = current_dir_index;
  int initial_current_dir_first_block = current_dir->first_block;

  mychdir(path);

  // set the file name
  char filename[MAXNAME];
  strcpy(filename, last_entry_in_path(path_to_array(path)));
  strcat(filename, "\0");

  int location = file_entry_index(filename);

  if (location == -1) {
    printf("File not found.\n");
    return;
  }

  // clear the fat entries
  int block_index = virtual_disk[current_dir_index].dir.entrylist[location].first_block;
  int next_block_index;
  while(1){
    next_block_index = FAT[block_index];
    FAT[block_index] = UNUSED;
    if (next_block_index == ENDOFCHAIN) break;
    block_index = next_block_index;
  }
  copy_fat(FAT);

  // clear the dir_entry
  direntry_t *dir_entry = &virtual_disk[current_dir_index].dir.entrylist[location];
  dir_entry->first_block = 0;
  dir_entry->unused = 1;
  int length = strlen(dir_entry->name);
  for (int i = 0; i < length; i++){
    dir_entry->name[i] = '\0';
  }

  current_dir_index = initial_current_dir_index;
  current_dir->first_block = initial_current_dir_first_block;
}
예제 #5
0
파일: tagfs.c 프로젝트: williamwoelke/TagFS
/**
 * Read directory
 *
 * This supersedes the old getdir() interface. New applications should use this.
 *
 * The filesystem may choose between two modes of operation:
 *
 * 1) The readdir implementation ignores the offset parameter, and passes zero 
 * to the filler function's offset. The filler function will not return '1' 
 * (unless an error happens), so the whole directory is read in a single readdir * operation. This works just like the old getdir() method.
 *
 * 2) The readdir implementation keeps track of the offsets of the directory 
 * entries. It uses the offset parameter and always passes non-zero offset to 
 * the filler function. When the buffer is full (or an error happens) the filler * function will return '1'.
 *
 * Introduced in version 2.3
 */ 
int tagfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
	char **path_array = NULL;
	char *file_name = NULL;
	char *folder_name = NULL;
	int *files = NULL;
	int *folders = NULL;
	int file_id = 0;
	int filler_ret = 0;
	int i = 0;
	int num_files = 0;
	int num_folders = 0;
	int path_count = 0;
	int retstat = 0;
	int tag_id = 0;

	DEBUG(ENTRY);
	INFO("Reading directory %s", path);

	filler(buf, ".", NULL, 0);
	filler(buf, "..", NULL, 0);

	/* add files */
	num_files = files_at_location(path, &files);

	if(num_files > 0) {
		for(i = 0; i < num_files; i++) {
			file_id = files[i];
			file_name = file_name_from_id(file_id);

			filler_ret = filler(buf, file_name, NULL, 0);
			if(filler_ret != 0) {
				DEBUG("filler returned %d", filler_ret);
				WARN("An error occured while loading files. Out of memory?");
				retstat = -ENOMEM;
			}

			free_single_ptr((void **)&file_name);
		}
	}

	/* if there are files at the requested location, or we are at root, show folders */
	if(num_files > 0 || strcmp("/", path) == 0) {
		/* add folders */
		num_folders = folders_at_location(path, files, num_files, &folders);

		if(files != NULL) /* if at root with no files */ {
			free_single_ptr((void **)&files);
		}

		if(num_folders > 0) {
			path_count = path_to_array(path, &path_array);

			for(i = 0; i < num_folders; i++) {
				tag_id = folders[i];
				folder_name = tag_name_from_tag_id(tag_id);

				/* filter tags out of path */
				if(!array_contains_string((const char **)path_array, folder_name, path_count)) {
					filler_ret = filler(buf, folder_name, NULL, 0);
				}

				free_single_ptr((void **)&folder_name);

				if(filler_ret != 0) {
					DEBUG("filler returned %d", filler_ret);
					WARN("An error occured while loading tags. Out of memory?");
					retstat = -ENOMEM;
				}
			}

			free_single_ptr((void **)&folders);

			if(path_array != NULL) {
				free_double_ptr((void ***)&path_array, path_count);
			}
		}
	}

	DEBUG(EXIT);
	return retstat;
} /* tagfs_readdir */